[{"content":"","date":null,"permalink":"https://justinfx.com/blog/","section":"Blogs","summary":"","title":"Blogs"},{"content":"","date":null,"permalink":"https://justinfx.com/categories/","section":"Categories","summary":"","title":"Categories"},{"content":"","date":null,"permalink":"https://justinfx.com/categories/fx/","section":"Categories","summary":"","title":"FX"},{"content":"Staff software engineer with 20+ years in VFX pipeline development, working in Go and Python. Currently building AI platform infrastructure at Wētā FX in New Zealand.\nFor my complete professional history, see my LinkedIn profile.\n","date":null,"permalink":"https://justinfx.com/","section":"JustinFX.com","summary":"\u003cp\u003eStaff software engineer with 20+ years in VFX pipeline development, working in Go and Python. Currently building AI platform infrastructure at Wētā FX in New Zealand.\u003c/p\u003e\n\u003cp\u003eFor my complete professional history, see my \u003ca href=\"https://www.linkedin.com/in/justinisrael/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eLinkedIn profile\u003c/a\u003e.\u003c/p\u003e","title":"JustinFX.com"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/presentation/","section":"Tags","summary":"","title":"Presentation"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/siggraph/","section":"Tags","summary":"","title":"Siggraph"},{"content":" At the SIGGRAPH 2017 Convention, in Los Angeles, I had represented Weta Digital and presented a 20 minute talk under the Pipe Dreams category:\nSIGGRAPH 2017 \u0026gt; Talks \u0026gt; Pipe Dreams\nThe talk was entitled Large Scale VFX Pipelines and focused on Weta\u0026rsquo;s migration from an older commercial render farm solution, to an in-house render management system called Plow. It detailed the original scalability problems, the challenges in switching, the methods used to make a successful migration, and the production results of the change.\nAbstract:\nTo ensure peak utilization of hardware resources and handle the increasingly dynamic demands placed on its render farm infrastructure, Weta Digital developed custom queuing, scheduling, job description, and submission systems. This talk presents the scalability issues encountered and details the strategy, process, and results in solving these problems.\nA video of the presentation and the published abstract are available here:\n(Scroll down to the Pipe Dreams session and click Large Scale VFX Pipelines)\nhttps://www.siggraph.org/sites/default/files/SIGGRAPH-2017-Talks.html\n","date":"Jul 5, 2018","permalink":"https://justinfx.com/2018/07/05/siggraph-2017-large-scale-vfx-pipelines/","section":"Blogs","summary":"\u003cimg src=\"/uploads/2018/07/05/s2017-logo.png\" style=\"width:360px;\"\u003e\n\u003cp\u003eAt the SIGGRAPH 2017 Convention, in Los Angeles, I had represented Weta Digital and presented a 20 minute talk under the Pipe Dreams category:\u003c/p\u003e","title":"Siggraph 2017 - Large Scale VFX Pipelines"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/","section":"Tags","summary":"","title":"Tags"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/vfx/","section":"Tags","summary":"","title":"Vfx"},{"content":" gofileseq is a Go language library for parsing file sequence strings commonly used in VFX and animation applications.\nSequences of files follow a pattern similar to #/path/to/some/file_foo.0100.exr /path/to/some/file_foo.1-100#.jpg /path/to/some/file_foo.1-100@@@.tif Support range formats # Standard: 1-10 Comma Delim: 1-10,10-20 Chunked: 1-100x5 Filled: 1-100y5 Staggered: 1-100:3 (1-100x3, 1-100x2, 1-100) Negative frames: -10-100 Padding: #=4 padded, @=single pad Tools #Included with the library are two command line utilities:\nseqls - An ls-style tool for searching and listing file sequences\n$ seqls -r file_foo.0100.exr subdir/file_foo.1-100#.jpg subdir2/file_foo.1-100@@@.tif seqinfo - Parses one or more sequence pattern strings and list plain text or json info\n$ seqinfo --json \u0026quot;/path/to/file.exr\u0026quot; \u0026quot;/path/to/seq.-10-200x2@@.exr\u0026quot; { \u0026quot;/path/to/file.exr\u0026quot;: { \u0026quot;error\u0026quot;: \u0026quot;\u0026quot;, \u0026quot;string\u0026quot;: \u0026quot;/path/to/file.exr\u0026quot;, \u0026quot;dir\u0026quot;: \u0026quot;/path/to/\u0026quot;, \u0026quot;base\u0026quot;: \u0026quot;file\u0026quot;, \u0026quot;range\u0026quot;: \u0026quot;\u0026quot;, \u0026quot;pad\u0026quot;: \u0026quot;\u0026quot;, \u0026quot;ext\u0026quot;: \u0026quot;.exr\u0026quot;, \u0026quot;start\u0026quot;: 0, \u0026quot;end\u0026quot;: 0, \u0026quot;length\u0026quot;: 1, \u0026quot;zfill\u0026quot;: 0, \u0026quot;hasRange\u0026quot;: false }, \u0026quot;/path/to/seq.-10-200x2@@.exr\u0026quot;: { \u0026quot;error\u0026quot;: \u0026quot;\u0026quot;, \u0026quot;string\u0026quot;: \u0026quot;/path/to/seq.-10-200x2@@.exr\u0026quot;, \u0026quot;dir\u0026quot;: \u0026quot;/path/to/\u0026quot;, \u0026quot;base\u0026quot;: \u0026quot;seq.\u0026quot;, \u0026quot;range\u0026quot;: \u0026quot;-10-200x2\u0026quot;, \u0026quot;pad\u0026quot;: \u0026quot;@@\u0026quot;, \u0026quot;ext\u0026quot;: \u0026quot;.exr\u0026quot;, \u0026quot;start\u0026quot;: -10, \u0026quot;end\u0026quot;: 200, \u0026quot;length\u0026quot;: 106, \u0026quot;zfill\u0026quot;: 2, \u0026quot;hasRange\u0026quot;: true } } As of recent, the gofileseq project has adopted the use of the goreleaser tool, which means that tagged releases now automatically include cross-compiled binaries of the tools for linux, osx, and windows.\nC++ #There is also a C++ port of gofileseq within the repository, for those C++ devs that need to work with VFX-style file sequence patterns. Doxygen API docs are now automatically built from the master branch: justinfx.com/gofileseq/cpp\n","date":"Feb 20, 2018","permalink":"https://justinfx.com/2018/02/20/gofileseq-binary/","section":"Blogs","summary":"\u003cimg src=\"https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png\" alt=\"GitHub\" style=\"width:100px; float:left; margin:0 1.25rem 0.5rem 0;\" \u003e\n\u003cp\u003e\u003ca href=\"https://github.com/justinfx/gofileseq\" title=\"gofileseq\" target=\"_blank\" rel=\"noreferrer\"\u003egofileseq\u003c/a\u003e is a Go language library for parsing file sequence strings commonly used in VFX and animation applications.\u003c/p\u003e","title":"seqls \u0026 seqinfo (gofileseq) binary releases"},{"content":"","date":null,"permalink":"https://justinfx.com/categories/code/","section":"Categories","summary":"","title":"Code"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/maya/","section":"Tags","summary":"","title":"Maya"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/pyqt4/","section":"Tags","summary":"","title":"Pyqt4"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/python/","section":"Tags","summary":"","title":"Python"},{"content":"In 2011 and 2012 I had released 3 commercial Python training tutorials, using Maya as a target platform. Now enjoy them free of charge!\nPython For Maya Artists - Volume 1 Python For Maya Artists - Volume 2 PyQt4 UI Development for Maya Python For Maya Artists - Volume 1 # Project material available here\nAmazing at Animation? Master of Modeling? Conquistador of Character Rigging?\nBut how is your Python?\nThis course brings the talented artist into the fold of the technical-side of Maya. Learn the basics of Python, and its place in your 3D workflow, with visual examples and real world problems. Get a kick-start on adding some automation into your life, and solving common problems in a fraction of the time. By the end of this video, you should have a deeper understanding of one of the languages Maya speaks under the hood, and how to start viewing your scenes in terms of glorious Python code!\nPython For Maya Artists - Volume 2 # Project material available here\nIf you watched the first video, you now have a good grasp on Python. Sweet. Let\u0026rsquo;s plow through some more involved concepts like python juggernauts!\nWith a working knowledge of the python scripting language, and the Maya Python commands API, we can continue to learn new ways to solve more challenging problems, create complete scripts, and build user interfaces around our tools. We also introduce the Maya Python API; a lower-level interface into Maya.\nThis video focuses more on breaking down full scripts, as opposed to typing out syntax. Its jam packaged with information and moves fast to deliver you as much brain food as possible. The first segment of the video transitions from beginning to intermediate level, with the majority of the video being intermediate, and finishing out by touching on advanced concepts. The included project files are abundant, complete, and full of helpful documentation so that you can take your time and learn about each piece of the tools.\nPyQt4 UI Development for Maya # Project material available here\nIntroduction #This tutorial is about learning PyQt4 python bindings for the Qt Framework, and how to introduce new UI elements to Maya as a platform.\nWe discuss what comprises a “Framework” and a “GUI Framework”, and how Qt and PyQt4 work together.\nGetting Started With PyQt4 #There are multiple ways of getting a working installation of PyQt4, both for the general system and for Maya. We look into these approaches to get your system up and running to begin working with PyQt4!\nWe also talk about what is included, such as command line tools and applications, tips on how to test and learn the code, and how to structure a project.\nPyQt4 Fundamentals #Lets get crackin\u0026rsquo; and learn the basics!\nWhat is a QObject? What is a QWidget? Common PyQt4 classes are explained in detail Working with the Qt Designer application, to build a UI visually Layouts: Making widgets resize elegantly and stay organized in your design Coordinate space: How do widgets transform in your 2D screen space? QApplication and the Qt Event Loop: The engine that runs your UI Events, Signals, and Slots: How components communicate changes and how the application can respond to changes to make it dynamic General Examples #With an understanding of the framework components, we can begin working with fully functional stand-alone examples.\nCommon PyQt4 app template Subclassing Widgets: Creating custom functionality to the existing classes provided by PyQt4 Dialogs: Raising dialog windows above existing windows, Modal vs Non-modal, and creating forms. We look at different ways to validate the data provided by the user, to these dialog forms. PyQt4 And Maya Introduction #Finally, some Maya action! Maya has a slightly different approach to using PyQt4…\nHow does the QApplication and event loop work? Common Maya PyQt4 app template Looking at the Maya API\u0026rsquo;s MQtUtil class The sip module: Helping us translate between Maya\u0026rsquo;s Qt and our own PyQt4 code Replicating Maya\u0026rsquo;s UI Components #What better way to see examples of creating UI for Maya than to replicate some existing functionality? This gives us the opportunity expand with custom functionality\nIn this chapter we will take two different UI components in Maya, and do a basic custom version of our own, and show to how link them up to Maya\u0026rsquo;s own callbacks.\nSome Features Of This Chapter Include\nThe QTableWidget Model / View separation with QTreeView Docking windows into the Maya interface Mixing together PyQt4, the Maya API, Maya commands, and callbacks Sorting model data Customizations #A button can be a button, and a slider might look alright in its stock form, but sometimes we want to customize the look of our widgets. This chapter introduces multiple ways of achieving custom looks to our components\nStylin\u0026rsquo; Style-sheets: Use CSS-like syntax for applying style sheets to widgets Painting By \u0026hellip; Paint events: For even more control, we can tell a widget exactly how to draw itself on the screen. We will look at two different examples of how to use custom painting. ","date":"Mar 22, 2017","permalink":"https://justinfx.com/2017/03/22/python-tutorials-released-free/","section":"Blogs","summary":"\u003cp\u003eIn 2011 and 2012 I had released 3 commercial Python training tutorials, using Maya as a target platform.\nNow enjoy them free of charge!\u003c/p\u003e","title":"Python Video Tutorials Released Free"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/training/","section":"Tags","summary":"","title":"Training"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/tutorial/","section":"Tags","summary":"","title":"Tutorial"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/bindings/","section":"Tags","summary":"","title":"Bindings"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/c++/","section":"Tags","summary":"","title":"C++"},{"content":"This is an overview describing my approach to creating C++ bindings around a Go library.\nA bit about wrapping C/C++ #I\u0026rsquo;ve had some past experience in writing cgo bindings on top of C and C++ libraries.\nAuthor\nOpenImageigo and OpenColorigo - Color pipeline and image manipulation and conversion libraries relevant to the Visual Effects industry. These cgo libraries wrap C++. Contributor\nimagick - Bindings on top of the C-API for ImageMagick; Image manipulation pigosat - Bindings on top of Picosat C-API; Satisfiability solver. C libraries are more straight-forward to wrap, because Go can access them directly. C++, on the other hand, requires a \u0026ldquo;shim\u0026rdquo; layer written in C. This layer has to handle the calls between Go and the target C++ library. An example would be to treat a C++ class as an opaque pointer and provide C functions that accept the pointer and delegate to the C++ methods. Or to convert between vectors and arrays:\nref: github.com/justinfx/openimageigo/cpp/oiio.h\n// oiio.h #ifdef __cplusplus extern \u0026#34;C\u0026#34; { #endif typedef void ImageInput; // imageinput.cpp ImageInput* ImageInput_Open(const char* filename, const ImageSpec _config) { std::string s_filename(filename); return (ImageInput*) OIIO::ImageInput::open( s_filename, static_cast\u0026lt;const OIIO::ImageSpec*\u0026gt;(config)); } const char* ImageInput_format_name(ImageInput *in) { return static_cast[OIIO::ImageInput*](OIIO::ImageInput*)(in)-\u0026gt;format_name(); } As you can see, we make an opaque ImageInput* available to Go, and create a shim layer that is C compatible. ImageInput_Open() is a factory function that wraps the static C++ ImageInput::open() equivalent. We just cast between our pointer and theirs (OIIO\u0026rsquo;s), in order to call functions and methods.\nBut like I said, these are Go bindings on top of C/C++ libraries. What about exposing a C++ library on top of a pure Go library?\nExposing Go libraries to C++ #I had previously written a Go library called gofileseq. This library also caters to the Visual Effects industry, providing a way to build, parse, and find sequences of files, and frame ranges. Such as dealing with:\n/path/to/some/file_foo.0100.exr /path/to/some/file_foo.1-100#.jpg /path/to/some/file_foo.1-50x2,100-200x3@@@.tif gofileseq library is a port of a python equivalent, fileseq, which I help to maintain. If the parsing rules need to be updated in the Python library, they should also be updated to match in the Go library, to maintain compatibility.\nI had been asked more than once by colleagues if a C++ version of fileseq was available. It wasn\u0026rsquo;t, and I also didn\u0026rsquo;t want to have to maintain a 3rd standalone port that should follow the same behavior as the other two. But since the introduction of the Go -buildmode flag in 1.5, it has become possible to export functions from Go to C/C++\n// sum.go package main import \u0026#34;C\u0026#34; //export sum func sum(x, y int) int { return x + y } func main() { } $ go build -buildmode=c-shared -o sum.so $ ls sum.c sum.go sum.h sum.so Now we have a shared library and a header file, to use in our C app\n// sum.c #include \u0026lt;stdio.h\u0026gt; #include \u0026#34;sum.h\u0026#34; int main(void) { int z = sum(1, 2); printf(\u0026#34;1+2=%d\\n\u0026#34;, z); return 0; } $ gcc sum.c sum.so -o sum \u0026amp;\u0026amp; ./sum 1+2=3 This looks pretty straight-forward, right? It would seem so until you encounter the need to export instances of your types from Go to C, and these types contain pointers to other types. You see, there are certain rules about what you can do when communicating via cgo. And these rules were made official as off Go 1.6.\nSome of those rules are:\nYou can pass Go pointers to C, but C should not hang on to them beyond the scope of the call. You can not pass memory to C that contains pointers. That is, a struct which has pointer fields. These pose an issue if you want to be able to have your C++ library create instances of objects in Go and hang on to them longer than the Go function call. In the case of gofileseq, the main two objects are FileSequence and FrameSet. These are constructed from strings, perform parsing, and maintain private state. So a user would want to construct them and keep them around until they are done calling methods on them. But according to the cgo rules, I can\u0026rsquo;t give a pointer to C++ for it to hang on to indefinitely, and I can\u0026rsquo;t create a C struct in a shim to populate, because there are more internal pointers involved in a FileSequence. Basically I saw this as a more complex type than just a struct with simple data fields.\nHow do I construct these instances for C++? I created package-private maps using generated uint64 keys, and the instances as values. Actually, I wrap the instances up in a struct that also tracks reference counts. This allows C++ to manage the lifetime of the objects.\nThe full implementation is located here: github.com/justinfx/gofileseq/cpp\ntype FileSeqId uint64 type fileSeqRef struct { *fileseq.FileSequence refs uint32 } type fileSeqMap struct { lock *sync.RWMutex m map[FileSeqId]*fileSeqRef rand idMaker } type idMaker interface { Uint64() uint64 } func (m *frameSetMap) Incref(id FrameSetId) { // Inc refs } func (m *frameSetMap) Decref(id FrameSetId) { // Dec refs // If refs == 0, delete from map } Now when C++ wants to create a FileSequence, they can call a New function which will create an instance, add it to the map, and return a uint64 id handle\n//export FileSequence_New func FileSequence_New(frange *C.char) (FileSeqId, Error) { fs, e := fileseq.NewFileSequence(C.GoString(frange)) if e != nil { // err string is freed by caller return 0, C.CString(e.Error()) } id := sFileSeqs.Add(fs) return id, nil } //export FileSequence_Dirname func FileSequence_Dirname(id FileSeqId) *C.char { fs, ok := sFileSeqs.Get(id) // caller must free string if !ok { return C.CString(\u0026#34;\u0026#34;) } return C.CString(fs.Dirname()) } You can see here that because this is C++ calling Go, we aren\u0026rsquo;t able to free the C string from Go, as the string needs to outlive the Go call. We just make sure that C++ always frees *C.char when it is returned. To make sure I always clean up the char* in C++, I made a helper StringProxy class which wraps it and cleans it up in the destructor:\nref: github.com/justinfx/gofileseq/cpp/private/fileseq_p.h\nclass StringProxy { public: StringProxy(char* managed) : m_data(managed), m_str() { if (managed != NULL) { m_str.assign(managed); } } ~StringProxy() { if (m_data != NULL) { free(m_data); m_data = NULL; } } //... }; This all ended up working fine! I created some benchmarks to compare fileseq between Python, C++, and Go. The test involved looping 100k times, creating a FileSequence, and calling 4 methods on it.\nconst int n = 100000; for (int i=0; i \u0026lt; n; ++i) { fileseq::FileSequence fs(\u0026#34;/path/to/file_name.1-100x2#.ext\u0026#34;); str = fs.string(); str = fs.frameRange(); num = fs.start(); num = fs.end(); } Python: 8.0s Go: 1.9s C++: 3.2s There is a bit of overhead in the C++ lib from the fact that they are bindings on top of a Go layer, but I think the win for me is that it is still an acceptable level of performance and I don\u0026rsquo;t have to maintain a 3rd standalone port of fileseq!\nIt bothered me a little that I did have to rely on a mutex-guarded static map, so I asked on go-nuts about an alternative approach. Ian Lance Taylor confirmed that the guarded map approach, with opaque ids as keys, was a completely viable approach to solving this problem. But that in some circumstance it can also be possible to malloc C memory to back Go objects, in which case they are not tracked by Go\u0026rsquo;s GC.\ni.e., something like this:\nfs := (*FileSequence)unsafe.Pointer( C.malloc(unsafe.Sizeof(FileSequence{}))) I tried to apply this approach, but it became really tedious and confusing to figure out how to malloc all of the internal data nested in the types. For instance, FrameSet has methods that create more data along the way. And I had no idea how to cleanly get it to keep malloc\u0026rsquo;ing memory so the entire structure continues to be 100% managed by C++. So I gave up on trying this route, although I bet it would work for less nested structs.\nIf anyone has any suggestions on another way to improve the process of exporting instances of Go objects to C++, I would definitely welcome feedback! And for anyone wanting to make their Go libraries available to C++, I hope this overview has been useful!\n","date":"May 14, 2016","permalink":"https://justinfx.com/2016/05/14/cpp-bindings-for-go/","section":"Blogs","summary":"\u003cp\u003eThis is an overview describing my approach to creating C++ bindings around a Go library.\u003c/p\u003e","title":"C++ Bindings For A Go Library"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/cgo/","section":"Tags","summary":"","title":"Cgo"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/go/","section":"Tags","summary":"","title":"Go"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/golang/","section":"Tags","summary":"","title":"Golang"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/sublimetext/","section":"Tags","summary":"","title":"Sublimetext"},{"content":"My code editor of choice has been SublimeText for a while now. It is blazing fast for searching and doing matching, replacements, and refactoring. I also love that it is very lightweight, so that I can use it as my default shell $EDITOR, and also have an alias st which can easily open files and folders in the current or new Sublime window:\n# Add directory to current sublime $ st -a /path/to/src # Open a new sublime window, with the current directory $ st -n . Sublime is cross-platform, which means I can have the same development environment across Linux and OSX. It also has an amazing python-based plugin framework, which is enriched by the plugin manager and plugin community, PackageControl. While it is not a full-fledged IDE, because of the availability of so many plugin options, you can get it pretty close to being like an IDE for a number of different languages. Currently I use it for Python, Go, Markdown editing, and C++. This post outlines some simple steps for configuration a SublimeText3 project for use with C++.\nBefore we get into the specifics of C++ configuration, let me first give a quick overview of my SublimeText3 setup, across all of my language\u0026hellip;\nAnaconda - Python language Auto-complete, Goto Definition, and Documentation Cython+ - Cython language Syntax support GoOracle - Go language support for using \u0026ldquo;Oracle\u0026rdquo; tool GoSublime - IDE-like support for Go language Markdown Preview - Markdown highlighting and previewing MayaSublime - Written by myself; Send Python/MEL code into Maya PrettyJSON - Reformatting and validating JSON SideBarEnhancements - Amp up the side bar and context menu ThriftSyntax - Syntax highlighting for Apache Thrift spec files And the ones we will be looking at today, for C++ support:\nClang-Complete Switch File Deluxe Uncrustify These steps were performed on an OSX laptop, so you will need to look at the specific README files for Linux/Windows details. I also assume you have installed Package Control, which makes it trivial to install plugins.\nClang-Complete #OSX already comes with the clang compiler, and this plugin for SublimeText3 allows your source to be compiled on the fly and have diagnostic details made available.\nInstall Clang-Complete\nThere aren\u0026rsquo;t any plugin settings to adjust, but you will want to set up either general clang settings, or project-specific clang settings. General settings may be include paths related to finding system libraries, however in my case I only set up project specific settings.\nProject -\u0026gt; Edit Project\nIf you don\u0026rsquo;t already have a settings key, create one, and then under that create a cc_include_options list of flags to pass to clang. Example:\n\u0026#34;settings\u0026#34;: { \u0026#34;cc_include_options\u0026#34;: [ \u0026#34;-I/path/to/some/library/include\u0026#34; ] } The setting is called \u0026ldquo;cc_include_options\u0026rdquo;, but it is a bit misleading. Really it seems to just be any compiler flags you want to pass to clang. I have put -D macro defines, as well as being able to disable warnings, etc, etc.\nOnce you have your basic includes entered for your given project, you should review your key mappings. There is only one I cared about:\n{ \u0026#34;command\u0026#34;: \u0026#34;clang_goto_def\u0026#34;, \u0026#34;keys\u0026#34;: [\u0026#34;super+.\u0026#34;, \u0026#34;super+g\u0026#34;], \u0026#34;context\u0026#34;: [{\u0026#34;key\u0026#34;: \u0026#34;selector\u0026#34;, \u0026#34;operator\u0026#34;: \u0026#34;equal\u0026#34;, \u0026#34;operand\u0026#34;: \u0026#34;source.c++\u0026#34;} ] } Adjust the \u0026ldquo;keys\u0026rdquo; sequence as needed. This gives you the ability to jump to definitions from a given symbol.\nAt this point, you should have code completion, and the ability to navigate through C++ symbols. You will know your code completion is working if the completion popup has more than just names, and actually has type information on the right side.\nSwitch File Deluxe #This is a pretty sweet and simple plugin that lets you switch between headers and source files. Before Sublime, I had been using Qt Creator for C++ Qt projects, and this functionality was built-in and mapped to the F4 key.\nInstall Switch File Deluxe\nOnce installed, all I had to do was map a key sequence:\n{ \u0026#34;command\u0026#34;: \u0026#34;switch_file_deluxe\u0026#34;, \u0026#34;keys\u0026#34;: [\u0026#34;f4\u0026#34;], \u0026#34;args\u0026#34;: { \u0026#34;extensions\u0026#34;: [ \u0026#34;.cpp\u0026#34;, \u0026#34;.cxx\u0026#34;, \u0026#34;.cc\u0026#34;, \u0026#34;.c\u0026#34;, \u0026#34;Qt.cpp\u0026#34;, \u0026#34;Qt.h\u0026#34;, \u0026#34;.hpp\u0026#34;, \u0026#34;.hxx\u0026#34;, \u0026#34;.h\u0026#34;, \u0026#34;_p.h\u0026#34;, \u0026#34;_p_p.h\u0026#34;, \u0026#34;.ipp\u0026#34;, \u0026#34;.inl\u0026#34;, \u0026#34;.m\u0026#34;, \u0026#34;.mm\u0026#34; ] } } From any C++ header or source file, when you hit F4 you will switch to the corresponding header or source. If the matching file is ambiguous, you should be presented with a choice of files. Once you select the file, future uses of the key will immediately switch between the previously selected files.\nUncrustify #If you prefer your C++ source code to follow a particular style, then you can use the \u0026ldquo;uncrustify\u0026rdquo; tool to apply beautification based on a configuration file of rules.\nFirst I installed uncrustify via homebrew: brew install uncrustify\nThen, install Uncrustify\nIf your uncrustify binary is in a non-standard location, you can set the user settings for the plugin with uncrustify_executable. For setting up projects to match configs, I actually used the uncrustify_config_by_filter setting to set up a list of patterns:\n{ \u0026#34;uncrustify_filtering_rule\u0026#34;: 1, \u0026#34;uncrustify_config_by_filter\u0026#34;: [ {\u0026#34;/path/to/some/*/project\u0026#34;: \u0026#34;/path/to/project/uncrustify.cfg\u0026#34;} ]\t} It helps to store your uncrustify.cfg within your project repo. Also, there is a tool I used for visually editing the rules for setting up an uncrustify config: [universalindent](http://universalindent.sourceforge.net/). Build System #On a per-project basis, you can set up your build commands. Going into Project -\u0026gt; Edit Project, I added something like the following to work with my particular build system for the project:\n{ \u0026#34;build_systems\u0026#34;: [ { \u0026#34;file_regex\u0026#34;: \u0026#34;(\\\\S*?):(\\\\d+):(\\\\d+): (error.*)\u0026#34;, \u0026#34;name\u0026#34;: \u0026#34;Default \u0026#39;Project\u0026#39; Build\u0026#34;, \u0026#34;shell\u0026#34;: true, \u0026#34;shell_cmd\u0026#34;: \u0026#34;./\\\\$USER/scripts/build_cmd arg1 arg2\u0026#34;, \u0026#34;variants\u0026#34;: [ { \u0026#34;cmd\u0026#34;: [ \u0026#34;./\\\\$USER/scripts/build_cmd arg3 arg4\u0026#34; ], \u0026#34;name\u0026#34;: \u0026#34;\u0026#39;Project\u0026#39; Build Debug\u0026#34;, \u0026#34;shell\u0026#34;: true } ], \u0026#34;working_dir\u0026#34;: \u0026#34;/path/to/project/root\u0026#34; } ] } file_regex is a pattern specifying how to capture the filename, line number, column number, and error message from the output of the build command. This is useful to adapt to any kind of build system and have Sublime give you context about the errors in your view.\nYou specify the default build command, and then optionally a number of variants for the build system, such as debug builds or different options. Once this is entered you can now set your build system selection and use your build hotkey.\nWrapping up #I don\u0026rsquo;t do much debugging from within my editor (I am primarily an Editor+Terminal kind of developer), so I didn\u0026rsquo;t go as far as to investigate Sublime options for debugging. But with a pretty minimal amount of configuration, I have a pretty lightweight and capable editor for working on C++ projects. And it is the same editor I use for working on Python and Go projects.\nGot any other recommendations for making SublimeText an even more capable solution for C++ projects? Let me know!\n","date":"Apr 17, 2016","permalink":"https://justinfx.com/2016/04/17/sublimetext-editor-and-clang/","section":"Blogs","summary":"","title":"SublimeText Editor and Clang (C++)"},{"content":"Since 2006, my small blog has existed as a Wordpress site. This worked really well for me, as it was easy to hit a one-click install from a hosting dashboard, and then be able to install plugins, themes, and updates, all from the Wordpress admin. Ultimately it was one less thing vying for my time as opposed to a custom site from scratch. With limited free time, and a choice of projects to work on, the last thing I really wanted to do was website design and maintenance.\nIn addition to my Wordpress blog, for a while I had also been hosting other applications, such as a Redmine system for project management. Redmine, being a Ruby-on-Rails setup, was quite a memory hog. But that combined with Wordpress made sense to use some form of hosting. Eventually I stopped using Redmine and was left with just a Wordpress blog, hosted on a semi-VPS service, and paying $7 USD a month. Finally I realized this was silly and I should just switch to something that costs\u0026hellip; maybe nothing?\nHugo: A static site generator #I\u0026rsquo;m already a fan and user of the Go language, and so in following a number of the Go social communities, I discovered Hugo. A static site generator is an application that can take content in some original description (markdown in the case of Hugo), and renders final content by applying rules. This final content can then be hosted anywhere, without the need for server-side runtime support, such as Python/PHP/Go/Node/etc, because it does not require server-side processing to handle rendering the pages on the fly. This makes the site very portable and simple to deploy, and can be served out of aggressive caching.\nAnother benefit of Hugo is that you don\u0026rsquo;t need to futz with an in-browser editor while writing pages. Hugo comes with a built-in production-grade server, which provides developers the option of watching for any changes in content. When content changes, Hugo will render that content again, and also trigger an update of your local webpage by way of a connected websocket. I can sit comfortably within my code editor of choice (SublimeText), and write a post in markdown. Each time I save the file, my webpage immediately updates to reflect the changes.\nThis post is primarily focused on my experience in switching to Hugo, and not attempting to provide an A-Z tutorial of using it, nor a comparison to any similar options in static site generation. Detailed documentation can be found on the official Hugo site.\nMigrating from Wordpress to Hugo #I can\u0026rsquo;t claim that the process of converting my Wordpress-based site to Hugo was 100% automatic, or even 90%. Let\u0026rsquo;s say about 80%. But it was fairly painless.\nI started with the Wordpress To Hugo Exporter. Even though there were some claims that it didn\u0026rsquo;t work 100% of the time, I actually had no problems using it with a semi recent 4.x install of Wordpress. I believe those that experienced issues might have had very large sites and encountered some kind of timeout issue. My site has relatively few posts, compared to others, and installing this plugin and exporting the site had worked right away. What you get as an end result is an archive of your site, converted into a basic Hugo project structure. All of your metadata from your posts are preserved in the Hugo format called \u0026ldquo;Front Matter\u0026rdquo;. This is a section of metadata that sits at the top of every markdown file, which the engine will use to build out your static site properly. For instance, the Front Matter that was generated for my post entitled \u0026ldquo;Comparing performance of Qt smart pointer options\u0026rdquo;, looks like this:\n--- title: Comparing performance of Qt smart pointer options author: Justin Israel type: post date: 2015-06-07 slug: comparing-performance-of-qt-smart-pointer-options url: /2015/06/07/comparing-performance-of-qt-smart-pointer-options/ categories: - Code tags: - benchmark - c++ - pointers - qt --- This is YAML (the other supported format is TOML), and gives the engine information about the post that it can use to format the page, and to organize it into the site. You can see definitions of categories and tags (preserved from the Wordpress export), which also drives other aspects of the site like the menu system.\nOnce I had my new set of markdown files, I saw that they needed a tiny bit of cleanup. This probably has to do with the type of plugins I used in Wordpress to format code and embed media, which couldn\u0026rsquo;t be translated to look exactly the way it should. But it was simple enough to go through each page and correct the bits of hyper-links and code formatting. A great thing about Hugo is that it comes with a production-quality web server, which you can use in development mode as you work on your site:\n$ hugo server -w -D This starts the server, and tells it to run in \u0026ldquo;watch\u0026rdquo; mode, and to also render posts that are still in \u0026ldquo;draft\u0026rdquo; mode, so that I can see them in their unpublished state on the site. I can then check out my site right away, by hitting http://127.0.0.1:1313 in my browser. \u0026ldquo;Watch\u0026rdquo; mode means that the site is instrumented with a websocket connection to the server, and will automatically refresh when the server detects that content has changed (after the server automatically renders the content again). This is awesome, because I can type out content, hit save, and see the changes. This was a bit clunkier of a process in Wordpress, where I would type some stuff in a WYSIWYG editor and have to hit \u0026ldquo;save draft\u0026rdquo;, and manually refresh my preview page in another tab (or maybe Wordpress auto-refreshed preview pages. I can\u0026rsquo;t remember now).\nAll-in-all the export and cleanup process was the most painless part. Most of the time was spent learning the new concepts of the Hugo system.\nDeployment #I\u0026rsquo;m going to start with describing the deployment process, since I find that to be one of the most appealing aspects of switching to Hugo. As I had mentioned, my previous solution was a paid hosted approach, in order to have a MySQL database, and a php-enabled dynamic site. My new approach brings my hosting expense down to zero. By using Github Pages, I can treat my site as just another code repository, while serving it for free. You can see the final rendered static site, right here at github.com/justinfx/justinfx.github.io.\nGenerating your static site via Hugo is as simple as doing the following:\n$ hugo 0 of 1 draft rendered 0 future content 32 pages created 0 paginator pages created 45 tags created 3 categories created in 195 ms This command causes Hugo to generate the site to the \u0026ldquo;public/\u0026rdquo; directory in the current working directory. If I had wanted to generate it to another location, I would just need to pass -d \u0026lt;dest\u0026gt; to tell Hugo to generate to another output location.\nI actually symlink the \u0026ldquo;public/\u0026rdquo; subdirectory to point to my \u0026ldquo;justinfx.github.io\u0026rdquo; Github Pages local repo. What that means is that after running Hugo, and because it is managed via a git repository, I now only need to commit the new changes to my repo in order to update my public site. This is a very natural workflow for anyone that is comfortable with git repositories. And it also means that I automatically get revision control for any changes to my website.\nUnderstanding Hugo Concepts #The aspect that took the longest, in the switch to Hugo, was understanding the project structure, and how the layout of the site was generated. The main terms you will deal with upfront are things like: content, layouts, templates, types, archetypes, and static. To oversimplify what I have come to understand is that the Hugo project structure separates your content from your view, or the way that content ultimately is arranged in your site. You spend the most time getting your layout and types set up once, and then moving forward it becomes a simple matter of typing new markdown content, which gets seamlessly integrated into the layout.\nConfiguration #The first thing you want to look at is your config.yaml file. There isn\u0026rsquo;t much to it, and the default could be mostly correct for you. But I did have to change a few things to get it right. Mine looks like this:\n--- baseurl: \u0026#34;http://justinfx.com\u0026#34; languageCode: \u0026#34;en-us\u0026#34; title: \u0026#34;JustinFX.com\u0026#34; DisqusShortname: \u0026#34;justinfx\u0026#34; copyright: \u0026#34;Justin Israel\u0026#34; pygmentsstyle: \u0026#34;friendly\u0026#34; author: name: \u0026#34;Justin Israel\u0026#34; permalinks: blog: /:year/:month/:day/:slug/ taxonomies: tag: \u0026#34;tags\u0026#34; category: \u0026#34;categories\u0026#34; params: \u0026lt; snip ... \u0026gt; Not every field is required. Probably the most important settings are the baseurl and title. The rest of these settings control optional aspects of the site. You can see that I am setting my Disqus id, allowing Hugo to embed its integrated Disqus comment system into the posts. I\u0026rsquo;m also setting some options for how code syntax highlighting is displayed, and some definitions for organization and permalinks.\nContent #Under the \u0026ldquo;content/\u0026rdquo; directory of my project is where all my markdown files are stored. I have the following:\ncontent/ blog/ \u0026lt;postA\u0026gt;.md \u0026lt;postB\u0026gt;.md \u0026lt;postC\u0026gt;.md page/ \u0026lt;pageA\u0026gt;.md \u0026lt;pageB\u0026gt;.md wp-content/ ... \u0026ldquo;blog\u0026rdquo; and \u0026ldquo;page\u0026rdquo; reflect the concepts that came from Wordpress, where I had posts for the blog that would have comments and show up in the feed, and then pages which show up in menus and were not open for comments. The key difference in these two sections is the \u0026ldquo;type\u0026rdquo; parameter that is set in the Front Matter of the markdown files in each section. Blog posts have type: post, while pages have type: page. This becomes important in dictating how they are organized and rendered, when they need to line up with your layouts. Blog posts will be grouped and displayed one way, with indexing and comments, while pages will be displayed another.\nWithin the markdown files, in addition to text and markdown formatting, you can also include template logic, to be expanded at render time (running the hugo command).\nArchetypes #At first, I had thought archetypes were something more complicated than they actually are. Really all they do is define a new \u0026ldquo;type template\u0026rdquo; so that when you create new content with hugo new \u0026lt;...\u0026gt;, the new content will be created with type-specific defaults. For instance, I have an archetype defined that makes any markdown files created in my \u0026ldquo;content/blog/\u0026rdquo; location have the type \u0026ldquo;post\u0026rdquo;:\n$ ls archetypes/ blog.md $ cat archetypes/blog.md +++ type = \u0026#34;post\u0026#34; draft = true +++ $ hugo new blog/new_post.md justinfx.com/content/blog/new_post.md created $ cat content/blog/new_post.md +++ date = \u0026#34;2015-11-21T09:20:47+13:00\u0026#34; draft = true title = \u0026#34;test\u0026#34; type = \u0026#34;post\u0026#34; +++ You can see that a new draft post was created for me, and the Front Matter was pre-populated with the settings from the blog archetype. Just an easy way to set up new content really.\nLayouts #This was the hardest part of the learning curve for me. Layouts are the part of your codebase that specify how your content is turned into actual views in your static site. There is a correlation between the layout directories, and the type names we talked about previously. Because I have two types, \u0026ldquo;post\u0026rdquo; and \u0026ldquo;page\u0026rdquo;, it means I will have the corresponding locations within the layouts directory. Hugo has a resolution order it will use, when figuring out which layouts to apply. First it will check if there is a direct match for the type, and then it will fall back on a special \u0026ldquo;_default\u0026rdquo; directory. Within these directories, you can specify what content should look like when it is viewed as:\na single item - the actual blog post or page a list of items - an index of all blog posts, such as by date a summary of an item - like a preview of an item For example, I have some layouts structured like this:\nlayouts/ _default/ list.html single.html ... page/ single.html post/ li.html single.html summary.html section/ blog.html \u0026ldquo;_default\u0026rdquo; will be the fallback for any particular types that don\u0026rsquo;t explicitly have their own layout definitions. You can see that pages just define a specific single view. Posts define how they look when displayed in a list, or a single view, or their summary view. I also have a \u0026ldquo;section/\u0026rdquo; location defined, which results in the /blog endpoint on my site.\n\u0026ldquo;section/blog.html\u0026rdquo; looks like this:\n{{ template \u0026#34;chrome/head.html\u0026#34; . }} \u0026lt;body\u0026gt; {{ template \u0026#34;chrome/sidebar.html\u0026#34; . }} \u0026lt;div class=\u0026#34;content container\u0026#34;\u0026gt; \u0026lt;h1 class=\u0026#34;title\u0026#34;\u0026gt;Blog Posts\u0026lt;/h1\u0026gt; \u0026lt;ul class=\u0026#34;posts\u0026#34;\u0026gt; {{ range .Data.Pages.GroupByDate \u0026#34;2006\u0026#34; }} \u0026lt;h2\u0026gt;{{ .Key }}\u0026lt;/h2\u0026gt; \u0026lt;ul id=\u0026#34;list\u0026#34;\u0026gt; {{ range .Pages }} {{ .Render \u0026#34;li\u0026#34;}} {{ end }} \u0026lt;/ul\u0026gt; {{ end }} \u0026lt;/ul\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/body\u0026gt; \u0026lt;/html\u0026gt; Breaking this down, we have template directives that will include other templates that render the common header and sidebar. Then we set up how \u0026ldquo;/blog\u0026rdquo; will look when displaying a date-sorted list of all my posts. We loop over all the blog posts, grouped by the year they were created, then loop over each post in a group and render it using its \u0026ldquo;li\u0026rdquo; (list item) definition. This is the place where Hugo will resolve which view to use for list elements. Because we are dealing with \u0026ldquo;post\u0026rdquo; types, Hugo will find \u0026ldquo;layouts/post/li.html\u0026rdquo; first (matching \u0026ldquo;li\u0026rdquo; with \u0026ldquo;li.html\u0026rdquo;, and use that to render each list item.\n\u0026ldquo;layouts/post/li.html\u0026rdquo; looks like this:\n\u0026lt;li\u0026gt; \u0026lt;span style=\u0026#34;line-height: 1.0\u0026#34;\u0026gt; {{if .Draft}}[draft] {{end}}\u0026lt;a href=\u0026#34;{{ .Permalink }}\u0026#34;\u0026gt;{{ .Title }}\u0026lt;/a\u0026gt; \u0026lt;div class=\u0026#34;post-item\u0026#34;\u0026gt; \u0026lt;span style=\u0026#34;font-size: .75em\u0026#34;\u0026gt;{{ .Date.Format \u0026#34;Mon, Jan 2, 2006\u0026#34; }}\u0026lt;/span\u0026gt; \u0026lt;/div\u0026gt; \u0026lt;/span\u0026gt; \u0026lt;/li\u0026gt; This template is purely concerned with defining an \u0026lt;li\u0026gt; element. We handle optionally indicating if a post is still in draft state (only visible if we are running the hugo server with -D), and then showing the title and date of the post.\nExtra info on layouts and views can be found here and here\nThemes #Hugo supports themes, and already has a sizable gallery of existing themes to choose from.\nI had started out trying to just drop in different themes (placing them in the \u0026ldquo;themes\u0026rdquo; subdirectory, and activating them in the config file or via the command line), but I noticed that not every theme would render properly. I came to understand that themes still require a bit of integration, and are not simply a stylesheet. They define their own views which become part of the resolution order when Hugo looks them up at render time. Finally I just took the advise from Nate Finch\u0026rsquo;s Hugo post, where he grabbed a theme that was closest to what he wanted and started tweaking it. I then started with Nate\u0026rsquo;s modified theme (since I liked it), and also further tweaked it to match what I liked. This resulted in getting rid of an explicit \u0026ldquo;themes\u0026rdquo; location, and just integrating the templates directly into my \u0026ldquo;layouts/\u0026rdquo; location.\nShortcodes #Shortcodes are sweet. They are very similar to Wordpress shortcodes provided by plugins, allowing you to create little functions that can take arguments and expand into reusable code.\nMy shortcodes look like this:\nshortcodes/ lightbox.html vimeo.html youtube.html And \u0026ldquo;vimeo.html\u0026rdquo; looks like this:\n\u0026lt;div class=\u0026#34;js-video vimeo\u0026#34;\u0026gt; \u0026lt;iframe src=\u0026#34;https://player.vimeo.com/video/{{ .Get 0 }}?byline=0\u0026#34; width=\u0026#34;640\u0026#34; height=\u0026#34;360\u0026#34; frameborder=\u0026#34;0\u0026#34; mozallowfullscreen allowfullscreen \u0026gt; \u0026lt;/iframe\u0026gt; \u0026lt;/div\u0026gt; Now I have the ability to embed my vimeo media from within my markdown files, just by using the shortcode and passing the vimeo id as a parameter:\n{{\u0026lt; vimeo 12067694 \u0026gt;}}\nStatic files #Static files are pretty straightforward. It is just a \u0026ldquo;static/\u0026rdquo; location where everything underneath is served directly by your site, and does not go through a rendering process when you generate your site. This would be the place to store css, javascript, images, and other static content that simply needs to be served up in pages or urls. Themes can come with their own static locations, which will be integrated into the main static content when you render your site.\nClosing Thoughts #There is something quite satisfying about having the source of my site being so tangible, while being easy to update, and easy to deploy. I don\u0026rsquo;t have to worry about a database, or hosting, or Wordpress site and plugin updates. I don\u0026rsquo;t have to worry about security, since there are no dynamic pages or Wordpress vulnerabilities to guard against. I don\u0026rsquo;t have to mess with backups and exports from a hosting service, since I check my entire site into github.\nEven for someone like me, that hates doing web front-end development, I didn\u0026rsquo;t mind the minimal amount of css and html templates that needed tweaking. The end result is a site that is straightforward to manage, lightning fast to generate when deploying changes, and now costs me nothing to host.\n","date":"Nov 8, 2015","permalink":"https://justinfx.com/2015/11/08/switching-from-wordpress-to-hugo/","section":"Blogs","summary":"\u003cp\u003eSince 2006, my small blog has existed as a Wordpress site. This worked really well for me, as it was easy to hit a one-click install from a hosting dashboard, and then be able to install plugins, themes, and updates, all from the Wordpress admin. Ultimately it was one less thing vying for my time as opposed to a custom site from scratch. With limited free time, and a choice of projects to work on, the last thing I really wanted to do was website design and maintenance.\u003c/p\u003e","title":"Switching from Wordpress to Hugo"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/benchmark/","section":"Tags","summary":"","title":"Benchmark"},{"content":"There are a number of sources of information on the usage and behavioral differences of the many “smart pointer” options offered by Qt. But one thing I couldn’t find enough information on were the performance characteristics.\n“Continue Using QPointer” describes the complicated situation that came about when the Qt project was choosing to either deprecate QPointer vs QWeakPointer APIs in Qt5, and ultimately how QPointer was preserved. It also describes how in Qt4, the QPointer has a large performance hit vs its improved backend in Qt5. So basically it says to choose performance vs compatibility.\n“What C++ Smart Pointer Implementations are available?“, on StackOverflow, offers a pretty nice breakdown of not only the Qt smart pointers, but also other available options via Boost and C++11.\nI was in a situation where an existing code base had a number of basic classes that were stored in very large parent/child relationships, as pointers. Once I needed to start sharing pointers between some newer classes, I pretty quickly ran into issues of dangling pointers when relationships would change and objects would get deleted, and it seemed that a proper solution would be to introduce some sort of guarded/smart pointer in the mix. Each of a number of options have their own pros and cons. My first approach was just to use a QPointer at the point of creation, and only change the signature of functions that really needed to receive the QPointer. But I was concerned about performance, since more than one source referenced just how slow QPointer can be. But I didn’t want to just switch to a QWeakPointer because of the deprecation in Qt5. So I ended up doing some benchmarks and figured this information might round out the rest of the available info on the web.\nThe test for my benchmark involved creating a number objects, adding them to a list, and then deleting them. The options for the test include both pointers to a basic struct and a QObject, QPointers, QSharedPointers, QWeakPointers, and just for an external comparison I also included boost::shared_ptr and boost::weak_ptr. The test was performed with different numbers of objects, as well as for both Qt4 and Qt5. Here is a more detailed description of each test.\nThe Test Environment #OSX 10.9.5 Laptop 2.8 Ghz Intel Core 2 Duo 8 GB 1067 Mhz DDR3 memory Clang x86 64bit Qt 4.8.6 Qt 5.4.2 Description of Tests #test_raw_pointer : Creating pointers to a basic struct, adding the raw pointers to a QList, and then deleting all of the pointers\ntest_raw_qobject : Creating pointers to QObject instances, adding them to a QList, and then deleting all of the pointers\ntest_ptr_qsharedpointer : Creating QSharedPointers to a basic struct, and also a QWeakPointer for each, and adding the shared pointers to a QList. Then deleting them all.\ntest_qobj_qsharedpointer : Creating QSharedPointers to a QObject, and also a QWeakPointer for each, and adding the shared pointers to a QList. Then deleting them all.\ntest_qobj_qweakpointer : Creating QWeakPointers directly from QObject instances, adding them to a QList, and then deleting them all. This test could only be performed in Qt4, because Qt5 deprecated QObject tracking support for QWeakPointers, which can now only be used with QSharedPointer\ntest_qpointer : Creating QPointers directly from QObject instances, adding them to a QList, and then deleting them all.\ntest_boost_sharedptr : Creating boost::shared_ptrs from basic struct instances, as well as boost::weak_ptrs for each, adding the shared_ptrs to a QList, and then deleting them\ntest_boost_qobj_sharedptr : Creating boost::shared_ptrs from QObject instances, as well as boost::weak_ptrs for each, adding the shared_ptrs to a QList, and then deleting them\nThe Test Results #Testing w/ 5000 objects Qt4 Qt5 test_raw_pointer: 1 ms 1 ms test_raw_qobject: 4 ms 3 ms test_ptr_qsharedpointer: 3 ms 3 ms test_qobj_qsharedpointer: 13 ms 6 ms test_qobj_qweakpointer: 6 ms - test_qpointer: 8 ms 7 ms test_boost_sharedptr: 5 ms 3 ms test_boost_qobj_sharedptr: 6 ms 4 ms Testing w/ 50000 objects test_raw_pointer: 12 ms 10 ms test_raw_qobject: 41 ms 35 ms test_ptr_qsharedpointer: 32 ms 35 ms test_qobj_qsharedpointer: 66 ms 62 ms test_qobj_qweakpointer: 76 ms - test_qpointer: 103 ms 65 ms test_boost_sharedptr: 32 ms 31 ms test_boost_qobj_sharedptr: 69 ms 61 ms Testing w/ 500000 objects test_raw_pointer: 109 ms 107 ms test_raw_qobject: 379 ms 329 ms test_ptr_qsharedpointer: 352 ms 354 ms test_qobj_qsharedpointer: 709 ms 642 ms test_qobj_qweakpointer: 811 ms - test_qpointer: 1109 ms 725 ms test_boost_sharedptr: 350 ms 346 ms test_boost_qobj_sharedptr: 680 ms 611 ms Testing w/ 2000000 objects test_raw_pointer: 417 ms 401 ms test_raw_qobject: 1502 ms 1201 ms test_ptr_qsharedpointer: 1933 ms 1383 ms test_qobj_qsharedpointer: 3207 ms 2604 ms test_qobj_qweakpointer: 3387 ms - test_qpointer: 5599 ms 2832 ms test_boost_sharedptr: 1370 ms 1350 ms test_boost_qobj_sharedptr: 2864 ms 2453 ms The test shows the overhead of simply going from a simple struct to a QObject, and then the further impact of introducing various smart pointers on QObjects, and also on non-QObjects where permitted.\nQPointer was the easiest change to introduce, because after you make the original class into a QObject subclass, you only need to change the code at the call site(s) where the pointers are created, and then only within the functions that specifically need to receive a guarded QPointer. For all the other function signatures, QPointer will automatically cast to an unguarded T* and behave exactly the same as before. But you can see from the results that the performance impact can be over 10x slower than when we originally started with our non-QObject class. In Qt5, while it is still most poorly performing option, it is not too far off from the option of a QSharePointer + QWeakPointer.\nThe best performing option seems to be keeping the class as a non-QObject and using either QSharedPointer+QWeakPointer, or boost shared_ptr+weak_ptr. Although, this is the most intrusive change since all signatures have to be updated to accept QSharedPointer (or typedef).\nIn between, using a QWeakPointer with direct QObject tracking seems like a balance between the ease of slotting it in to the existing code, and performance. The classes would still need to be QObject subclasses, but only the specific functions that need a QWeakPointer would need to change. Unfortunately this is not supported anymore in Qt5 (as only the QSharedPointer support is allowed), so it becomes a choice of whether the code needs to stay clean for future compatibility, or if one just wants to make the change later when a Qt5 migration actually happens.\nFor a small number of object creations/deletions, the performance difference doesn’t seem like it would matter that much, but when it involves tons of objects it might be a problem. If your classes were already QObjects then there are less options to consider in the first place. And the more performant route, if you don’t care about the amount of code that has to change, would probably be to shoot for QSharedPointer + QWeakPointer.\n","date":"Jun 7, 2015","permalink":"https://justinfx.com/2015/06/07/comparing-performance-of-qt-smart-pointer-options/","section":"Blogs","summary":"\u003cp\u003eThere are a number of sources of information on the usage and behavioral differences of the many “smart pointer” options offered by Qt. But one thing I couldn’t find enough information on were the performance characteristics.\u003c/p\u003e","title":"Comparing performance of Qt smart pointer options"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/pointers/","section":"Tags","summary":"","title":"Pointers"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/qt/","section":"Tags","summary":"","title":"Qt"},{"content":"","date":null,"permalink":"https://justinfx.com/categories/random-stuff/","section":"Categories","summary":"","title":"Random Stuff"},{"content":"On my last day of work at South Park Studios, my co-worker Tory gave me a present. It’s a book that collects together a history of doodles and graphics, capturing significant moments during my 4 year run with the team.\nTory tends to represent our team as dog characters. I can be identified usually by the pierced chin. Much of this content refers to inside jokes, but I feel it also has a number of generally hilarious imagery.\nThank you, Tory!\n","date":"Dec 19, 2012","permalink":"https://justinfx.com/2012/12/19/south-park-going-away-book-gift/","section":"Blogs","summary":"\u003cp\u003eOn my last day of work at South Park Studios, my co-worker Tory gave me a present. It’s a book that collects together a history of doodles and graphics, capturing significant moments during my 4 year run with the team.\u003c/p\u003e\n\u003cp\u003eTory tends to represent our team as dog characters. I can be identified usually by the pierced chin. Much of this content refers to inside jokes, but I feel it also has a number of generally hilarious imagery.\u003c/p\u003e","title":"South Park “going-away” book gift"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/southpark/","section":"Tags","summary":"","title":"Southpark"},{"content":" #PyQt4 UI Development for Maya #Just released my 3rd python-based online training video through cmiVFX.com\nIntroduction # This tutorial is about learning PyQt4 python bindings for the Qt Framework, and how to introduce new UI elements to Maya as a platform. We discuss what comprises a “Framework” and a “GUI Framework”, and how Qt and PyQt4 work together. Getting Started With PyQt4 # There are multiple ways of getting a working installation of PyQt4, both for the general system and for Maya. We look into these approaches to get your system up and running to begin working with PyQt4! We also talk about what is included, such as command line tools and applications, tips on how to test and learn the code, and how to structure a project. PyQt4 Fundamentals # Lets get crackin’ and learn the basics! • What is a QObject? What is a QWidget? Common PyQt4 classes are explained in detail • Working with the Qt Designer application, to build a UI visually • Layouts: Making widgets resize elegantly and stay organized in your design • Coordinate space: How do widgets transform in your 2D screen space? • QApplication and the Qt Event Loop: The engine that runs your UI • Events, Signals, and Slots: How components communicate changes and how the application can respond to changes to make it dynamic General Examples # With an understanding of the framework components, we can begin working with fully functional stand-alone examples. • Common PyQt4 app template • Subclassing Widgets: Creating custom functionality to the existing classes provided by PyQt4 • Dialogs: Raising dialog windows above existing windows, Modal vs Non-modal, and creating forms. We look at different ways to validate the data provided by the user, to these dialog forms. PyQt4 And Maya Introduction # Finally, some Maya action! Maya has a slightly different approach to using PyQt4… • How does the QApplication and event loop work? • Common Maya PyQt4 app template • Looking at the Maya API’s MQtUtil class • The sip module: Helping us translate between Maya’s Qt and our own PyQt4 code Replicating Maya’s UI Components # What better way to see examples of creating UI for Maya than to replicate some existing functionality? This gives us the opportunity expand with custom functionality In this chapter we will take two different UI components in Maya, and do a basic custom version of our own, and show to how link them up to Maya’s own callbacks. Some Features Of This Chapter Include • The QTableWidget • Model / View separation with QTreeView • Docking windows into the Maya interface • Mixing together PyQt4, the Maya API, Maya commands, and callbacks • Sorting model data Customizations # A button can be a button, and a slider might look alright in its stock form, but sometimes we want to customize the look of our widgets. This chapter introduces multiple ways of achieving custom looks to our components • Stylin’ Stylesheets: Use CSS-like syntax for applying style sheets to widgets • Painting By … Paint events: For even more control, we can tell a widget exactly how to draw itself on the screen. We will look at two different examples of how to use custom painting. Previous cmiVFX tutorials: # Intro to Python for Maya – Vol 1 Python for Maya – Vol 2 ","date":"Oct 12, 2012","permalink":"https://justinfx.com/2012/10/12/pyqt4-for-maya/","section":"Blogs","summary":"\u003ch2 id=\"\" class=\"relative group\"\u003e\u003ca href=\"http://www.cmivfx.com/tutorials/view/498/PyQt4\u0026#43;UI\u0026#43;Development\u0026#43;for\u0026#43;Maya\" target=\"_blank\" rel=\"noreferrer\"\u003e\u003cimg class=\"alignnone size-full wp-image-525\" title=\"PyQt4 for Maya\" src=\"/uploads/2012/10/1350054625_Master.jpeg\" alt=\"\" width=\"800\" height=\"450\" /\u003e\u003c/a\u003e \u003cspan class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100\"\u003e\u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\" style=\"text-decoration-line: none !important;\" href=\"#\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\u003c/span\u003e\u003c/h2\u003e\u003ch1 id=\"pyqt4-ui-development-for-maya\" class=\"relative group\"\u003ePyQt4 UI Development for Maya \u003cspan class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100\"\u003e\u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\" style=\"text-decoration-line: none !important;\" href=\"#pyqt4-ui-development-for-maya\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\u003c/span\u003e\u003c/h1\u003e\u003cp\u003eJust released my 3rd python-based online training video through \u003ca href=\"https://cmivfx.com/store/498-pyqt4\u0026#43;ui\u0026#43;development\u0026#43;for\u0026#43;maya\" target=\"_blank\" rel=\"noreferrer\"\u003ecmiVFX.com\u003c/a\u003e\u003c/p\u003e\n\u003ch2 id=\"introduction\" class=\"relative group\"\u003e\u003cstrong\u003eIntroduction\u003c/strong\u003e \u003cspan class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100\"\u003e\u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\" style=\"text-decoration-line: none !important;\" href=\"#introduction\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\u003c/span\u003e\u003c/h2\u003e\u003cdiv\u003e\nThis tutorial is about learning PyQt4 python bindings for the Qt Framework, and how to introduce new UI elements to Maya as a platform.\n\u003c/div\u003e","title":"Tutorial: PyQt4 UI Development for Maya"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/cpickle-serialization/","section":"Tags","summary":"","title":"Cpickle Serialization"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/json/","section":"Tags","summary":"","title":"Json"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/pickle/","section":"Tags","summary":"","title":"Pickle"},{"content":"In a recent python project where I was sending multiple messages per second of data over a basic socket, I had initially just grabbed the cPickle module to get the prototype proof-of-concept functioning properly. cPickle is awesome for easily serializing more complex python objects like custom classes, even though in my case I am only sending basic types.\nMy messages were dicts with some nested dicts, lists, floats, and string values. Roughly 500-1000 bytes. cPickle was doing just fine, but there came a point where I wanted to investigate the areas that could be tightened up. The first thing I realized was that I had forgotten to encode cPickle in the binary format (the default is ascii). That saved me quite a bit of time. But then I casually searched online to see if any json options might be better since my data is pretty primitive anyways.\nI found UltraJSON, which is a pure C json parsing library for python, and ran some tests. There are benchmarks on the project page for ujson, as well as other articles on the internet, but I just wanted to post up my own results using a mixed type data container. ujson came out extremely fast: faster than binary cPickle and msgpack, in the encoding test. Although in the decoding test, msgpack appeared to be fastest, followed by binary cPickle, and then ujson coming in 3rd\nThis test included the following:\npickle/cPickle json simplejson cjson ujson yajl-py msgpack-python Here is my Python 2.7.2 test script using timeit for each encode and decode step. Dependencies: pip install tabulate simplejson python-cjson ujson yajl msgpack-python Test:\nfrom timeit import timeit from tabulate import tabulate setup = \u0026#39;\u0026#39;\u0026#39; d = { \u0026#39;words\u0026#39;: \u0026#34;\u0026#34;\u0026#34; Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris adipiscing adipiscing placerat. Vestibulum augue augue, pellentesque quis sollicitudin id, adipiscing. \u0026#34;\u0026#34;\u0026#34;, \u0026#39;list\u0026#39;: range(100), \u0026#39;dict\u0026#39;: dict((str(i),\u0026#39;a\u0026#39;) for i in xrange(100)), \u0026#39;int\u0026#39;: 100, \u0026#39;float\u0026#39;: 100.123456 } \u0026#39;\u0026#39;\u0026#39; setup_pickle = \u0026#39;%s ; import cPickle ; src = cPickle.dumps(d)\u0026#39; % setup setup_pickle2 = \u0026#39;%s ; import cPickle ; src = cPickle.dumps(d, 2)\u0026#39; % setup setup_json = \u0026#39;%s ; import json; src = json.dumps(d)\u0026#39; % setup setup_msgpack = \u0026#39;%s ; src = msgpack.dumps(d)\u0026#39; % setup tests = [ # (title, setup, enc_test, dec_test) (\u0026#39;pickle (ascii)\u0026#39;, \u0026#39;import pickle; %s\u0026#39; % setup_pickle, \u0026#39;pickle.dumps(d, 0)\u0026#39;, \u0026#39;pickle.loads(src)\u0026#39;), (\u0026#39;pickle (binary)\u0026#39;, \u0026#39;import pickle; %s\u0026#39; % setup_pickle2, \u0026#39;pickle.dumps(d, 2)\u0026#39;, \u0026#39;pickle.loads(src)\u0026#39;), (\u0026#39;cPickle (ascii)\u0026#39;, \u0026#39;import cPickle; %s\u0026#39; % setup_pickle, \u0026#39;cPickle.dumps(d, 0)\u0026#39;, \u0026#39;cPickle.loads(src)\u0026#39;), (\u0026#39;cPickle (binary)\u0026#39;, \u0026#39;import cPickle; %s\u0026#39; % setup_pickle2, \u0026#39;cPickle.dumps(d, 2)\u0026#39;, \u0026#39;cPickle.loads(src)\u0026#39;), (\u0026#39;json\u0026#39;, \u0026#39;import json; %s\u0026#39; % setup_json, \u0026#39;json.dumps(d)\u0026#39;, \u0026#39;json.loads(src)\u0026#39;), (\u0026#39;simplejson-3.3.1\u0026#39;, \u0026#39;import simplejson; %s\u0026#39; % setup_json, \u0026#39;simplejson.dumps(d)\u0026#39;, \u0026#39;simplejson.loads(src)\u0026#39;), (\u0026#39;python-cjson-1.0.5\u0026#39;, \u0026#39;import cjson; %s\u0026#39; % setup_json, \u0026#39;cjson.encode(d)\u0026#39;, \u0026#39;cjson.decode(src)\u0026#39;), (\u0026#39;ujson-1.33\u0026#39;, \u0026#39;import ujson; %s\u0026#39; % setup_json, \u0026#39;ujson.dumps(d)\u0026#39;, \u0026#39;ujson.loads(src)\u0026#39;), (\u0026#39;yajl 0.3.5\u0026#39;, \u0026#39;import yajl; %s\u0026#39; % setup_json, \u0026#39;yajl.dumps(d)\u0026#39;, \u0026#39;yajl.loads(src)\u0026#39;), (\u0026#39;msgpack-python-0.3.0\u0026#39;, \u0026#39;import msgpack; %s\u0026#39; % setup_msgpack, \u0026#39;msgpack.dumps(d)\u0026#39;, \u0026#39;msgpack.loads(src)\u0026#39;), ] loops = 15000 enc_table = [] dec_table = [] print \u0026#34;Running tests (%d loops each)\u0026#34; % loops for title, mod, enc, dec in tests: print title print \u0026#34; [Encode]\u0026#34;, enc result = timeit(enc, mod, number=loops) enc_table.append([title, result]) print \u0026#34; [Decode]\u0026#34;, dec result = timeit(dec, mod, number=loops) dec_table.append([title, result]) enc_table.sort(key=lambda x: x[1]) enc_table.insert(0, [\u0026#39;Package\u0026#39;, \u0026#39;Seconds\u0026#39;]) dec_table.sort(key=lambda x: x[1]) dec_table.insert(0, [\u0026#39;Package\u0026#39;, \u0026#39;Seconds\u0026#39;]) print \u0026#34;\\nEncoding Test (%d loops)\u0026#34; % loops print tabulate(enc_table, headers=\u0026#34;firstrow\u0026#34;) print \u0026#34;\\nDecoding Test (%d loops)\u0026#34; % loops print tabulate(dec_table, headers=\u0026#34;firstrow\u0026#34;) OUTPUT:\nRunning tests (15000 loops each) pickle (ascii) [Encode] pickle.dumps(d, 0) [Decode] pickle.loads(src) pickle (binary) [Encode] pickle.dumps(d, 2) [Decode] pickle.loads(src) cPickle (ascii) [Encode] cPickle.dumps(d, 0) [Decode] cPickle.loads(src) cPickle (binary) [Encode] cPickle.dumps(d, 2) [Decode] cPickle.loads(src) json [Encode] json.dumps(d) [Decode] json.loads(src) simplejson-3.3.1 [Encode] simplejson.dumps(d) [Decode] simplejson.loads(src) python-cjson-1.0.5 [Encode] cjson.encode(d) [Decode] cjson.decode(src) ujson-1.33 [Encode] ujson.dumps(d) [Decode] ujson.loads(src) yajl 0.3.5 [Encode] yajl.dumps(d) [Decode] yajl.loads(src) msgpack-python-0.3.0 [Encode] msgpack.dumps(d) [Decode] msgpack.loads(src) Encoding Test (15000 loops) Package Seconds -------------------- --------- ujson-1.33 0.232215 msgpack-python-0.3.0 0.241945 cPickle (binary) 0.305273 yajl 0.3.5 0.634148 python-cjson-1.0.5 0.680604 json 0.780438 simplejson-3.3.1 1.04763 cPickle (ascii) 1.62062 pickle (ascii) 14.0497 pickle (binary) 15.4712 Decoding Test (15000 loops) Package Seconds -------------------- --------- msgpack-python-0.3.0 0.240885 cPickle (binary) 0.393152 ujson-1.33 0.396875 python-cjson-1.0.5 0.694321 yajl 0.3.5 0.748369 simplejson-3.3.1 0.780531 cPickle (ascii) 1.38561 json 1.65921 pickle (binary) 5.20554 pickle (ascii) 17.8767 ","date":"Jul 25, 2012","permalink":"https://justinfx.com/2012/07/25/python-2-7-3-serializer-speed-comparisons/","section":"Blogs","summary":"\u003cp\u003eIn a recent python project where I was sending multiple messages per second of data over a basic socket, I had initially just grabbed the cPickle module to get the prototype proof-of-concept functioning properly. cPickle is awesome for easily serializing more complex python objects like custom classes, even though in my case I am only sending basic types.\u003c/p\u003e","title":"Python 2.7.2 serializer speed comparisons"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/speed-test/","section":"Tags","summary":"","title":"Speed Test"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/3d/","section":"Tags","summary":"","title":"3d"},{"content":"A recent project of mine involves research and development with an XBOX 360 Kinect Sensor. Being a python guy, I started searching for python bindings to some OSX-supported framework. When you just get started looking into this area it can be a little confusing. There are a number of layers to the software stack to enable one to accomplish anything meaningful. This is just a short and general blog post outlining the basics of what I have discovered thus far, to help anyone else that might also be getting started.\nAt the lowest level, you need a driver. Something that can talk to the USB device that is the Kinect sensor. When you purchase the XBOX Kinect for Windows version of the sensor, and you are going to be developing on windows, much of this whole stack is provided to you by way of the Kinect SDK. But for the open source folks with the standard XBOX 360 sensor, you need to piece together your own solution.\nTwo drivers that I have discovered thus far:\nOpenKinect PrimeSense Sensor I had started OpenKinect (libfreenect) because it comes with a python wrapper included. There were a few dependencies (I will talk about specific build steps in just a moment), but once I got this installed I was able to fire up the included glview app and see both depth and rgb data streaming in from my sensor. The role of these drivers is to provide simply the basic streams. That is, the depth, rgb, audio, and a few other sensor data streams. If your goal is to start tracking players, seeing skeletons, and registering gestures, the drivers are not enough. You would be required to make your own solution from this raw data at this phase in the game.\nYou would now want to look into middleware that can take the raw data and provide to you an API with higher level information. This would include finding users in the scene for you, tracking their body features, and giving you various events to watch for as the data streams.\nBeing that my goal was to have python bindings, I found my options to be much more limited than if I were going to be developing in C++. Wrappers have to exist for the framework you want. This is where my research really started ramping up. I spent a few days dealing wtih compiling issues, as well as having an actual bad power adapter that had to be exchanged. But all said and done, here is what I have settled on thus far…\nDriver: PrimeSense Sensor OpenNI Framework A recent project of mine involves research and development with an XBOX 360 Kinect Sensor. Being a python guy, I started searching for python bindings to some OSX-supported framework. When you just get started looking into this area it can be a little confusing. There are a number of layers to the software stack to enable one to accomplish anything meaningful. This is just a short and general blog post outlining the basics of what I have discovered thus far, to help anyone else that might also be getting started. At the lowest level, you need a driver. Something that can talk to the USB device that is the Kinect sensor. When you purchase the XBOX Kinect for Windows version of the sensor, and you are going to be developing on windows, much of this whole stack is provided to you by way of the Kinect SDK. But for the open source folks with the standard XBOX 360 sensor, you need to piece together your own solution.\nTwo drivers that I have discovered thus far:\nOpenKinect PrimeSense Sensor I had started OpenKinect (libfreenect) because it comes with a python wrapper included. There were a few dependencies (I will talk about specific build steps in just a moment), but once I got this installed I was able to fire up the included glview app and see both depth and rgb data streaming in from my sensor. The role of these drivers is to provide simply the basic streams. That is, the depth, rgb, audio, and a few other sensor data streams. If your goal is to start tracking players, seeing skeletons, and registering gestures, the drivers are not enough. You would be required to make your own solution from this raw data at this phase in the game.\nYou would now want to look into middleware that can take the raw data and provide to you an API with higher level information. This would include finding users in the scene for you, tracking their body features, and giving you various events to watch for as the data streams.\nBeing that my goal was to have python bindings, I found my options to be much more limited than if I were going to be developing in C++. Wrappers have to exist for the framework you want. This is where my research really started ramping up. I spent a few days dealing wtih compiling issues, as well as having an actual bad power adapter that had to be exchanged. But all said and done, here is what I have settled on thus far…\nDriver: PrimeSense Sensor OpenNI Framework OpenNI Modules for OpenNI PyOpenNI python bindings Install Details #Install homebrew (package manager) #http://mxcl.github.com/homebrew/\nInstall build tools #brew install cmake brew install boost Install python2.7 #brew install python --framework Suggestion: virtualenv Environment #This is not a requirement. But I recommend using virtualenv to set up an environment that specifically uses python2.7 so that you don’t have to fight with mixed dependencies and versions.\nCreate a virtualenv called “kinect”\npip install virtualenv virtualenv --no-site-packages -p python2.7 kinect cd kinect source bin/activate Install libusb (patched version) #There is a special patched version of the libusb library, in the form of a homebrew formula.\ngit clone https://github.com/OpenKinect/libfreenect.git Now copy platform/osx/homebrew/libusb-freenect.rb -\u0026gt; /usr/local/Library/Formula/\nbrew install libusb-freenect Install SensorKinect drivers #git clone https://github.com/avin2/SensorKinect.git Then uncompress Bin/SensorKinect093-Bin-MacOSX-v*tar.bz2\nsudo ./install.sh Install OpenNI framework # Go here: http://www.openni.org/Downloads/OpenNIModules.aspx Download Unstable Binary for MacOSX sudo ./install.sh Install NITE middleware (for OpenNI) # Go here: http://www.openni.org/Downloads/OpenNIModules.aspx Download Unstable MIDDLEWARE of NITE for OSX sudo ./install.sh Install PyOpenNI #Be aware that on OSX, PyOpenNI requires a framework build of python 2.7+ and that you must build it for x86_64 specifically. Also, I was having major problems with cmake properly finding the python includes location. I had to suggest a fix, so please see here for the necessary corrections. I have referenced a patched fork of the repository below.\nexport CPPFLAGS=\u0026#34;-arch x86_64\u0026#34; git clone git://github.com/justinfx/PyOpenNI.git mkdir PyOpenNI-build cd PyOpenNI-build cmake -D PYTHON_INCLUDE_DIR=/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Headers ../PyOpenNI make copy the lib/openni.so module to the python2.7 site-packages\nExamples #Once you have everything installed, you can try out the examples that are included both in the NITE source location that you downloaded and also in the PyOpenNI source location:\nNITE/Samples PyOpenNI/examples I also tried out ofxKinect (github.com/ofTheo/ofxKinect) on the side, which is an addon for OpenFrameworks. This is kind of a separate path than the OpenNI stack. I would say its more like an advanced offering of libfreenect. Using the included example, I recorded a 3D point cloud that is built on the fly from the RGB and depth data: ","date":"Jun 21, 2012","permalink":"https://justinfx.com/2012/06/21/getting-started-with-xbox-360-kinect-on-osx/","section":"Blogs","summary":"\u003cp\u003eA recent project of mine involves research and development with an XBOX 360 Kinect Sensor. Being a python guy, I started searching for python bindings to some OSX-supported framework. When you just get started looking into this area it can be a little confusing. There are a number of layers to the software stack to enable one to accomplish anything meaningful. This is just a short and general blog post outlining the basics of what I have discovered thus far, to help anyone else that might also be getting started.\u003c/p\u003e","title":"Getting started with XBOX 360 Kinect on OSX"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/kinect/","section":"Tags","summary":"","title":"Kinect"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/osx/","section":"Tags","summary":"","title":"Osx"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/code/","section":"Tags","summary":"","title":"Code"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/question/","section":"Tags","summary":"","title":"Question"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/stackoverflow/","section":"Tags","summary":"","title":"Stackoverflow"},{"content":"Permalink – writemycode.net\nIn the spirit of a very similar blog post, I decided to expand upon a specific area of that article…\nConsider a question like this:\nI want to do this. Create 10000 files, (filename can be just combination of time and random number). File size should be 4k. And I want to time this. say how many seconds it will take.\nHow can I do this on bash?\nThank you.\nObviously this person needs some assistance, and the question is very short and easy to understand. But the problem with this type of question is that there are really only two ways someone can approach the answer. Your options for an answer are either to just give the person the complete code snippet as they have requested, or fall back on a lengthy personalized tutorial.\nShort questions that primarily request a complete code example as an answer are counter-productive to code communities.\nAnswer Option 1 #As the topic of this article suggests, option 1 is “Write my code for me”. It might seem easy as a one-off situation to simply donate a working code snippet and get the person asking this question moving on their merry way, but really this is not helping them in the long run. They haven’t learned anything beyond the process of hitting a roadblock, then immediately going online to ask for a solution. Had this person included some references to what they have researched, and most importantly a code snippet representing what they have attempted, viewers of this question would have a basis for comment and potentially an answer pointing out where the person has gone wrong.\nAnswer Option 2 #And in the other direction: providing a lengthy tutorial. We all want to help and teach, but this is just one of numerous questions floating out in the ether that requires a response. Can we really spare that much time for every single question like this to re-teach material that is most likely already documented in generalized contexts all across the internet? That would create quite a lot of redundant information simply because each person combines new components into a new question needing a new lesson. Really, every part of this question can be Googled quite easily. Why ask a community to do a new custom writeup for you?\nNow, assuming we actually wanted to write a tutorial for this person asking the question. The problem at this point is where do we begin? The information provided doesn’t suggest that this person has a grasp on any part of the problem. So the tutorial answer might need to include:\nBash and for-loops How to get the current time How to generate random numbers Creating files Populating new files to a specific size How to write a complete bash script, and time its execution. Had they told us what they know how to do so far, and what aspect has them stuck, we could simply focus on one area and provide a good bit of knowledge to get them moving again. But right now this is just too much work to net a situation where they will learn something.\nFor those that are immediately inclined to provide the complete code snippet to solve the problem, where do we draw the line? What if the question being asked would need 10 lines of code? 20? 100? And if you are also interested in frequently helping people, would you be willing to provide 5 lines of complete code to 10 people a day, knowing that each person probably didn’t learn much? Furthermore, after having given this individual a quick answer, you have now rewarded their lazy behavior, and more than likely just encouraged them to repeat the bad habit again.\nThrough a conversation between my coworker and I, some interesting metaphors were raised that I simply can’t resist from sharing…\nVending-machine communities #**Put a question in the slot and pop out a solution. **\nBe it a traditional forum, an online discussion group, mailing list, or a trust and reputation based technical site like stackoverflow.com, these communities are driven by people, not machines. People have to take time to review content, and contribute their knowledge. We all work hard to acquire that knowledge, so lets all try and put some value on it in the form of the quality of our questions. A .25 cent answer is insulting. Treat your questions like they are costing you actual money that properly reflects the value of people’s knowledge. Code communities don’t work for you, and you don’t work for them. We are all here to help because we love it. Please don’t make us hate it, or feel like we are all just part of a big vending-machine.\nToilet paper answers #Answers that can be used only one particular time for one particular situation.\nThere is an insane amount of content on the internet. It’s hard enough sometimes to sift through the results of a vague Google search, let alone the content on our individual communities. When you ask a question that provides zero context, or proof of the extent of your current effort, then both the question and the answer are for the most part “throw aways”. If its going to be a persistent part of a community space, it should aim to benefit future support-seekers with similar situations. Referring to the example question above, someone going with Option 1 (“Write my code”) will end up providing an answer that will likely not help many people beyond this situation. Unless they too are looking for a way to do a for loop and create 10,000 4k dummy files and measure the execution time. The only way it would stand to benefit future visitors is if the answer did Option 2 and wrote a fully self-describing tutorial.\nConclusion #I can only speak for myself about what I might do. I consider myself to be the type that would go as far as to look at API docs for someone, and work out some pretty extensive examples on my local machine. I might even install libs that I don’t have or have never used before in an effort to provide assistance. But I need to be motivated to do so. It’s exciting for me to write out a page-length of information if I know it will help this person. But in a case like the above there is no show of effort and no context provided — just a person asking to have code written for them.\nAs I suggested already, we all want to help. Thats why we frequent these forums and sites. But we help these types of answer-seekers even more by withholding instant gratification.\nAnd now… I direct you back to whathaveyoutried.com\n","date":"Apr 14, 2012","permalink":"https://justinfx.com/2012/04/14/write-my-code-for-me/","section":"Blogs","summary":"\u003cp\u003ePermalink – writemycode.net\u003c/p\u003e\n\u003cp\u003e\u003cem\u003eIn the spirit of a \u003ca href=\"http://whathaveyoutried.com\" target=\"_blank\" rel=\"noreferrer\"\u003every similar blog post\u003c/a\u003e, I decided to expand upon a specific area of that article…\u003c/em\u003e\u003c/p\u003e\n\u003cp\u003eConsider a question like this:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eI want to do this. Create 10000 files, (filename can be just combination of time and random number). File size should be 4k. And I want to time this. say how many seconds it will take.\u003c/p\u003e\n\u003cp\u003eHow can I do this on bash?\u003c/p\u003e\n\u003cp\u003eThank you.\u003c/p\u003e\n\u003c/blockquote\u003e","title":"Write My Code For Me"},{"content":" I had just received my brand new MacBook Pro a few days ago. Amazing machine. Probably the best laptop I have ever laid my hands upon. It was the early Feb 2011 model so I got a crazy good deal. But something caught my eye that I just had to investigate…\nI’m a bit obsessive when it comes to small issues that I can’t resolve, and this is just still bothering me. I noticed that when I smooth scroll (trackpad or smooth wheel logitech mouse) on such content as webpages, or Mail, that there is a flicker in the display of text and context. It depends on the size and orientation of the content, whether it will flicker more or less. My eyes just couldn’t ignore it and I figured it couldn’t possibly be normal functionality. Thus, step one of my problem solving began: Google search.\nMy search turned up a number of similar complaints to both MacBook Pro and Air models, such as this discussion: https://discussions.apple.com/thread/2645516?start=0\u0026tstart=0\nIt seemed the problem was not just limited to my specific early 2011 Macbook Pro. Suggestions ranged from resetting the PRAM (holding cmd+option+p+r for a couple of reboot cycles), to toggling the screen through display resolutions, to adjusting brightness of the display. Nothing seemed to make much of a difference to me.\nInversion (pixel-walk) #Googling also turned up a reference to this site, which offers various types of LCD tests: http://www.lagom.nl/lcd-test/inversion.php\nAccording to this site, its normal to have a slight flicker in one box. And heavier flickering suggests voltage alignment issues in the LCD display. Using this test, I tried it on a number of Apple product configurations. Here is a collection of my findings:\nDevice Display Scrolling Not Scrolling Macbook Pro (early 2011) 15\" 1440\u0026#215;900 Heavy multi-color flickering in all boxes At least 2 boxes always lightly flickering Mac Pro MacPro4,1 (2009) 24\" Cinema Display Light amount of flickering in all boxes No flicker Mac Pro MacPro5,1 (2010) 27\" LED Cinema Display No flicker Very light flicker in box 7a Inversion (pixel-walk) test results on LCD displays Apple Support #After speaking to support over the phone, they suggested that I go into the store for more help. When I got to the store and started speaking with a tech at the Genius Bar, he had never heard of this issue before. But once I showed him an example on both news.google.com, and in my Apple Mail, he definitely acknowledged that its noticeable. He then went off into the back to research the issue a bit.\nWhen the tech came back he said that he had found no outstanding information from Apple about this issue. A second tech even came and looked at the issue, and had no explanation for it.\nI went around the store and checked web page scrolling on 13″ MacBook Airs, and 13″, 15″, and 17″ MacBook Pro models, with and without the higher resolution LCD display options. All models exhibited the same flicker during scrolling. My final recommendation from the stumped Apple tech was that it could be an issue with Lion and its rendering of fonts, or whatever, and that I could either return my laptop, or hold out for some kind of fix from Apple. Basically, no idea.\nMy question is… Am I being overly sensitive to this display flicker? I figure I can’t be the only one, as per the discussion lists of other users that notice the problem. Some of my friends with the same laptop said they have never really noticed until I pointed it out. I just wonder why such a fantastic laptop would exhibit this visual artifact, and whether it is something I should just accept as being normal?\n","date":"Dec 5, 2011","permalink":"https://justinfx.com/2011/12/05/apple-macbooks-and-unexplainable-lcd-flicker/","section":"Blogs","summary":"\u003cimg src=\"/uploads/2011/12/bmacbook_flicker.png\" alt=\"\" title=\"Macbook Pro flicker\" width=\"490\" height=\"268\" class=\"alignnone size-full wp-image-395\" /\u003e\n\u003cp\u003eI had just received my \u003ca href=\"http://www.bhphotovideo.com/c/product/756789-REG/Apple_MC721LL_A_15_4_MacBook_Pro_Notebook.html\" target=\"_blank\" rel=\"noreferrer\"\u003ebrand new MacBook Pro\u003c/a\u003e a few days ago. Amazing machine. Probably the best laptop I have ever laid my hands upon. It was the early Feb 2011 model so I got a crazy good deal. But something caught my eye that I just had to investigate…\u003c/p\u003e\n\u003cp\u003eI’m a bit obsessive when it comes to small issues that I can’t resolve, and this is just still bothering me. I noticed that when I smooth scroll (trackpad or smooth wheel logitech mouse) on such content as webpages, or Mail, that there is a flicker in the display of text and context. It depends on the size and orientation of the content, whether it will flicker more or less. My eyes just couldn’t ignore it and I figured it couldn’t possibly be normal functionality. Thus, step one of my problem solving began: Google search.\u003c/p\u003e","title":"Apple Macbooks and Unexplainable LCD Screen Flicker"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/mac/","section":"Tags","summary":"","title":"Mac"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/macbook/","section":"Tags","summary":"","title":"Macbook"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/troubleshooting/","section":"Tags","summary":"","title":"Troubleshooting"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/api/","section":"Tags","summary":"","title":"Api"},{"content":"A question came up in the Maya-Python mailing list that I thought was a really good topic, and should be reposted.\nSomeone asked how you can create maya UI objects and embed them within your main PyQt application. Specifically he wanted to create a modelPanel and embed it so that he would have a camera view within his own PyQt window.\nHere is my example of how to achieve this…\nUpdate: Instructions for Maya 2017+, using PySide2 and Qt5, are available via this blog post by Lidia Martínez\nUpdate: A port of the older PyQt4 example for Maya 2017+ using Qt5 and PySide2\nfrom PySide2 import QtCore, QtWidgets import shiboken2 import maya.cmds as cmds import maya.OpenMayaUI as mui class MyDialog(QtWidgets.QDialog): def __init__(self, parent, **kwargs): super(MyDialog, self).__init__(parent, **kwargs) self.setObjectName(\u0026#34;MyWindow\u0026#34;) self.resize(800, 600) self.setWindowTitle(\u0026#34;PyQt ModelPanel Test\u0026#34;) self.verticalLayout = QtWidgets.QVBoxLayout(self) self.verticalLayout.setContentsMargins(0,0,0,0) # need to set a name so it can be referenced by maya node path self.verticalLayout.setObjectName(\u0026#34;mainLayout\u0026#34;) # First use SIP to unwrap the layout into a pointer # Then get the full path to the UI in maya as a string layout = mui.MQtUtil.fullName(long(shiboken2.getCppPointer(self.verticalLayout)[0])) cmds.setParent(layout) paneLayoutName = cmds.paneLayout() # Find a pointer to the paneLayout that we just created ptr = mui.MQtUtil.findControl(paneLayoutName) # Wrap the pointer into a python QObject self.paneLayout = shiboken2.wrapInstance(long(ptr), QtWidgets.QWidget) self.cameraName = cmds.camera()[0] self.modelPanelName = cmds.modelPanel(\u0026#34;customModelPanel\u0026#34;, label=\u0026#34;ModelPanel Test\u0026#34;, cam=self.cameraName) # Find a pointer to the modelPanel that we just created ptr = mui.MQtUtil.findControl(self.modelPanelName) # Wrap the pointer into a python QObject self.modelPanel = shiboken2.wrapInstance(long(ptr), QtWidgets.QWidget) # add our QObject reference to the paneLayout to our layout self.verticalLayout.addWidget(self.paneLayout) def showEvent(self, event): super(MyDialog, self).showEvent(event) # maya can lag in how it repaints UI. Force it to repaint # when we show the window. self.modelPanel.repaint() def show(): # get a pointer to the maya main window ptr = mui.MQtUtil.mainWindow() # use sip to wrap the pointer into a QObject win = shiboken2.wrapInstance(long(ptr), QtWidgets.QWidget) d = MyDialog(win) d.show() return d try: dialog.deleteLater() except: pass dialog = show() Older Maya \u0026lt; 2017 using Qt4 and PyQt4\nfrom PyQt4 import QtCore, QtGui import maya.cmds as cmds import maya.OpenMayaUI as mui import sip class MyDialog(QtGui.QDialog): def __init__(self, parent, **kwargs): super(MyDialog, self).__init__(parent, **kwargs) self.setObjectName(\u0026#34;MyWindow\u0026#34;) self.resize(800, 600) self.setWindowTitle(\u0026#34;PyQt ModelPanel Test\u0026#34;) self.verticalLayout = QtGui.QVBoxLayout(self) self.verticalLayout.setContentsMargins(0,0,0,0) # need to set a name so it can be referenced by maya node path self.verticalLayout.setObjectName(\u0026#34;mainLayout\u0026#34;) # First use SIP to unwrap the layout into a pointer # Then get the full path to the UI in maya as a string layout = mui.MQtUtil.fullName(long(sip.unwrapinstance(self.verticalLayout))) cmds.setParent(layout) paneLayoutName = cmds.paneLayout() # Find a pointer to the paneLayout that we just created ptr = mui.MQtUtil.findControl(paneLayoutName) # Wrap the pointer into a python QObject self.paneLayout = sip.wrapinstance(long(ptr), QtCore.QObject) self.cameraName = cmds.camera()[0] self.modelPanelName = cmds.modelPanel(\u0026#34;customModelPanel\u0026#34;, label=\u0026#34;ModelPanel Test\u0026#34;, cam=self.cameraName) # Find a pointer to the modelPanel that we just created ptr = mui.MQtUtil.findControl(self.modelPanelName) # Wrap the pointer into a python QObject self.modelPanel = sip.wrapinstance(long(ptr), QtCore.QObject) # add our QObject reference to the paneLayout to our layout self.verticalLayout.addWidget(self.paneLayout) def showEvent(self, event): super(MyDialog, self).showEvent(event) # maya can lag in how it repaints UI. Force it to repaint # when we show the window. self.modelPanel.repaint() def show(): # get a pointer to the maya main window ptr = mui.MQtUtil.mainWindow() # use sip to wrap the pointer into a QObject win = sip.wrapinstance(long(ptr), QtCore.QObject) d = MyDialog(win) d.show() return d try: dialog.deleteLater() except: pass dialog = show() You need sip and the MQtUtil functions to convert between maya node paths and python Qbjects. Its the same idea as having to use those functions to get a reference to the maya MainWindow, in order to parent your dialog.\n","date":"Nov 21, 2011","permalink":"https://justinfx.com/2011/11/20/mixing-pyqt4-widgets-and-maya-ui-objects/","section":"Blogs","summary":"\u003cp\u003eA question came up in the \u003ca href=\"http://groups.google.com/group/python_inside_maya\" target=\"_blank\" rel=\"noreferrer\"\u003eMaya-Python mailing list\u003c/a\u003e that I thought was a really good topic, and should be reposted.\u003c/p\u003e\n\u003cp\u003eSomeone asked how you can create maya UI objects and embed them within your main PyQt application. Specifically he wanted to create a modelPanel and embed it so that he would have a camera view within his own PyQt window.\u003c/p\u003e","title":"Mixing PyQt4 widgets and Maya UI objects"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/pyqt/","section":"Tags","summary":"","title":"Pyqt"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/sip/","section":"Tags","summary":"","title":"Sip"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/ui/","section":"Tags","summary":"","title":"UI"},{"content":"\nSecond video in the python for maya series, just released through cmiVFX!\nPython For Maya – Volume 2 #If you watched the first video, you now have a good grasp on Python. Sweet. Let’s plow through some more involved concepts like python juggernauts!\nWith a working knowledge of the python scripting language, and the Maya Python commands API, we can continue to learn new ways to solve more challenging problems, create complete scripts, and build user interfaces around our tools. We also introduce the Maya Python API; a lower-level interface into Maya.\nThis video focuses more on breaking down full scripts, as opposed to typing out syntax. Its jam packaged with information and moves fast to deliver you as much brain food as possible. The first segment of the video transitions from beginning to intermediate level, with the majority of the video being intermediate, and finishing out by touching on advanced concepts. The included project files are abundant, complete, and full of helpful documentation so that you can take your time and learn about each piece of the tools.\nIf you check it out, leave me feedback!\nhttps://cmivfx.com/store/328-python-for-maya-vol-02\nFirst video can be found here\n","date":"Nov 15, 2011","permalink":"https://justinfx.com/2011/11/15/python-for-maya-artists-volume-2/","section":"Blogs","summary":"\u003cp\u003e\u003ca href=\"https://cmivfx.com/store/328-python-for-maya-vol-02\" target=\"_blank\" rel=\"noreferrer\"\u003e\u003cimg class=\"alignnone\" src=\"/uploads/2011/11/maya_python_vol2.jpg\" alt=\"\" width=\"60%\" height=\"60%\" /\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eSecond video in the python for maya series, just released through \u003ca href=\"http://www.cmivfx.com\" target=\"_blank\" rel=\"noreferrer\"\u003ecmiVFX\u003c/a\u003e!\u003c/p\u003e\n\u003ch3 id=\"python-for-maya--volume-2\" class=\"relative group\"\u003e\u003ca href=\"https://cmivfx.com/store/328-python-for-maya-vol-02\" target=\"_blank\" rel=\"noreferrer\"\u003ePython For Maya – Volume 2\u003c/a\u003e \u003cspan class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100\"\u003e\u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\" style=\"text-decoration-line: none !important;\" href=\"#python-for-maya--volume-2\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\u003c/span\u003e\u003c/h3\u003e\u003cp\u003e\u003cem\u003eIf you watched the first video, you now have a good grasp on Python. Sweet. Let’s plow through some more involved concepts like python juggernauts!\u003c/em\u003e\u003c/p\u003e","title":"Python for Maya Artists – Volume 2"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/2012/","section":"Tags","summary":"","title":"2012"},{"content":"This is a follow up post to my previous one on Installing PyQt4 for Maya 2011\nRecently while putting together my next video tutorial for Python for Maya, I came to a section where I wanted to demo PyQt4 in Maya2012. But I was concerned that viewers would have to go through the complicated steps of building PyQt4. I noticed that other people have made available precompiled PyQt installers for windows (here) but I could not find any for OSX or linux. So I decided to put together a build.\nI created a new project on github called MyQt4\nhttps://github.com/justinfx/MyQt4\nIts a Makefile for completely downloading and building PyQt4 for maya, and generating a .pkg installer. Hopefully someone can contribute improvements since I dont have a ton of experience writing makefiles, and also that someone might create a linux version.\nHere is a link to the latest pkg build:\n**Snow Leopard: **\nMaya2011: MyQt4.7.4-maya2011-x64-osx-10.6.pkg Maya2012: MyQt4.9.4-maya2012-x64-osx-10.6.pkg Maya2013: MyQt4.9.4-maya2013-x64-osx-10.6.pkg **Lion: **\nMaya2012: MyQt4.8.6-maya2012-x64-osx-10.7.pkg (Thanks Chris!) Maya2013: MyQt4.8.6-maya2013-x64-osx-10.7.pkg Mountain Lion:\nMaya2011: MyQt4.7.4-maya2011-x64-osx-20130114.pkg Here are builds other people have made:\nWin 32bit: http://blarg.robertkist.com/?p=51{.broken_link} Win 64bit: http://nathanhorne.com/?p=322 Win 7 64bit Maya 2013: https://www.box.com/s/1db3b0c903059ac89fc4 Linux: http://www.kurianos.com/wordpress/?p=551 ","date":"Nov 10, 2011","permalink":"https://justinfx.com/2011/11/09/installing-pyqt4-for-maya-2012-osx/","section":"Blogs","summary":"\u003cp\u003eThis is a follow up post to my previous one on \u003ca href=\"/2011/01/07/installing-pyqt-for-maya-2011-osx/\"\u003eInstalling PyQt4 for Maya 2011\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eRecently while putting together my next video tutorial for Python for Maya, I came to a section where I wanted to demo PyQt4 in Maya2012. But I was concerned that viewers would have to go through the complicated steps of building PyQt4. I noticed that other people have made available precompiled PyQt installers for windows (\u003ca href=\"http://blarg.robertkist.com/?p=51\" target=\"_blank\" class=\"broken_link\"\u003ehere\u003c/a\u003e) but I could not find any for OSX or linux. So I decided to put together a build.\u003c/p\u003e","title":"Installing PyQt4 for Maya 2012+ (osx)"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/cmivfx/","section":"Tags","summary":"","title":"Cmivfx"},{"content":"\nJust released my first online video tutorial, through cmiVFX\nPython Introduction Vol 01 – Maya #Amazing at Animation? Master of Modeling? Conquistador of Character Rigging?\nBut how is your Python?\nThis course brings the talented artist into the fold of the technical-side of Maya. Learn the basics of Python, and its place in your 3D workflow, with visual examples and real world problems. Get a kick-start on adding some automation into your life, and solving common problems in a fraction of the time. By the end of this video, you should have a deeper understanding of one of the languages Maya speaks under the hood, and how to start viewing your scenes in terms of glorious Python code!\nCheck it out: http://cmivfx.com/store/320-Python+Introduction+Vol+01+-+Maya\nIf you check out this course, please leave me some feedback! I would love to hear your thoughts.\nStay tuned for more installments to come!\n","date":"Oct 8, 2011","permalink":"https://justinfx.com/2011/10/08/intro-to-python-for-maya-artists-tutorial/","section":"Blogs","summary":"\u003cp\u003e\u003ca href=\"https://cmivfx.com/python-introduction-vol-01---maya\" target=\"_blank\" rel=\"noreferrer\"\u003e\u003cimg class=\"alignnone\" alt=\"\" src=\"/uploads/2011/10/1318089294_Python_Background_master.jpg\" width=\"60%\" height=\"60%\" /\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eJust released my first online video tutorial, through \u003ca href=\"http://www.cmivfx.com\" target=\"_blank\" rel=\"noreferrer\"\u003ecmiVFX\u003c/a\u003e\u003c/p\u003e\n\u003ch3 id=\"python-introduction-vol-01--maya\" class=\"relative group\"\u003e\u003ca href=\"http://cmivfx.com/store/320-Python\u0026#43;Introduction\u0026#43;Vol\u0026#43;01\u0026#43;-\u0026#43;Maya\" target=\"_blank\" rel=\"noreferrer\"\u003ePython Introduction Vol 01 – Maya\u003c/a\u003e \u003cspan class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100\"\u003e\u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\" style=\"text-decoration-line: none !important;\" href=\"#python-introduction-vol-01--maya\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\u003c/span\u003e\u003c/h3\u003e\u003cp\u003e\u003cem\u003eAmazing at Animation? Master of Modeling? Conquistador of Character Rigging?\u003c/em\u003e\u003c/p\u003e\n\u003cp\u003eBut how is your Python?\u003c/p\u003e","title":"Intro to Python for Maya Artists – Tutorial"},{"content":" # Preface #I’ve been programming in python for over 5 years now, and I love the language a lot. I would look for any opportunity to accomplish my coding tasks using python, as opposed to learning new languages. PyQt4 for user interfaces, Django for web design, etc… And when python just isn’t an option, I have done my share of php, javascript, objective-c and so on.\nRecently I started thinking that I should probably expand my programming knowledge a bit to make myself more marketable.\nWhile python is pretty key in the world of Visual Effects pipelines… so is C++. Having previously focused on being a Compositor and not a programmer, I had always told myself that if I needed to learn C++, then I was going too far in that direction. But now that I have been working in pipeline development for over 2.5 years, it has become clear that I really should explore the world of compiled languages.\nGrabbing some books on C+, I dove in. Yuk. Why is it so freaking boring? It really does suck trying to learn C++ after having been so spoiled with python for so long. Its like taking a Aborigine and trying to turn him into a snooty English gentleman. Hmm…Is that right? Well whatever. Its completely disorienting. So many things that I never had to think about, like type declarations, memory management, pointers… But I kept on reading and learning.\nThen I came across a post on Google+, by someone that actually works at Google, mentioning a language being developed in-house. So I started reading about Go @ http://golang.org/\nThe Go Language #From the standpoint of a python programmer, Go feels like it sits right between C/C++ and python. You get the simpler syntax, but with the speed of a compiled language. Because Go has garbage collection, memory management isn’t a concern. I was never used to the code/compile/test/repeat pattern before, but it compiles so fast and is so easy to set up a project that it feels pretty natural. Go doesn’t require you to have header files and declare everything in advance, so banging out a simple program is quite fast and only slightly more overhead than writing a python script. Just have to add the step of compiling it. As far as the library, so far I have found everything pretty useful. And it seems that every time I search for a Go binding for something, I find one. I will go into more detail on that in a bit.\nOne thing that will make python programmers feel more at home is the type inference while creating a variable. While you can do something like this in Go: var myString string = \u0026quot;Foo\u0026quot; you can also type the same thing like this: myString := \u0026quot;Foo\u0026quot;\nThe := operator lets you initialize a new variable and makes the compiler figure out what type it should be, based on the return type of the right hand side.\nPointers are still kind of strange for python programmers, but Go is a lot more flexible about using them. You don’t always have to explicitly dereference them like (*myPointer).myFunction(). It just does it for you when you access member functions and attributes: myPointer.myFunction().\nHaving no type inheritance is also a bit different as well. Instead of creating base abstract classes, and subclassing them, you only have structs… no classes. But you share functionality by using interfaces. An interface is just a definition of methods. If any object implements those methods, its consider that type of interface. This is something I have yet to really get into, since my current first project is more of a cmd program, rather than a pkg library. I’m sure I could be using interfaces already, but it hasn’t quite felt natural enough to incorporate as of yet.\nA pretty crazy aspect of Go is its native support for concurrency using what they call “Goroutines”. The closest way I have been able to compare it to my experience in python is while using ZeroMQ for messaging. ZeroMQ promotes not only using its library for messaging, but also to replace issues with threads and locks. It has similar concepts in promoting concurrency. You divide your program up into its components and instead of sharing data structures between them, you communicate over channels (sockets in ZeroMQ). When you fire off a Goroutine, you aren’t waiting for it anymore. It can run and do its thing and you keep on going. You can then send data back and forth with channels, and even use them just for signaling, like saying “ok now exit”.\nActual Usage #I’ve been writing a message server so far in python, using the Tornado web server, along with some socket.io bindings called TornadIO, and also ZeroMQ for internal communication. So far its been working pretty well, but there are a lot of complex layers, with ZeroMQ sort of riding on top of Tornados ioloop. I decided to try and rewrite this server in Go. Turns out Go has a lot of built-in support for doing exactly what this python server was doing. The whole web-socket server functionality is part of the standard http library module. I quickly found Go bindings for socket.io and I was on my way.\nIt was quite fast to get the server to the point of doing global messages, but now I had to think about implementing the support for channel subscriptions. My first instinct was to go grab ZeroMQ and its bindings again, or to use Redis for the messaging, but then I was thinking “Shouldn’t I be able to do all this with Go’s concurrency?”. One thing that really helped me out was how fast everyone responds on the golang-nuts discussion group. It was quickly pointed out by more than one person that I should definitely be able to accomplish the internal message routing purely in Go. And they were right. I just set up a “dispatcher” function and run it in a loop as a goroutine, and then pass messages in and out of it. The dispatcher manages its data structure, and no other part of the code accesses it directly.\nSo far, this Go server is turning out great, and I’m excited by the fact that its compiled and faster. I don’t have to distribute my source code now Performance # Disclaimer: These numbers are just comparisons between what I built in python vs Go. I think the point is to reflect what I naturally came up with on my first pass at using Go, vs applying years of python experience. I’m dead sure my Go code isn’t written as efficiently as someone with more experience, which I think makes it even more interesting of a comparison. Go comes with built in testing and benchmarking functionality. What I built was a client test that connects to a running server and rapid fires messages. It times how long it takes for a 150 byte message to be sent out, flow through the server, and come back to that client as been delivered. The gotest utility that is used to run the test code will run the test, and if it ran too fast to calculate timings, it will repeat the test over and over with larger iterations. When I first got my Go server working to where a client would send a message and it would just get broadcasted right back out to everyone, I ran a benchmark. Here are the results of my tests…\nTEST TIME PER MSG NET RESULT Python (Tornado, …) 835314 ns/op \u0026#8211; Go (barebones messaging) 107091 ns/op 7.8x faster Go (1-to-1 python port) 159823 ns/op 5.2x faster Go (weekly.12-01-2011) 76230 ns/op 11x faster The second Go test was after I finished implementing the same 1-to-1 feature set of the python version. I had thought the numbers would be dramatically impacted after adding the overhead of all the internal message routing, but the Go server still came out almost 5x faster than the python version. And this is from my first attempt at writing a Go program! I bet once I get a lot more solid with the language I can optimize this code a lot more.\nConclusion #I’m pretty hooked on the language. I feel its the perfect option for a python programmer that wants some speed increases and simple concurrency, without having to learn something as intense as C++. Go is supposed to get faster and faster as they improve things like the goroutines, channels, and the garbage collector, so its a great time to jump in and start learning. Its really helped me understand more formal concepts that will probably make learning C++ even easier once I decide to go back to learning it ","date":"Jul 28, 2011","permalink":"https://justinfx.com/2011/07/28/go-language-for-python-programmers/","section":"Blogs","summary":"\u003ch3 id=\"\" class=\"relative group\"\u003e \u003cspan class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100\"\u003e\u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\" style=\"text-decoration-line: none !important;\" href=\"#\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\u003c/span\u003e\u003c/h3\u003e\u003ch3 id=\"preface\" class=\"relative group\"\u003e\u003ca href=\"http://golang.org\" target=\"_blank\" rel=\"noreferrer\"\u003e\u003cimg class=\"alignleft\" src=\"https://blog.golang.org/gopher/gopher.png\" alt=\"\" width=\"116\" height=\"142\" /\u003e\u003c/a\u003e Preface \u003cspan class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100\"\u003e\u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\" style=\"text-decoration-line: none !important;\" href=\"#preface\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\u003c/span\u003e\u003c/h3\u003e\u003cp\u003eI’ve been programming in python for over 5 years now, and I love the language a lot. I would look for any opportunity to accomplish my coding tasks using python, as opposed to learning new languages. PyQt4 for user interfaces, Django for web design, etc… And when python just isn’t an option, I have done my share of php, javascript, objective-c and so on.\u003c/p\u003e\n\u003cp\u003eRecently I started thinking that I should probably expand my programming knowledge a bit to make myself more marketable.\u003c/p\u003e","title":"Go language for python programmers"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/programming/","section":"Tags","summary":"","title":"Programming"},{"content":"Update: #I am now hosting a built package for Maya2011: MyQt4.7.4-maya2011-x64-osx-10.6.pkg And for Maya 2012+, see: Installing pyqt4 for maya2012\nPersonally, when trying to run PyQt from within Maya 2009 / 2010 using the pumpThread method, I never had much luck. The best I ever got was the ability to bring up a dialog but not without locking up the UI, even though the pumpThread tool is meant to address that.\nAnyways, when I found out Maya 2011 was rewritten based on Qt for the UI, I was really stoked. I saw the example video of being able to design a ui file in Designer, and just directly open it in a maya script, and all I could think about was designing Qt GUIs so much more easily now. Turns out that Maya 2011 didn’t actually ship with PyQt included for licensing reasons I’m sure. But it included documentation on how one could go about building PyQt for maya. Unfortunately I had tons of issues that caused maya to just crash when importing PyQt.\nWhat I finally figured out was a mish-mash of information from the maya documention, and different forums and user groups. So I decided to make this easier on anyone having the same problems as I did, and just collect that information into one place. This process is for OSX. I’m sure most of it is probably still relevant to linux or win, except for the last parts with ‘install_name_tool’. You would just need to make sure to find the right Qt/PyQt/SIP packages for your OS.\nBuilding PyQt4 for Maya 2011 on OSX # Update for Maya 2012 #While Maya uses newer versions, it seems the versions from the 2011 install still work. But here they are anyways incase you want the newer version for 2012:\nAutodesk modified qt 4.7.1 sip 4.12.4 pyqt 4.8.6 Make sure you have downloaded and installed the latest XCode from Apple. Its also included on your OSX installation disc.\nQt: Maya has a specific version of Qt built into it. This is Qt 4.5.3. # Download: qt-mac-opensource-src-4.5.3.tar.gz\nExtract: tar zxvf qt-mac-opensource-src-4.5.3.tar.gz cd qt-mac-opensource-src-4.5.3\nBuild and install: ./configure -cocoa -arch x86_64 -debug-and-release \\ -no-phonon -no-phonon-backend -no-qt3support \\ -no-webkit -nomake docs -nomake examples -nomake demos \\ -nomake translations -no-rpath -no-framework make -j 8 sudo make install\nSIP: The maya docs recommend sip version 4.10 # Download this specific SIP: sip-4.10.tar.gz\nExtract: tar zxvf sip-4.10.tar.gz cd sip-4.10\nBuild and install: /Applications/Autodesk/maya2011/Maya.app/Contents/bin/mayapy \\ configure.py --arch=x86_64 make -j 8 sudo make install\nPyQt4: The maya docs suggest PyQt 4.7 # Download this specific PyQt: PyQt-mac-gpl-4.7.4.tar.gz\nExtract: tar zxvf PyQt-mac-gpl-4.7.3.tar.gz cd PyQt-mac-gpl-4.7.3\nSet up some environment variables before building: export QTDIR=/usr/local/Trolltech/Qt-4.5.3 export PATH=/usr/local/Trolltech/Qt-4.5.3/bin:$PATH export QMAKESPEC=/usr/local/Trolltech/Qt-4.5.3/mkspecs/macx-g++ export DYLD_LIBRARY_PATH=/usr/local/Trolltech/Qt-4.5.3/lib\nBuild and install: /Applications/Autodesk/maya2011/Maya.app/Contents/bin/mayapy \\ configure.py \\ LIBDIR_QT=/usr/local/Trolltech/Qt‐4.5.3/lib \\ INCDIR_QT=/usr/local/Trolltech/Qt‐4.5.3/include \\ MOC=/usr/local/Trolltech/Qt‐4.5.3/bin/moc \\ -w --no-designer-plugin make -j 8 sudo make install\nPyQt4 will now be installed into Maya’s python site-packages, BUT will be linked against the wrong Qt binaries. The maya docs have an annoying multi step set of commands but they don’t copy/paste nicely, so here is a for-loop you can use: for mod in Core Gui Svg OpenGL Xml do sudo find /Applications/Autodesk/maya2011/Maya.app/Contents/Frameworks/Python.framework/Versions/Current/lib/python2.6/site-packages/PyQt4 -name \u0026#34;*so\u0026#34; \\ -exec install_name_tool -change libQt${mod}.4.dylib @executable_path/Qt${mod} {} ; done\nAt this point you should be able to start up Maya and import and run PyQt from the script editor. You no longer need the pumpThread. Here is a test code snippet that I borrowed from here (the original had typos in it that I corrected)\nimport maya.OpenMayaUI as mui from PyQt4.QtCore import * from PyQt4.QtGui import * def getMayaWindow(): ptr = mui.MQtUtil.mainWindow() return sip.wrapinstance(long(ptr), QObject) class Form(QDialog): def __init__(self, parent=None): super(Form, self).__init__(parent) self.setWindowTitle(\u0026#39;Test Dialog\u0026#39;) self.setObjectName(\u0026#39;mainUI\u0026#39;) self.mainLayout = QVBoxLayout(self) self.myButton = QPushButton(\u0026#39;myButton\u0026#39;) self.mainLayout.addWidget(self.myButton) global app global form app = qApp form = Form(getMayaWindow()) form.show() It doesn’t seem like you even need the install of Qt 4.5.3 that we did at this point since we changed the links, unless you use another Qt module besides QtCore, QtGui, QtSvg, QtXml, QtOpenGL (such as QtNetwork), but this could be solved by copying over the missing libs to where Maya is expecting them. Example for copying over QtNetwork:\nsudo cp /usr/local/Trolltech/Qt-4.5.3/lib/libQtNetwork.* /Applications/Autodesk/maya2011/Maya.app/Contents/MacOS sudo install_name_tool -change libQtCore.4.dylib @executable_path/QtCore /Applications/Autodesk/maya2011/Maya.app/Contents/MacOS/libQtNetwork.4.dylib If you happen to have a mixed library environment like me, with more than one python lib location for code, and you see any funny errors while importing a module, just make sure that mayas python site-package is always in the front of the sys.path:\nsys.path.insert(0,\u0026#39;/Applications/Autodesk/maya2011/Maya.app/Contents/Frameworks/Python.framework/Versions/Current/lib/python2.6/site-packages\u0026#39;) And there you have it. PyQt4 now installed in Maya 2011 under OSX.\nReferences:\nhttp://images.autodesk.com/adsk/files/pyqtmaya2011.pdf groups.google.com/group/python_inside_maya http://community.softimage.com/forum/autodesk-maya/python/pyqt-and-maya-pyqt-window-parented-to-maya-window/ ","date":"Jan 8, 2011","permalink":"https://justinfx.com/2011/01/07/installing-pyqt-for-maya-2011-osx/","section":"Blogs","summary":"\u003ch4 id=\"update\" class=\"relative group\"\u003eUpdate: \u003cspan class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100\"\u003e\u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\" style=\"text-decoration-line: none !important;\" href=\"#update\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\u003c/span\u003e\u003c/h4\u003e\u003cp\u003eI am now hosting a built package for Maya2011: \u003ca href=\"https://dl.dropbox.com/u/34613220/MyQt4/MyQt4.7.4-maya2011-x64-osx-10.6.pkg\" target=\"_blank\" rel=\"noreferrer\"\u003eMyQt4.7.4-maya2011-x64-osx-10.6.pkg\u003c/a\u003e And for Maya 2012+, see: \u003ca href=\"/2011/11/09/installing-pyqt4-for-maya-2012-osx/\"\u003eInstalling pyqt4 for maya2012\u003c/a\u003e\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003ePersonally, when trying to run PyQt from within Maya 2009 / 2010 using the pumpThread method, I never had much luck. The best I ever got was the ability to bring up a dialog but not without locking up the UI, even though the pumpThread tool is meant to address that.\u003c/p\u003e","title":"Installing PyQt for maya 2011 (OSX)"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/atomsplitter/","section":"Tags","summary":"","title":"Atomsplitter"},{"content":"We finally decided to release the source code for AtomSplitter, since we were getting some feedback that the application builds weren’t 100% working on every possible system.\nUpdate #1: #I have posted the AtomSplitter project on github now: https://github.com/justinfx/AtomSplitter\nProject site:\nhttp://redmine.justinfx.com/projects/atomsplitter\nThe current version is 1.6.2, which adds the cmivfx chatroom to a tab, and some minor bug fixes. More info:\nhttp://www.cmivfx.com/productpages/product.aspx?name=AtomSplitter_1.6\n","date":"Oct 8, 2010","permalink":"https://justinfx.com/2010/10/08/atomsplitter-source-code-released/","section":"Blogs","summary":"\u003cp\u003eWe finally decided to release the source code for AtomSplitter, since we were getting some feedback that the application builds weren’t 100% working on every possible system.\u003c/p\u003e","title":"AtomSplitter source code released"},{"content":" AtomSplitter has been updated to v1.6, available through cmivfx.com\nAtomSplitter 1.6 – cmiVFX.com\nUpdates:\nExports Terragen .tgd scene file format See the original post.\nCOMMAND LINE HELP OSX: AtomSplitter.app/Contents/MacOS/AtomSplitter \u0026lt;chan file\u0026gt; [out file] Linux: AtomSplitter \u0026lt;chan file\u0026gt; [out file] Windows: AtomSplitter.exe \u0026lt;chan file\u0026gt; [out file] ========================================= HELP: $ AtomSplitter -h Usage: AtomSplitter \u0026lt;chan file\u0026gt; [out file] Options: -h, --help show this help message and exit -o OBJ, --obj=OBJ Optional nuke-exported pointCloud .obj file -f FPS, --fps=FPS Set FPS rate (default 24) -x WIDTH, --width=WIDTH Set frame width (default 2048) -y HEIGHT, --height=HEIGHT Set frame height (default 1556) --filmwidth=FILMWIDTH Set film aperature width in mm (default 24.576) --filmheight=FILMHEIGHT Set film aperature height in mm (default 18.672) -s SCALE, --scale=SCALE Scale the translation values by this amount -F FORMAT, --format=FORMAT Output format (fbx, action, terragen) ","date":"Aug 31, 2010","permalink":"https://justinfx.com/2010/08/31/208/","section":"Blogs","summary":"\u003cimg src=\"/uploads/2009/12/chan2fbx.jpg\"\u003e\n\u003cp\u003eAtomSplitter has been updated to v1.6, available through cmivfx.com\u003c/p\u003e","title":"AtomSplitter v1.6 update"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/chan/","section":"Tags","summary":"","title":"Chan"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/nuke/","section":"Tags","summary":"","title":"Nuke"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/curves/","section":"Tags","summary":"","title":"Curves"},{"content":"This is a story about my journey in solving a problem at work involving curves. The solution seemed really simple at first, but because of a stupid Maya issue, this turned into me having to rewrite the tool 3 times before I discovered a surprising solution.\nThe Problem: #Because we rely heavily on the process of importing Illustrator .ai files into Maya as nurbsCurves, we constantly have to deal with curves that intersect themselves. This is a result of the curves having been hand drawn originally in the art department, and they posed issues during rendering after being planar-ized.\nWe needed a way to detect self-intersecting nurbsCurves, so that we could fix them before working with them as nurbsSurfaces.\nLoop Curves (self-intersection) Getting started. I hate you, Maya: #The obvious place for me to start was to use the existing curveIntersect command. This command will tell you if two curves intersect, and at what points. Although it requires that you tell it 2 individual curves to test, I figured I could just split the single curve into parts (using detach curve), and pair off all the parts to test them. And here is where I ran into something that just pissed me off. While it works great to tell you where the intersection is… when it DOESN’T find an intersection, it prints a “Warning: Could not find curve-curve intersection” line. Printing to the script editor in maya is SUPER expensive as I have found. Everything slows down. This was the initial reason I decided not to use this method. I later found out the RIGHT hack way to deal with this is to wrap the entire process in scriptEditorInfo commands to suppress warnings being printed to the Script Editor and re-enable after. This method does prevent the amazing slowness, but still has the unacceptable flood of warnings once suppression is turned back off again. So even with this fix, I still found this approach to be too slow. For a single complex curve object that might have, say, 500 spans… that would be 124750 unique combinations that would have to be tested with the curveIntersect command. In a test of just looping that many times and calling this command, the process took 54 seconds! No way could this work, with a scene that could easily have 2000+ nurbsCurves!\nGreat. Now I get to investigate my own intersection detection from scratch.\nApproach #2 – Brute Force #I’m a film school graduate… not a computer science major. Never thought I would have to use the kind of math I TRIED to implement for a first solution. Solving the cubic function of every curve segment to find the intersections? Meh. Too hard.\nNext I thought of an idea to take a curve and sample N-amount of points from start to end parameter. So lets say 1000 samples. I would get 1000 points on the curve, then compare each point to the other non-neighboring points to see if they are within a distance tolerance of each other. If they are, I consider this a point in the curve where it looped and self-intersected. This method did work. It was still not super fast, but no where NEAR as slow as using the intersect command. I built in some dynamic scaling of the sampling and tolerance to accommodate for curves of different size and complexity. Even though I had to test 499500 point combinations per nurbsCurve for the 1000 point samples, this was only math and not a repeat call to curveIntersect. Ultimately, I was still not where I needed to be in terms of usability. A complex curve could still be a few seconds to test. Still too slow.\nApproach #2.5 – Brute Force mixed with a fast little pre-check #Amongst the tons of search results I waded through on google, I found a really cool little trick someone came up with: http://forums.cgsociety.org/archive/index.php/t-517347.html\nHe suggested a cool hack where you planar the surface, then convert it to polygon with certain options, and then count the number of resulting faces that were produced. Theoretically there should only be 1 face if the curve never intersected itself. If it did, those loops should also have faces.\nWell then, why couldn’t I just use this method as my detection algorithm? While it was pretty darn fast since no iteration is involved, I discovered a few limited cases where I was getting False Negatives: The method said there was only one face (no intersection) on a curve that actually did have a self intersection. So I decided to use this as a pre-check to save time. If it DID say there was self-intersection, great! Log it. Otherwise, slow test it with the brute force method.\nApproach #3 – Math that I never learned #At this point I had accepted the solution for detecting self-intersection, and moved on to writing a maya UI for the tool. It would detect loops and optionally even report back the best estimate to the point where it actually occurred. But once I started writing another bigger tool that would use this script, I just knew it could be done faster with the power of math and without the poop of maya script command calls.\nBezier Clipping Method I discovered a paper written about a method called “Bezier Clipping” : Curve intersection using Bezier Clipping\nFor this method to be used on a single curve, one would first need to split the curve into its segments, in my case producing a bunch of cubic curves. With each pair of combinations, a bounding box check would be performed. If the bounding boxes do not overlap, you are done. No intersection would have occurred. If the bounding boxes did overlap, then you would start drilling down the check by clipping away sections of the curves outside the bounding box overlap. You can discover the intersection pretty fast by either drilling down until the segments are small enough to represent the single point, or the segments are now small enough to be considered linear and a you can use the slopes to find the intersection.\nI was really stoked by this idea. The paper made it look really straight forward. I ended up writing a really cool custom wrapper around a nurbsCurve object that could represent a sub-section of the curve, and could easily give me things like the length and parameter range. It had a split() method that could split the curve at a given length or parameter and give me back two sub-curves, of which each could further be split. This class was integrated into the Bezier Clipping method and I finally got it all working. The initial tests were amazingly fast, but I ended up finding that the process became quite slow on large numbers of complex curves. I attribute this to my implementation of the bezier clipping, not the method itself. I didn’t take the time to actually generate proper sub-segments based on the bounding box overlap, and instead just did a simple 50/50 split of each curve, and tested the new combinations. I think I was just so bummed about the performance results that I didn’t feel like making the improvements to the process would make enough of a difference. What I had now was ultimately slower than my brute force method when tested against an entire scene of curves. So I decided to just go back to that.\nApproach #4 – The unexpected trick #Whilst working on the larger project meant to make use of the loop detection script, I discovered something amongst the curve commands. offsetCurve includes the function of clipping away loops while creating the new offset curve object. My idea was to create an offsetCurve with the minimal changes, at a zero distance, so the curves would be right on top of each other. Then I could just compare the area/length/etc attributes of the curves to see if there was a change. This was really fast and really accurate, down to the smallest loops. Right now I’m comparing the area and length values rounded to a certain tolerance. This method was amazingly fast, and a fraction of the code.\nThe only minor downside was I found that because of the rounding I needed to do to compare the values, every so often a couple curves would be found as self-intersecting when they were not. Thats much better than MISSING curves during the detection. So what I did was combine the earlier face-counting solution with this one, to fail over between the two. The combination was really fast and accurate, without 100,000 warnings showing up in the stupid script editor.\nAll in all #I’m really surprised how many versions of this tool I had to write, to ultimately end up at a really simple one. I never would have thought to look at this offsetCurve command for a solution. Had to dig into some math I never thought I would use, also. So THATS what those stupid polynomial equations were for?\n","date":"Aug 9, 2010","permalink":"https://justinfx.com/2010/08/09/maya-and-self-intersecting-nurbscurves/","section":"Blogs","summary":"\u003cp\u003eThis is a story about my journey in solving a problem at work involving curves. The solution seemed really simple at first, but because of a stupid Maya issue, this turned into me having to rewrite the tool 3 times before I discovered a surprising solution.\u003c/p\u003e\n\u003ch4 id=\"the-problem\" class=\"relative group\"\u003eThe Problem: \u003cspan class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100\"\u003e\u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\" style=\"text-decoration-line: none !important;\" href=\"#the-problem\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\u003c/span\u003e\u003c/h4\u003e\u003cp\u003eBecause we rely heavily on the process of importing Illustrator .ai files into Maya as nurbsCurves, we constantly have to deal with curves that intersect themselves. This is a result of the curves having been hand drawn originally in the art department, and they posed issues during rendering after being planar-ized.\u003c/p\u003e","title":"Maya, and self-intersecting nurbsCurves"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/film-jam/","section":"Tags","summary":"","title":"Film Jam"},{"content":"I recently did an interview with my friends on their show, Film Jam. Its a podcast dealing with the film industry from the perspective of 3 guys working their way up the ladder. Fantastic show up ’till this point. Hopefully I don’t break the cycle Please make sure to leave a review about the show via iTunes!\nEpisode #20 #Playlist page\n","date":"Aug 5, 2010","permalink":"https://justinfx.com/2010/08/04/film-jam-podcast-interview/","section":"Blogs","summary":"\u003cp\u003eI recently did an interview with my friends on their show, Film Jam. Its a podcast dealing with the film industry from the perspective of 3 guys working their way up the ladder. Fantastic show up ’till this point. Hopefully I don’t break the cycle \u003ci class=\"fa fa-smile-o\" aria-hidden=\"true\"\u003e\u003c/i\u003e\u003c/p\u003e\n\u003cp\u003ePlease make sure to leave a review about the show via iTunes!\u003c/p\u003e\n\u003ch3 id=\"episode-20\" class=\"relative group\"\u003eEpisode #20 \u003cspan class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100\"\u003e\u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\" style=\"text-decoration-line: none !important;\" href=\"#episode-20\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\u003c/span\u003e\u003c/h3\u003e\u003cp\u003e\u003cspan style=\"color: #00ccff;\"\u003ePlaylist page\u003c/span\u003e\u003cspan style=\"color: #00ccff;\"\u003e\u003cbr /\u003e \u003c/span\u003e\u003c/p\u003e","title":"Film Jam Podcast Interview"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/podcast/","section":"Tags","summary":"","title":"Podcast"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/visual-effects/","section":"Tags","summary":"","title":"Visual Effects"},{"content":"AtomSplitter has been updated to v1.5, available through cmivfx.com\nAtomSplitter 1.5 – cmiVFX.com\nUpdates: Added the ability to convert point cloud data, exported from Nuke as a .obj, to be included in the fbx/action export. See the original post.\n","date":"May 26, 2010","permalink":"https://justinfx.com/2010/05/26/atomsplitter-v1-5-update/","section":"Blogs","summary":"\u003cp\u003eAtomSplitter has been updated to v1.5, available through cmivfx.com\u003c/p\u003e","title":"AtomSplitter v1.5 update"},{"content":"AtomSplitter (chanToFbx) has been updated to v1.2, available through cmivfx.com\nAtomSplitter 1.2 – cmiVFX.com\nUpdates:\nCamera rotation order set to ZXY, which is the Nuke camera default Fixed a bug where the FocalLength value was not being keyframed properly Added a scene scale field, for adjusting the translation values globally. If you haven’t visited cmiVFX.com before, PLEASE check them out. Chris Maynard does an amazing job rounding up top talent in the industry to create these outstanding visual fx tutorials. The information is always cutting edge.\nSee the original post.\n","date":"May 11, 2010","permalink":"https://justinfx.com/2010/05/11/atomsplitter-v1-2-update/","section":"Blogs","summary":"\u003cp\u003eAtomSplitter (chanToFbx) has been updated to v1.2, available through cmivfx.com\u003c/p\u003e","title":"AtomSplitter v1.2 update"},{"content":"","date":null,"permalink":"https://justinfx.com/page/","section":"Pages","summary":"","title":"Pages"},{"content":"Direct Link: PDF\nThis is a one page summary. My LinkedIn profile has my complete professional history.\n","date":null,"permalink":"https://justinfx.com/vfx-resume/","section":"Pages","summary":"\u003cp\u003eDirect Link: \u003ca href=\"https://drive.google.com/open?id=0B9Jy7IiM00tZNDkzNDYyZTUtNTZkNC00YWVhLWJiYWQtNWJkMWY0ZDNjNDBj\" target=\"_blank\"\u003ePDF\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eThis is a one page summary. My \u003ca href=\"https://www.linkedin.com/in/justinisrael/\" target=\"_blank\" rel=\"noopener noreferrer\"\u003eLinkedIn profile\u003c/a\u003e has my complete professional history.\u003c/p\u003e\n\u003ciframe id=\"resume-frame\" src='/public/resume/index.html'\nscrolling='no'\nframeborder='0'\nwidth=\"100%\"\nstyle=\"height: 300vh;\"\u003e\n\u003c/iframe\u003e\n\u003cscript\u003e\n  (function () {\n    var f = document.getElementById('resume-frame');\n    function fit() {\n      try { f.style.height = f.contentDocument.documentElement.scrollHeight + 'px'; } catch (e) {}\n    }\n    f.addEventListener('load', function () {\n      fit();\n      new ResizeObserver(fit).observe(f.contentDocument.documentElement);\n    });\n  })();\n\u003c/script\u003e","title":"VFX Resume"},{"content":"These are a collection of short films I have made over the years…\nOut of Touch (2006) # Synopsis:\nJohn is a social recluse who has devised a series of patterns to avoid contact with people. These patterns ensure John can live like a machine, without thought or question. That is… until the slightest unpredictable event throws his entire pattern out of balance. Only through this forced circumstance can John face his greatest fear… his own mind.\nNotes:\nShot in my final year of film school, this short was my first true HD project. We used the Sony CineAlta F900 camera, which shot at 1080p/24. The sound design/score is original and done by the same artist as my short film, Lucid. One of the many challenges of this film was the number of shots I WANTED to get versus what we really had the time to accomplish. The camera was expensive and we really only had 2 weekends to accomplish the shoot. The size of the case and crew was up to about 25 at any one time. Locations were both in downtown LA and Long Beach, CA. The budget for the film was around $6500\nLucid (2004) # Synopsis:\nA young man journeys through the twisted dimensions of his own mind, all the while being stalked by a devious tormentor.\nNotes:\nThis was shot during my first year of film school, on the Panasonic DVX100a, right when it had been released. It was also my first 24p project. The budget of the film was about $300 and was shot in a single weekend, and edited/fx in a couple days. The sound design/score is original.\nhttps://www.imdb.com/title/tt0898930/\nFlapjacks (2005) # Tag Line:\nHow would different directors go about shooting a clown flipping a pancake?\nNotes:\nA requirement of my intermediate film class was to shoot a short on 16mm, with a limitation of about 500ft of film, and a single day production time. The way the process actually worked, was that we were in groups of about 8 people and rotated positions on each film. On a single weekend, one director would shoot on a saturday, and the next on sunday. Then the next two would direct on the following weekend.\nThis film was challenging not only because of the limited time frame, but also because I chose to use color AND black and white rolls which meant an extra change of the mag and increased costs of post production.\nReverie of the Other (2004) # Synopsis:\nA down-and-out man dreams about his perfect woman.\nNotes:\nThis was one of the first films I had shot in the entry-level production class at film school. The camera was a cheap sony VX-2000, which ran at standard def 29.97fps. I forget what the actual requirements were, other than coming up with an original idea. But I shot this with something like a 3-man crew, in a bar in San Marcos, CA (The Jumping Turtle).\n","date":null,"permalink":"https://justinfx.com/short-films/","section":"Pages","summary":"\u003cp\u003eThese are a collection of short films I have made over the years…\u003c/p\u003e\n\u003chr\u003e\n\u003ch3 id=\"out-of-touch-2006\" class=\"relative group\"\u003eOut of Touch (2006) \u003cspan class=\"absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100\"\u003e\u003ca class=\"group-hover:text-primary-300 dark:group-hover:text-neutral-700\" style=\"text-decoration-line: none !important;\" href=\"#out-of-touch-2006\" aria-label=\"Anchor\"\u003e#\u003c/a\u003e\u003c/span\u003e\u003c/h3\u003e\u003cdiv class=\"js-video vimeo\"\u003e\n\t\u003ciframe src=\"https://player.vimeo.com/video/12067694?byline=0\" \n\t        width=\"640\" \n\t        height=\"360\" \n\t        frameborder=\"0\" \n\t        mozallowfullscreen \n\t        allowfullscreen \u003e\n\t\u003c/iframe\u003e\n\u003c/div\u003e\n\u003cp\u003e\u003cstrong\u003eSynopsis\u003c/strong\u003e:\u003c/p\u003e\n\u003cp\u003eJohn is a social recluse who has devised a series of patterns to avoid contact with people. These patterns ensure John can live like a machine, without thought or question. That is… until the slightest unpredictable event throws his entire pattern out of balance. Only through this forced circumstance can John face his greatest fear… his own mind.\u003c/p\u003e","title":"Short Films"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/phonon/","section":"Tags","summary":"","title":"Phonon"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/plugin/","section":"Tags","summary":"","title":"Plugin"},{"content":"“App’ing up” PyQt… ugh.\nOne of biggest problems with PyQt is distributing it in a stand-alone package. Even worse… wanting to make your Qt plugins still function (Phonon, jpeg, etc). At work I constantly had this battle, along with my co-worker Tory. She actually has a long-standing issue with this, and had to resort to workarounds or half fixes. Here is Tory’s original post regarding the issue .\nI would see an error similar to this when trying to package up and run an app using the Phonon module.\nWARNING: bool Phonon::FactoryPrivate::createBackend() phonon backend plugin could not be loaded Running macdeployqt myAppName.app does add things like the jpeg plugin, but never seemed to fix the Phonon issue. I finally decided to randomly look online for a solution, again, last week. What I found was a partial solution, followed by me trying one more thing and bam…it worked! Video playback from my .app standalone package.\nHere is what I did …\n(btw you might have to modify the location of the plugin, since I happen to be using OSX)\nIn your setup.py file, which is used for py2app, py2exe, or similar… add this to the DATA_FILES list, so that it looks as such: # This will put the phonon backend plugin into the # RESOURCES folder in the app. DATA_FILES = [(\u0026#39;phonon_backend\u0026#39;, [ \u0026#39;/Developer/Applications/Qt/plugins/phonon_backend/libphonon_qt7.dylib\u0026#39; ])] Package up your application via py2app / py2exe / etc. If you are on OSX, use macdeployqt on the app: \u0026gt;\u0026gt;\u0026gt; macdeployqt myApp.app Go into the app that was created (show package contents if you are on a mac), and move the phonon_backend directory FROM the Resources directory TO the PlugIns directory (which should be at the same level as Resources). That should be it!\n","date":"Mar 19, 2010","permalink":"https://justinfx.com/2010/03/18/pyqt4-phonon-and-on-and-on/","section":"Blogs","summary":"\u003cp\u003e“App’ing up” PyQt… ugh.\u003c/p\u003e\n\u003cp\u003eOne of biggest problems with PyQt is distributing it in a stand-alone package. Even worse… wanting to make your Qt plugins still function (Phonon, jpeg, etc). At work I constantly had this battle, along with my co-worker Tory. She actually has a long-standing issue with this, and had to resort to workarounds or half fixes. \u003ca href=\"http://www.toryhoke.com/2009/03/03/pyqt4-i-hate-you/\" target=\"_blank\" rel=\"noreferrer\"\u003e\u003cspan style=\"color: #3366ff;\"\u003eHere is Tory’s original post regarding the issue\u003c/span\u003e\u003c/a\u003e .\u003c/p\u003e\n\u003cp\u003eI would see an error similar to this when trying to package up and run an app using the Phonon module.\u003c/p\u003e","title":"PyQt4: phonon… and on… and on"},{"content":"I get to do a lot of interesting applications at SouthPark. This one in particular was the most challenging use of PyQt that I have experienced to date.\nThe backstory….\nThe art department wanted a tool to help them track assigned tasks, the progress, and to share media and notes associated with the tasks. Furthermore, they wanted to be able to skin the interface with custom graphics to make it their own.\nProgress…\nDuring the winter break (about a month) I was able to come up with version 1.0 of TaskMonster. It was written in python, using PyQt for the UI, sqlalchemy to talk to the database, and twisted for the client/server communication. Each client app sends messages to a small server daemon which in turn tells the rest of the clients about the updates.\nVersion 2.0 Alpha…\nTony Postma, from the art department, put together a design in Corel which I could hopefully implement in the UI. It called for the users to be represented as little pods in a circle around the supervisor, Adrien Beard. And each user pod could be clicked and rotated into place, in order to view that persons tasks.\nAfter a bunch of testing I was able to design a rotating widget that could dynamically lay out N widgets around it in a circle, track their position, and jump to any other widget. I was also able to break down the corel-\u0026gt;illustrator file, into a combination of SVG and PNG images, and skin the UI via CSS stylesheets.\nIts currently an alpha release. I guess I need to really learn how to control the widget painting, to make it faster. Never had to do this much before.\nWhat I came up with… ","date":"Mar 16, 2010","permalink":"https://justinfx.com/2010/03/16/southpark-a-crazy-little-interface-the-taskmonster/","section":"Blogs","summary":"\u003cp\u003eI get to do a lot of interesting applications at SouthPark. This one in particular was the most challenging use of PyQt that I have experienced to date.\u003c/p\u003e\n\u003cp\u003eThe backstory….\u003c/p\u003e\n\u003cp\u003eThe art department wanted a tool to help them track assigned tasks, the progress, and to share media and notes associated with the tasks. Furthermore, they wanted to be able to skin the interface with custom graphics to make it their own.\u003c/p\u003e","title":"SouthPark: A crazy little interface. The TaskMonster."},{"content":"You know when you have all these widgets laid out in your class, and you are hooking up all the connections, and you say “Aw dammit I have to subclass QLabel now just so make it ignore blahEvent”? You end up with all these little widget subclasses, where all they are doing is ignoring an event.\nI noticed I was doing this a few times, in more than one of my classes, and finally got annoyed for the last time. I figured there had to be a simple way of just overloading the method on the normal object when I create an instance. Fortunately python considers everything objects and pretty much anything can be changed. So I did this:\nmyLabel = QLabel() myLabel.mousePressEvent = lambda event: event.ignore() Magic.\nI have also had to make clickable widgets, such as QLabel:\nmyLabel = QLabel() myLabel.mousePressEvent = lambda event: myLabel.emit(SIGNAL(\u0026#34;clicked\u0026#34;)) Or if you had to do more than just a single statement:\nmyLabel = QLabel() def clickedEvent(event): myLabel.emit(SIGNAL(\u0026#34;clicked\u0026#34;)) # do other stuff # do stuff event.accept() myLabel.mousePressEvent = clickedEvent I like this better than piling up subclasses that don’t do much.\n","date":"Mar 10, 2010","permalink":"https://justinfx.com/2010/03/10/pyqt-ignoring-events-on-widgets/","section":"Blogs","summary":"\u003cp\u003eYou know when you have all these widgets laid out in your class, and you are hooking up all the connections, and you say “Aw dammit I have to subclass QLabel now just so make it ignore blahEvent”? You end up with all these little widget subclasses, where all they are doing is ignoring an event.\u003c/p\u003e\n\u003cp\u003eI noticed I was doing this a few times, in more than one of my classes, and finally got annoyed for the last time. I figured there had to be a simple way of just overloading the method on the normal object when I create an instance. Fortunately python considers everything objects and pretty much anything can be changed. So I did this:\u003c/p\u003e","title":"PyQt: Overloading/Ignoring events on widgets"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/flash/","section":"Tags","summary":"","title":"Flash"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/graph/","section":"Tags","summary":"","title":"Graph"},{"content":"I had a project where I was designing a statistics reporting site, to track production stats. I wanted to have really nice graphs that pulled from the database and were somewhat live and interactive. XML/SWF Charts is this awesome flash-based app that lets you embed graphs in your pages which receive their data from XML. There are tons of graph types and ways to customize the look.\nhttp://www.maani.us/xml_charts/index.php\nSo, the thing is… I wanted to use Django for the site. I decided to write a python module that wraps around the API for SWF charts, so that the XML could easily be generated for me after just setting all my parameters. Thought I might post this here for any python fans wanting nice looking graphs in their site.\nReally, this doesn’t just apply to django. You could just call out from anything to python code that will generate your XML for you.\nExample:\nchart = SwfChart() # the data chart.addRow( \u0026#39;Person A\u0026#39;, 1, 10, 5.5 ) chart.addRow( \u0026#39;Person B\u0026#39;, 6, 4.45, 8 ) chart.addColumnLabel( \u0026#39;Day1\u0026#39;, \u0026#39;Day2\u0026#39;, \u0026#39;Day3\u0026#39; ) # Extra graph settings chart.addFilter(\u0026#39;shadow\u0026#39;, \u0026#39;low\u0026#39;, distance=2, angle=45, alpha=35, blurX=5, blurY=5) chart.addFilter(\u0026#39;shadow\u0026#39;, \u0026#39;high\u0026#39;, distance=3, angle=45, alpha=35, blurX=10, blurY=10) chart.addFilter(\u0026#39;bevel\u0026#39;, \u0026#39;bevel1\u0026#39;, strength=10, quality=3, distance=2) chart.setChartBorder(top=1, bottom=2, left=0, right=0, color=\u0026#39;000000\u0026#39;) chart.setChartLabel(color=\u0026#39;000000\u0026#39;, alpha=80, size=8, position=\u0026#39;outside\u0026#39;, hide_zero=True) chart.setChartTransition(type=\u0026#39;scale\u0026#39;, delay=.5, duration=.5, order=\u0026#39;series\u0026#39;) chart.setChartRect(shadow=\u0026#39;high\u0026#39;) chart.setLegend(size=12, alpha=90, fill_alpha=30) chart.setAxisTicks(category_ticks=True, value_ticks=True, minor_count=3) chart.setContextMenu(about=False) # if you have the licensed version chart.setLicense(\u0026#39;license string\u0026#39;) Now at this point, the object can be treated like a string to get the xml, or just call getXML() :\nprint chart print chart.getXML() # same thing xml = str(chart) # or assign the XML string somewhere You can download the swfcharts.py module and use it freely. If you find it helpful, post a comment or shoot me an email.\nDownload swfcharts.py #Pydoc located here for convenience:\nswfcharts python documentation\n","date":"Jan 15, 2010","permalink":"https://justinfx.com/2010/01/15/python-api-for-xmlswf-charts-flash-graphing/","section":"Blogs","summary":"\u003cp\u003eI had a project where I was designing a statistics reporting site, to track production stats. I wanted to have really nice graphs that pulled from the database and were somewhat live and interactive. XML/SWF Charts is this awesome flash-based app that lets you embed graphs in your pages which receive their data from XML. There are tons of graph types and ways to customize the look.\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"http://www.maani.us/xml_charts/index.php\" target=\"_blank\" rel=\"noreferrer\"\u003e\u003cimg class=\"alignnone size-full wp-image-59\" title=\"graphs_example\" src=\"/uploads/2010/01/graphs_example.jpg\" alt=\"\" width=\"754\" height=\"112\" /\u003e\u003c/a\u003e\u003c/p\u003e","title":"Python API for XML/SWF Charts (Flash Graphing)"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/swfchart/","section":"Tags","summary":"","title":"Swfchart"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/xml/swf-charts/","section":"Tags","summary":"","title":"Xml/Swf Charts"},{"content":"I never thought I had known such a real sense of failure until today, when a system diagnostic became intent on showing me just how hard of a failure we will be experiencing together.\nThe hardest system fail ever This is probably the hardest system failure I have ever felt.\nThe system failed so hard, I was actually sent home from work for the day, and the system called my mom on the phone to inform her just how much of a failure this was. They scheduled a Parent-System conference for next week.\n","date":"Jan 12, 2010","permalink":"https://justinfx.com/2010/01/11/failed-hard/","section":"Blogs","summary":"\u003cp\u003eI never thought I had known such a real sense of failure until today, when a system diagnostic became intent on showing me just how hard of a failure we will be experiencing together.\u003c/p\u003e","title":"Failed… hard"},{"content":"","date":null,"permalink":"https://justinfx.com/tags/failure/","section":"Tags","summary":"","title":"Failure"},{"content":" I had received a mailing list email from cmiVFX, where Chris Maynard was challenging the community to write a tool that could convert a nuke camera .chan file to a functional FBX format. This was apparently meant to compliment the new 3d camera tracker in NukeX. So I decided to take on the challenge.\nThe tool started out as a command-line python script that would translate the chan files simple column-style output to fbx. But in testing specifically with Flame, Chris found that the fbx simply would not import all the channels properly. Thus, I was asked to integrate a solution by Georges Nakhle for converting the chan to an .action format, which is native to Flame. So with George’s .action code, Chris’s testing with the scaling in Flame, and the rest of my code, we seemed to have all the bases covered in getting the .chan file into a universal format.\nChris asked if I would wrap the tool into a GUI, to allow easier access to the few options the script provides. Using the cmiVFX.com website as a reference, I threw together a nice looking GUI in PyQt. It was fun because I got to really play around with CSS and skinning in PyQt, which is something I never really had to do before. I learned how much of a pain in the ass Palettes are, and how freaking simple the CSS route makes it to control the look or widgets.\nChris released it today: http://www.fxmogul.com/\nUpdate: This is no longer hosted through cmivfx, and has been posted on github, labeled “AtomSplitter”: https://github.com/justinfx/AtomSplitter Currently there is a version for both OSX and Windows. I have been having some issues packaging the code under Linux, but I just need to really sit down and figure it out. The build is kinda larger than I hoped, but thats what I get for distributing PyQt .chan To FBX GUI (osx) ","date":"Dec 7, 2009","permalink":"https://justinfx.com/2009/12/06/chantofbx-tool-released-through-cmivfx/","section":"Blogs","summary":"\u003cimg class=\"alignnone size-full wp-image-39\" title=\"chan2fbx\" src=\"/uploads/2009/12/chan2fbx.jpg\" alt=\"chan2fbx\" width=\"201\" height=\"104\" /\u003e\n\u003cp\u003eI had received a mailing list email from cmiVFX, where Chris Maynard was challenging the community to write a tool that could convert a nuke camera .chan file to a functional FBX format. This was apparently meant to compliment the new 3d camera tracker in NukeX. So I decided to take on the challenge.\u003c/p\u003e","title":"chanToFbx tool released through cmiVFX"},{"content":"Justin Israel\nVisual Effects Demo Reel 2008\nShot Breakdown: PDF\n","date":null,"permalink":"https://justinfx.com/visual-fx-demo/","section":"Pages","summary":"\u003cp\u003eJustin Israel\u003c/p\u003e\n\u003cp\u003eVisual Effects Demo Reel 2008\u003c/p\u003e\n\u003cp\u003eShot Breakdown:  \u003ca href=\"/public/demo_breakdown.pdf\" target=\"_blank\"\u003e\u003cspan style=\"color: #3366ff;\"\u003ePDF\u003c/span\u003e\u003c/a\u003e\u003c/p\u003e\n\u003cdiv class=\"js-video vimeo\"\u003e\n\t\u003ciframe src=\"https://player.vimeo.com/video/12068065?byline=0\" \n\t        width=\"640\" \n\t        height=\"360\" \n\t        frameborder=\"0\" \n\t        mozallowfullscreen \n\t        allowfullscreen \u003e\n\t\u003c/iframe\u003e\n\u003c/div\u003e","title":"Visual FX Demo"},{"content":"This is something that started back in 2006, when I received an email from one Miriam Israel. This Miriam claimed to be my grandmother, and proceeded to ask about details in my life that were not my details, and not my life. I thought a simple case of mistaken identity was made and informed her briefly that she had the wrong person. And I asked her to please remove me from her address book. Unfortunately, she didn’t seem to understand, and a few more correspondence took place during that year. I had forgotten about it until today, when it resurfaced. When I looked back across all the based mails, I realized it was kinda funny. So here it is.\nI actually do not have the first original mail and my reply. But you will get the idea. She asked me a bunch of stuff, and I replied with something like “Sorry. I’m not your grandson. Wrong person. Please remove me from your address book.”. Also, there were a few times when I just didn’t respond, and instead I bounced the mail so it looked like a wrong address. The following are the rest of the emails, after the first one.\nfrom: Miriam Israel to: justinisrael \u0026lt;justinisrael@gmail.com\u0026gt; date: Fri, Sep 29, 2006 at 2:58 AM Dear Justin Received your email. Why? What is wrong? Why areyu s angry? I WILL NOT ever remove you from my address book – your name is engraved on my heart. AND you will always be related to me and all the family here in South Africa and also to te family in Tampa. Wish you good health, strength and courage and success. May the coming year be wonderful, better than the previous one. Love also from Charlene and all of us here. Love you as always, hug and kisses for Alex. Grandma from: Justin Israel \u0026lt;justinisrael@gmail.com\u0026gt; to: Miriam Israel date: Sun, Oct 1, 2006 at 10:07 AM Miriam, These are not words of anger towards you… the clear fact is, we have no relation. You have me mixed up with someone else, possibly another Justin Israel? I do not have any relations in Africa… and for that matter, any living relatives outside of the U.S.. I appreciate your inquiry as to how ‘Alex’ is doing, but there is no known Alex in my family. We are NOT related, so please remove me from your emails. If you were actually close to the correct Justin Israel, or this ‘Alex’, you might know the person’s telephone number and how to actually reach your loved ones. from: Miriam Israel to: justinisrael \u0026lt;justinisrael@gmail.com\u0026gt; date: Fri, Nov 10, 2006 at 5:04 AM Dear Justin, Jill and Alex I want toknow if Alex has still got jerseys which I made for him. Do any still fit him? What size clothes do you buy for him? 2/3 or 3/4 years? I made him several more but the maid we had stole them plus other things as well. I bought more wool today to make him something, so that he will have it,from me with love, before the cold hits you. How is he doing? Photographs please! My arthritis is very bad. My neck, back, hands and legs are affected, but I still keep on doing things. It is very hot now with quite a lot of rain. Errol and Hadassa ae going to Connecticut for 10 days for rabbi’s conference for Aish Hatorah. She will post the jersey to you P.G. Ari finished his last end of the year exams. He is exhausted – he has worked very hard. Lisa is still writing final matric exams and should be finished in a week. It is almost shabbos so will end with good wishes and love to all. It would be nice to have an email from you – with answers to my questions. Please ask Marty to be in touch with me. Is Mommy well? As always, with warm love, Grandma. How are you Justin, and what is happening?. from: Miriam Israel to: justinisrael \u0026lt;justinisrael@gmail.com\u0026gt; date: Tue, Dec 5, 2006 at 9:43 AM Dear Justin, Just got your email, only one. I did not receive theone with Alex’s size and measurement. Has the package arrived yet? When it does, please let meknow how the jersey fits Alex. How are you all? Let me know what Alex does, says, does at school. Do you ever take him to shul? If not then shame on you. Did I tellyou four months ago that Leanne had twins, boy and girl at 26 weeks. They wereminute. Had to be in ICU for three months. They have beenhome now for one month. Still verysmall but puttingon weight and crying crying crying. Leanne does not get any sleep as she is busy with them all day. She does not have a maid. Suzanne and Elise help her when they can. They are both working. Suzanne is leaving her teaching post this month. She will teach privately at home, needs the money. They are called Binjamin (in Hebrew) and Batya after Leanne’s father. Hadassa and Errol leave N.York tomorrow and will be home P.G. on Thursday. Pity you could not see each other! Please keep in touch. Hope you enjoyed your birthday. Wish you many more happy, healthy and successful years to come. With much love and hugs for Alex and you both. Grandma. from: Justin Israel \u0026lt;justinisrael@gmail.com\u0026gt; to: Miriam Israel date: Wed, Dec 6, 2006 at 9:12 AM Oh dearest Grandma, It pain us so much to say, that poor little Alex has lost both of his legs. His size is now only 3 feet tall, and he must be pulled in a small radio flyer wagon that we had found at a garage sale. We are looking for the money to buy him robotic legs, similar to the movie Robocop, but this procedure is expensive, and it does not come with the gun holster, like in the movie. Please mourn this tragedy with us. Not your relative, Justin from: Miriam Israel to: justinisrael \u0026lt;justinisrael@gmail.com\u0026gt; date: Mon, Dec 25, 2006 at 7:12 AM Did you send this? from: Justin Israel \u0026lt;justinisrael@gmail.com\u0026gt; to: Miriam Israel date: Mon, Dec 25, 2006 at 5:25 PM Ah yes. Yes I did send this. Did you finally receive it? Are you slightly confused? Well maybe if you would listen to people instead of rambling on and living in a fantasy, you might have realized much earlier that I am not related to you, and that you have an incorrect email address. I decided, once you persisted to email me, that I would get your attention once and for all, and make you understand that you are not my relative. Glad you finally figured this out. Update: #My co-worker, could not let this situation go in her mind, and has hunted down the real Justin Israel: http://www.facebook.com/justinisrael2\nI totally beat him to getting the first facebook perma-link for our name.\n","date":"Nov 18, 2009","permalink":"https://justinfx.com/2009/11/18/my-fake-grandmother/","section":"Blogs","summary":"\u003cp\u003eThis is something that started back in 2006, when I received an email from one Miriam Israel. This Miriam claimed to be my grandmother, and proceeded to ask about details in my life that were not my details, and not my life. I thought a simple case of mistaken identity was made and informed her briefly that she had the wrong person. And I asked her to please remove me from her address book. Unfortunately, she didn’t seem to understand, and a few more correspondence took place during that year. I had forgotten about it until today, when it resurfaced. When I looked back across all the based mails, I realized it was kinda funny. So here it is.\u003c/p\u003e","title":"My fake grandmother…"},{"content":" Justin Israel\njustinisrael@gmail.com\nJustin is a California-born and New Zealand based software developer / pipeline engineer who graduated from Cal State Long Beach (CSULB) with a B.A. degree in Film and Video production. He started his Visual FX career at Stan Winston Digital as a digital artist and then developed strong pipeline/programming skills at Sony Pictures Imageworks while working on Spiderman 3, I Am Legend, and The Watchmen. He has also spent 4+ years as a Senior Pipeline Developer on the award winning television series South Park, designing tools for Maya, Nuke, and general pipeline. And just under a year as a compositor at the boutique studio, Custom Film Effects.\nCurrently Justin works as a Staff Engineer at Wētā FX, in New Zealand, where he has grown from Pipeline Engineer to Senior Software Engineer to Staff Engineer over more than a decade. His focus has shifted in recent years from core pipeline development to building AI platform infrastructure, including MCP gateways, LLM gateways, and coding agent tooling. His passion for live-action visual effects and film leads Justin to gain fundamental knowledge in all facets possible. He is experienced in Python, Go, C++, Cython, and pipeline development, as well as paint, rotoscoping, and compositing. His work includes feature films such as Commander \u0026amp; Chief, The Compass, Bride Wars, Tropic Thunder, I Am Legend, Spiderman 3, The Watchmen, Fantastic Four and more.\nJustin has worked as both an artist and a visual fx supervisor on films and television, as well as directing and practical lighting experience, in addition to his current focus in studio pipeline development, and is constantly looking for new challenges and opportunities to learn.\nCheck out IMDB for a list of past projects.\n","date":null,"permalink":"https://justinfx.com/about/","section":"Pages","summary":"\u003cimg src=\"/uploads/2026/10/justin-wide.jpg\" alt=\"Justin Israel\" width=\"900\" height=\"438\" style=\"width: 300px; height: auto;\" /\u003e\n\u003cp\u003eJustin Israel\u003c/p\u003e\n\u003cp\u003e\u003cspan style=\"color: #ff6600;\"\u003e\u003ca href='mailto:jus%74ini%73rael@gmail%2Ec%6Fm'\u003e\u003ca href=\"mailto:justinisrael@gmail.com\"\u003ejustinisrael@gmail.com\u003c/a\u003e\u003c/a\u003e\u003c/span\u003e\u003c/p\u003e\n\u003cp\u003eJustin is a California-born and New Zealand based software developer / pipeline engineer who graduated from \u003ca href=\"https://www.csulb.edu/\" target=\"_blank\" rel=\"noreferrer\"\u003eCal State Long Beach\u003c/a\u003e (CSULB) with a B.A. degree in Film and Video production. He started his Visual FX career at Stan Winston Digital as a digital artist and then developed strong pipeline/programming skills at \u003ca href=\"https://www.imageworks.com/\" target=\"_blank\" rel=\"noreferrer\"\u003eSony Pictures Imageworks\u003c/a\u003e while working on Spiderman 3, I Am Legend, and The Watchmen. He has also spent 4+ years as a Senior Pipeline Developer on the award winning television series South Park, designing tools for Maya, Nuke, and general pipeline. And just under a year as a compositor at the boutique studio, \u003ca href=\"https://www.imdb.com/search/title/?companies=co0067412\" target=\"_blank\" rel=\"noreferrer\"\u003eCustom Film Effects\u003c/a\u003e.\u003c/p\u003e","title":"About"}]