Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Badges

First AnniversaryName Dropper10 CommentsFirst Comment

jfriedman ✭✭

About

Username
jfriedman
Joined
Visits
2,099
Last Active
Roles
Fabric for Houdini
Points
53
Posts
81
Badges
4
  • Clang Format for Sublime text for KL

    So there's a really smart C++ code formatter in Clang. For a demo, see:

    I was about to go and try to make all the formatting on all our KL code consistent, so I thought perhaps my time would be better spent trying to make the clang-format work for me. The result is- I've modified a sublime plugin in order to do this. This is basically a hacked version of another Sublime text plugin, Ross Hemsley's SublimeClangFormat.

    It's here if you're interested: https://github.com/jonahf/SublimeClangFormatKL

    For myself, I decided to go for broke and enabled it to run every time I press save. I also turn on a bunch of formatting features that are a pain to write but nice to read, like lining up all consecutive assignments, putting spaces in parens before and after arguments, and I have to say I like it a lot. I also decided on 100 character columns, because the names of things in the KL library are a little verbose, but of course feel free to change all this yourself.

    The configuration is quite similar to what's specified in the KL style guide, which isn't overly specific about finer points of how to break arguments on lines or anything like that. Anyway, here's an example for the results from LittleDraw, only very slightly embellished:

    /// \dfgPresetOmit
    inline LittleDrawAxis.createLines( io Ref<Lines> lines, io Ref<ColorAttribute> vc, Vec3 pos ) {
      Vec3 origin = this.payload.multiplyVector3( Vec3() );
      Vec3 x      = this.payload.multiplyVector3( Vec3( 1, 0, 0 ) );
      Vec3 y      = this.payload.multiplyVector3( Vec3( 0, 1, 0 ) );
      Vec3 z      = this.payload.multiplyVector3( Vec3( 0, 0, 1 ) );
      switch( this.mode ) {
      case LD_MODE_A_AXIS_TRAIL:
        LittleDraw_addColoredLine( pos, origin, this.color * 0.50, this.color, lines, vc );
      case LD_MODE_A_AXIS:
        LittleDraw_addColoredLine( origin, x, this.color, Color( 1.0, 0.0, 0.0 ), lines, vc );
        LittleDraw_addColoredLine( origin, y, this.color, Color( 0.0, 1.0, 0.0 ), lines, vc );
        LittleDraw_addColoredLine( origin, z, this.color, Color( 0.0, 0.0, 1.0 ), lines, vc );
        break;
      }
    }
    
    //
    // Create Geometry
    //
    
    function LitteDraw_createGeometry( LittleDraw jobs[], Geometry geo, io Points debugPoints,
                                       io Lines debugLines ) {
      Ref<Lines> lines           = debugLines;                             // a comment 
      Ref<Points> points         = debugPoints;                            // another comment
      Ref<Vec3Attribute> posAttr = geo.getAttributes().positionsAttribute; // look comments line up!
      Ref<ColorAttribute> linesVCAttr = lines.getAttributes().getOrCreateColorAttribute( "vertexColors" );
      Ref<ColorAttribute> pntsVCAttr = points.getAttributes().getOrCreateColorAttribute( "vertexColors" );
      Ref<ScalarAttribute> pointsSizesAttr = points.getOrCreateSizesAttribute();
    
      for( Size i = 0; i < jobs.size(); i++ ) {
        Ref<LittleDraw> job = jobs[i];
    
        while( job != null ) {
          switch( job.type() ) {
          // switched out by type to hopefully give the inliner a chance
    
          case LittleDrawVector:
            Ref<LittleDrawVector>( job ).createLines( lines, linesVCAttr, posAttr.values[i] );
            Ref<LittleDrawVector>( job ).createPoints( points, pntsVCAttr, pointsSizesAttr,
                                                       posAttr.values[i] );
            break;
          }
        }
      }
    }
    
    //
    // HELPERS
    //
    
    /// \internal
    inline LittleDraw_addColoredLine( Vec3 pos0, Vec3 pos1, Color color0, Color color1,
                                      io Ref<Lines> lines, io Ref<ColorAttribute> vc ) {
      lines.addLine( pos0, pos1 );
      vc.values[vc.size() - 2] = color0;
      vc.values[vc.size() - 1] = color1;
    }
    

    In addition to having all those annoying to write but nice to read formatting features, it's really nice when renaming every occurrence of something, like a method name for example. Normally that wrecks any kind of even marginally fancy formatting, but with auto formatting everything just falls in line.

    This is implemented as just some modifications on that existing Sublime Text plugin. Clang format thinks it's dealing with C++, so a few modifications were necessary to make it not break things. For example, breaking string literals in the C++ way to multi line ones doesn't work, so that had to be disabled. Also certain keywords confuse it about how they should be formatted, and that's been fixed as well in the python code.

    Hope others find this useful as well!

  • Morris on a moving surface (and great work!)

    The animation produced by the rig is very compelling and would be very time consuming to do manually, and then seeing how the solver responds seamlessly to scaled segments and differently segmented legs is pretty amazing. The integration with blocks is really interesting too.

    I haven't dug in yet, but I'm imagining a use for the block presets might be to modify the solve so that the multipede can crawl over a character who is also moving (perhaps in response to having a giant centipede crawling on him). How might that work- perhaps post-solve, you'd store all the locations on the mesh and offsets from it, and then pre-solve in the next iteration you'd update those to the new locations so that this is what the solver sees as the starting position?

  • LittleDraw: Drawing from inside blocks

    Hello All,

    I've been getting my hands dirty with blocks and they're clearly a huge step forward for Canvas. I've also been teaching others how to use them and they're quite a natural way of doing things. There is something I've felt I've been missing, which is being able to do debug drawing from inside the blocks. So I've undertaken a little project (less than a day so far) to try to correct this. I say it's less than a day not to brag, but to say that I'm not married to anything here and it's submitted as much as an example of a possible workflow/technique as it is as an actual implementation.

    The result is here, a system called LittleDraw: https://github.com/jonahf/LittleDraw

    What we have here is a graph with a modified copy of the "deformInPlace" compound. Inside the compound are some nodes getting the cross product of the normal and another such vector, (not a particularly interesting example), but then ordering those vectors drawn from inside the block.

    Inside the block, the user sees a new out port of type, LittleDrawJob. A little draw job is a way of ordering something small, like a single vector or color, to be drawn. Users can just wire these up ad-hoc as needed, to draw the intermediate data in their processes which ICE has shown us is invaluable in debugging and learning.

    LittleDrawJob types:

    LittleDrawVector: This draws a vector. You have the option of drawing it normalized to a unit vector or not.

    LittleDrawPoints: This also draws Vec3 data, but as positions. These are drawn as points in space, optionally with trails pointing back to the context point (the point the block was working on).

    LittleDrawColor: Ther are three nodes here that can draw either colors, vectors or scalars as colored points on the context point. The vectors can be "normalized" meaning they are remapped from [-1, 1] to [0, 1] (better to see things like normals). The scalars have an option for showing negative values inverted.

    LittleDrawAxes: Draws axes from either XFOs or Mat44s. Can be drawn with trails to the context point (like ICE).

    Soon: LittleDrawString, to draw text (thanks for the code @malbrecht). This way you can get numeric display of your intermediate data.

    Other little features of LittleDrawJobs:

    Each LittleDrawJob has a "other" port where you can plug in another LittleDrawJob. These can also be daisy chained.

    Each LittleDrawJob has a color port as well, which can be connected to some other logic to get more information into the drawing. For example, draw a vector, with its color controlled by some other piece of data.

    Making your own types of LittleDrawJobs:

    This is pretty straightfoward, the interface for these is really simple. Other extensions can add new types of LittleDrawJobs.

    Making a block node able to do LittleDrawJobs:

    This is pretty simple. If your block node is operating on an array of some size, you'll want an array of LittleDrawJobs of the same size. If nothing is plugged into the block's port, it'll be an array of nulls, which should be rather small. After that there are some helper functions to create lines and points (the only two types created right now) with vertex colors and draw them.

    Performance:

    The overhead on this when not drawing is pretty low, it's just filling an array with nulls, and then later iterating that to generate (no) geometry. It should be further possible to optimize this so that if the array is filled with only nulls, it can know that before looping through it again. I haven't timed anything carefully but I don't think it's very expensive to have this around when it's drawing nothing. Also you could have a switch on the outside of the block that disables them entirely and never pulls that port, never fills any array, so if you had that the overhead of having this without drawing should be basically nothing and conceivably something the compiler could even delete.

    When drawing it's definitely not optimized, and there is a lot of room for improvement. Right now it just loops through all the jobs each one adds their lines to the Lines and Points objects one at a time, but it seems to be just fine for debug drawing, and there's definitely room to optimize it later. It also feels faster than ICE drawing, just as a point of reference. It draws all the lines to one Lines object, so the drawing doesn't bog down the viewport with huge numbers of tiny drawings, like drawing axes instances sometimes does.

    Inline drawing / RTR2 / What may come

    The drawing itself is a pretty insignificant part of this, since this system creates a Lines and Points object to draw and then gives them to standard drawing functions. The other drawing systems, if they can draw those types, should be able to use this system as well.

    What I want out of this:

    I would like to have something in all the applicable block presets that does this job. I'm not married to this particular system, this is more submitted for inspiration and for anyone who might find it useful. (Not that I'd rule out this system being used in the built in Fabric Engine nodes).

    I would, however, argue that this job is important and something should do it. Being able to quickly and easily draw the intermediate stages of calculations that might go on in these blocks is very important in my opinion.

    Blocks are amazing:

    Are blocks amazing or what? Being able to control not just the contents of them but the context in which they operate in is so ridiculously powerful that this kind of thing, which was a very basic feature in ICE, isn't even hard to add. I think blocks are going to be huge.

  • Re: Fabric at Siggraph videos

    Great to see these go online so fast. If anyone has any questions, I'm around and watching this thread.

  • Re: Fabric 2.3 and Blocks is now available

    Wow, what a release! Great examples too. I can't wait to really dig in and make some blocky things.

    Hope to see a lot of you at Siggraph!