Jump to content


  • Content count

  • Donations

    0.00 CAD 
  • Joined

  • Last visited

  • Days Won


Everything posted by animatrix

  1. Pragmatic VEX: Volume 1 [4K] [H18.5]

    There is a very practical use of the limit surface to figure out where a point is on the subdivision limit surface. Imagine a character head like the one we were using, and you add a lot of detail to it, just like what we did before using adaptive subdivision. That sounds all good in action, but what we are missing is the future projection of the same geometry, by additional subdivision, either as a post operation before exporting out the geometry, or as a render time operation. In any case, this will result in the areas where there is added detail, to be flatter than before, even though it's not the case without adaptive subdivision. Because if you recall, we were using Catmull-Clark subdivision algorithm, which will keep the original geometry nice and smooth. But in other cases where you might have additional detail using algorithms such as Bricker, it might result in the areas where there is added detail to be flatter than before. But we don't necessarily want this. What we want is to create detail without disturbing the future subdivided shape of the geometry. So how can we do this? Evaluating attributes at the subdivision limit surface gives us a way out.
  2. After more than 5 months of unimaginable amount of work, I am proud to release my first in-depth Houdini course on VEX More details in the video description and the website. Active Patreon members will receive additional discounts proportional to their lifetime support (25% of their lifetime support). Message me on Patreon for your discount coupon. Enjoy! Table of Contents 01 - Introduction [Point Clouds] 02 - Introduction [pcopen() vs pcfind() vs nearpoints()] 03 - Introduction 04 - Implementation 05 - pcfilter() Implementation for pcfind() 06 - pgfind() 07 - pcfind_radius() 08 - Excluding the Current Point & Ad-Hoc Groups 09 - Finding Min & Max Neighbour Points [Unique Pair Matching] 10 - Concept 11 - Implementation [Camera Based Occlusion with Variable Pscale] 12 - Concept 13 - Implementation [Uniform Point Distribution Over Polygonal Surfaces [Point Relaxation]] 14 - Concept 15 - Implementation 16 - Decoupling Operators [Convolution Kernels] 17 - Introduction 18 - Border Handling [Connectivity & k-Depth Point Neighbours Using Edges] 19 - Introduction 20 - Concept 21 - Implementation [Connectivity & k-Depth Point Neighbours Using Primitives] 22 - Concept 23 - Implementation [Extending k-Depth Point Neighbours Using Edges] 24 - Introduction 25 - Concept 26 - Implementation [Extending k-Depth Point Neighbours Using Primitives] 27 - Concept 28 - Implementation [smoothstep() [Cubic Hermite Interpolation]] 29 - Concept 30 - Implementation [Shaping Functions] 31 - Introduction 32 - Implementation 33 - Blurring Attributes [Sharpening Attributes Using Unsharp Mask] 34 - Concept 35 - Implementation [Generalizing the Kernel Code to Handle All Attribute Types] 36 - Concept 37 - Implementation [Attribute Gradient] 38 - Introduction 39 - Concept 40 - Implementation [Gradient Ascent & Descent] 41 - Planar Geometry - Introduction 42 - Planar Geometry - Concept 43 - Planar Geometry - Implementation 44 - 3D Geometry [Contour Lines] 45 - Introduction 46 - Concept 47 - Implementation 48 - Heightfields [Geometric Advection - Orthogonalization & Flowlines] 49 - Introduction 50 - Concept 51 - Implementation [Clustering & Quadtrees] 52 - Concept 53 - Implementation [Adaptive Subdivision] 54 - Introduction 55 - Implementation 56 - Hashing [Adaptive Subdivision] 57 - Improving OpenSubdiv Catmull-Clark Subdivision Surfaces Algorithm 58 - Half-Edges [Adaptive Subdivision] [Aggressive Performance Optimizations] 59 - Eliminating Groups 60 - Custom Fusing In VEX 61 - Recreating Proximity Structures In VEX 62 - Get Unshared Edges In VEX 63 - Final Optimizations [Limit Surface Sampling] 64 - Introduction 65 - OpenSubdiv Patches 66 - Moving Points to the Subdivision Limit Surface 67 - Scattering Points on the Subdivision Limit Surface 68 - Generating a Point Cloud on the Subdivision Limit Surface 69 - Pre-Generating a Point Cloud on the Subdivision Limit Surface 70 - Creating Isolines on the Subdivision Limit Surface [Adaptive Subdivision] 71 - Computing Surface Normals from the Subdivision Limit Surface [Custom Subdivision Surfaces] [Splitting Edges [Edge Divide]] 72 - Concept 73 - Converting Edges to Primitives 74 - Creating New Edge Points [Rebuilding Polygons] 75 - Concept 76 - Implementation 77 - Preserving & Interpolating Attributes 78 - Multithreading by Connectivity 79 - C++ vs VEX 80 - Preserving Groups 81 - Final Optimizations [Implementing Bilinear Subdivision] 82 - Introduction 83 - Concept 84 - Modeling Test Geometry 85 - Starting from Edge Divide 86 - Creating New Face Points 87 - Creating New Edge Points [Creating New Closed Polygons] 88 - Concept 89 - Implementation [Creating New Open Polygons] 90 - Concept 91 - Implementation 92 - Preserving Primitive Groups & Interpolating Primitive Attributes [Preserving Vertex Groups & Interpolating Vertex Attributes for Closed Polygons] 93 - Concept 94 - Implementation 95 - Preserving Vertex Groups & Interpolating Vertex Attributes for Open Polygons 96 - Implementing Iterations 97 - Preserving Literal Groups 98 - Creating Neighbour Primitives 99 - Final Changes 100 - Testing On Complex Geometry [Implementing Catmull-Clark Subdivision] 101 - Introduction [Closed Surfaces] 102 - Rules [Gathering Edge & Face Points] 103 - Concept 104 - Implementation [Computing Weights for New Edge Points] 105 - Concept 106 - Implementation [Computing Weights for Original Points] 107 - Concept 108 - Implementation [Attribute Interpolation] 109 - Concept 110 - Implementation [Boundary Interpolation Rules for New Edge Points] 111 - Concept 112 - Implementation [Boundary Interpolation Rules for Original Points] 113 - Concept 114 - Implementation 115 - Open Surfaces - Handling Corner Points 116 - Handling Non-Manifold Topology [Open Polygons] [Computing Weights for Original Points] 117 - Reverse Engineering OpenSubdiv 118 - Implementation [Computing Weights for New Edge Points] 119 - Reverse Engineering OpenSubdiv 120 - Implementation 121 - Handling Open Polygonal Curves [Handling Mixed Topology] 122 - Full Geometry 123 - Sub-Geometry 124 - Testing On Complex Geometry [Performance] 125 - Profiling [Grouping Boundary Edges from Primitive Group] 126 - Concept 127 - Implementation 128 - VEX vs C++ [Caustics] 129 - Introduction 130 - Sea Caustics 131 - Pool Caustics 132 - Conclusion
  3. Pragmatic VEX: Volume 1 [4K] [H18.5]

    To celebrate the yearly anniversary, I decided to share the Limit Surface Sampling chapter from the course (5 separate videos). AFAIK this topic has never been covered by other tutorials, so I hope it proves to be useful for your work! Enjoy! To generate interpolating surfaces for other subdivision schemes we need a method of determining the position and the normal at a set of points on the limit surface. Because the surface is the result of repeated application of a subdivision step, we can analyze the behavior of a small neighborhood of points as they converge to the limit surface in order to determine the surface properties at the point of convergence.
  4. Houdini 19 Wishlist

    Btw for people who are interested I simplified the locked viewport indicator code that I posted earlier: class ViewportOutlineWidget(QtWidgets.QWidget): thickness = 0 def __init__(self, thicknessValue=2): QtWidgets.QWidget.__init__(self, hou.qt.mainWindow(), QtGui.Qt.WindowStaysOnTopHint) self.thickness = thicknessValue self.setParent(hou.qt.floatingPanelWindow(None), QtGui.Qt.Window) self.update() p = self.palette() p.setColor(QtGui.QPalette.Window, QtGui.Qt.red) self.setPalette(p) def update(self): viewport = getSessionVariable("viewportWidget") s = viewport.size() p = viewport.mapToGlobal(QtCore.QPoint(0, 0)) w = s.width() h = s.height() self.setGeometry(p.x(), p.y(), w, h) all = QtGui.QRegion(0, 0, w, h) inside = QtGui.QRegion(self.thickness, self.thickness, w - 2 * self.thickness, h - 2 * self.thickness) self.setMask(all.subtracted(inside)) So instead of using 4 lines, I am just creating a mask to hollow out the inside of the rectangle, which is much easier to handle.
  5. Simple problem with vex, attribute array?

    Hi Ben, Your code is fine. It's just that the point numbers returned by addpoint are not guaranteed to be the final point numbers: https://www.sidefx.com/docs/houdini/vex/functions/addpoint.html Returns A point number for the created point, or -1 if the point could not be created. You can use the return value with setpointattrib to set attributes on the new point, however it may not be the final number of the point.
  6. Blue Text Under Node

    Hi, It's called Descriptive Parm:
  7. Pragmatic VEX: Volume 1 [4K] [H18.5]

    Celebrating 1 year anniversary of Pragmatic VEX: Volume 1! Since its inception it has been a huge success among the high end VFX studios and artists alike. And for that I am hugely grateful! Therefore it will be on a discounted sale for a week until August 20 12 PM PST. Enjoy!
  8. Blender function in VEX (snap)

    Hi, VEX has a lot of sample functions for these, for example sample_circle_uniform: https://www.sidefx.com/docs/houdini/vex/functions/sample_circle_uniform.html So you can do something like this in a Detail Wrangle: int count = chi("count"); for ( int i = 0; i < count; ++i ) { float u = float ( i ) / count; vector2 uv = set ( u, 1 ); vector2 p = sample_circle_uniform ( uv ); vector pnew = set ( p.x, 0, p.y ); addpoint ( 0, pnew ); }
  9. Random Seed Question [SOLVED]

    Hi, It's pseudo random, so the result will be completely different regardless of the size of the difference between the seeds. If you want the randomness to be relative to the seed value changes, you can use noise instead: https://www.sidefx.com/docs/houdini/expressions/noise.html
  10. Hi, When you create polylines, you can check if the current point number is greater than the target point number, or the opposite to avoid duplicates: if ( @ptnum > targetpt ) addprim()
  11. random sineblip wave help

    There are many ways, but the easiest is to sample the resulting curve using a float parameter like this: primuv("../attribwrangle1/", 0, "P", 1, ch("pos"), 0) This would be the expression you use in your parameter. Then you can control where to sample using another float parameter (normalized) called pos for example. This could be the current time also if you want, or you can animate the curve while sampling the same location on the curve.
  12. random sineblip wave help

    Hi, You can write something like this: float radius = ch("radius"); float amp = ch("amplitude"); float seed = ch("seed"); int count = chi("count"); for ( int i = 0; i < count; ++i ) { float r = rand ( i + 34.13 + seed ); vector p = primuv ( 0, "P", 0, r ); float d = distance ( p, @P ); float d2 = fit ( d, 0, radius, 0, PI ); float y = amp + sin ( d2 + 0.5 * PI ) * amp; if ( d < radius ) @P.y += y; }
  13. Interrupt SOP Cooking with time limit (Python)

    Hi, Since PolyExpand2d is compileable, you can implement it as a Python wrapper using node verbs with your time out/retry logic: https://www.sidefx.com/docs/houdini/model/verbs.html
  14. Hi, You can use pwd and path functions: paneTabObj = hou.ui.paneTabUnderCursor() print paneTabObj.pwd().path()
  15. Pragmatic VEX: Volume 1 [4K] [H18.5]

    Pragmatic VEX is listed as part of the official VEX learning path! Thanks SideFX! https://www.sidefx.com/learn/vex
  16. Hi, You can capture point neighbours and weights inside a For Loop network using Point Deform (Capture), and then use another Point Deform SOP to deform afterwards. So the capturing is done without time dependency which takes longer to cook while the deformation happens after, which will run much faster.
  17. Paste node downstream

    Hi, You can script something like this but you have to make sure you cover all cases properly if you want it to work well. For example what if you copy nodes that have multiple parent nodes as a whole, etc? You can handle Ctrl+V action using this API: https://www.sidefx.com/docs/houdini/hom/network.html Then you could do things like if there is no selection, behave as is, otherwise use your custom logic, etc. I use the same API to create a context sensitive rule based hotkey system bound to the network editor. I talk about it in detail here if you are interested:
  18. Houdini 19 Wishlist

    It's something like this: class SimpleWidget(QtWidgets.QWidget): def __init__(self, parent, x, y, w, h): QtWidgets.QWidget.__init__(self, parent, QtGui.Qt.WindowStaysOnTopHint) self.initialize(x, y, w, h) def initialize(self, x, y, w, h): self.setGeometry(x, y, w, h) self.setMask(QtGui.QRegion(0, 0, w, h)) p = self.palette() p.setColor(QtGui.QPalette.Window, QtGui.Qt.red) self.setPalette(p) def drawViewportOutline(thickness): if hasattr(hou.session, "viewportOutlineWindows"): for w in hou.session.viewportOutlineWindows: w.close() hou.session.viewportOutlineWindows = [] p = hou.session.overlayviewpos s = hou.session.overlayviewsize w = s.width() - thickness h = s.height() - thickness outlineWindows = [] w1 = SimpleWidget(hou.ui.mainQtWindow(), p.x(), p.y(), thickness, h) w1.setParent(hou.qt.floatingPanelWindow(None), QtGui.Qt.Window) outlineWindows.append(w1) w1.show() w2 = SimpleWidget(hou.ui.mainQtWindow(), p.x(), p.y(), w, thickness) w2.setParent(hou.qt.floatingPanelWindow(None), QtGui.Qt.Window) outlineWindows.append(w2) w2.show() w3 = SimpleWidget(hou.ui.mainQtWindow(), p.x() + w, p.y(), thickness, h) w3.setParent(hou.qt.floatingPanelWindow(None), QtGui.Qt.Window) outlineWindows.append(w3) w3.show() w4 = SimpleWidget(hou.ui.mainQtWindow(), p.x(), p.y() + h, w, thickness) w4.setParent(hou.qt.floatingPanelWindow(None), QtGui.Qt.Window) outlineWindows.append(w4) w4.show() hou.session.viewportOutlineWindows = outlineWindows def drawViewportOutline(): # Draw red outline if viewport is camera-locked sceneviewer = hou.ui.paneTabOfType(hou.paneTabType.SceneViewer) currentViewport = sceneviewer.curViewport() if hasattr(hou.session, "viewportOutlineWindows"): if currentViewport.isCameraLockedToView() and currentViewport.camera(): if len(hou.session.viewportOutlineWindows) == 0: drawViewportOutline(2) else: if len(hou.session.viewportOutlineWindows) > 0: for w in hou.session.viewportOutlineWindows: w.close() hou.session.viewportOutlineWindows = [] hou.ui.addEventLoopCallback(drawViewportOutline) The callback function is described here: https://www.sidefx.com/docs/houdini/hom/hou/ui.html Register a Python callback to be called whenever Houdini’s event loop is idle. This callback is called approximately every 50ms, unless Houdini is busy processing events. Basically you can do anything in this function and that means if you can query if the viewport is set to a camera and it's locked then you can toggle the viewport outline.
  19. Pragmatic VEX: Volume 1 [4K] [H18.5]

    Some feedback from Alexander Vasilyev (Technical Artist @ Ubisoft) on Artstation https://www.artstation.com/alexandervasilyev/blog/erN7/gradient-descent-ascent-and-contour
  20. Curl Noise Control

    Hi, I didn't check his method but maybe he is using contour lines? You can do this sort of effect very easily with this approach and can make it even more complex if you incorporate noise patterns, etc. Once you have these curves you can copy points or objects if you want, etc or just render them as curves like below:
  21. attribtype() - Distinguish Float from Vector

    Hi, To filter it further you have to use attribsize(): https://www.sidefx.com/docs/houdini/vex/functions/attribsize.html Returns The size of an attribute’s type. For a vector type, this is the number of components. For an integer, float, or string, this returns 1. For an array attribute, this returns the size of the tuples in the array. The tuple size is controlled by the Size parameter on the Attribute Create node. The best way to copy attributes is by using the Attribute Copy SOP, it's much faster also.
  22. Houdini 19 Wishlist

    Hi, It's not actually modifying the Houdini interface, it's a hack I just create 4 lines in Qt that outline the Houdini viewport. Qt support in Houdini is pretty limited so you can't just do things like this: viewport.qtWidget().bounds() You need to go through all available widgets in the entire app and filter by type, etc like this: https://www.sidefx.com/forum/topic/70782/?page=1#post-301055 I didn't post it publicly only on Patreon and the previous Houdini beta. I can post this part here but it might require some tweaks because it involves using a scene callback to check if the camera is locked, etc.
  23. Hi, nearpoints is a wrapper function which is calling pcfind so it's the simplest way AFAIK.
  24. One-liner for point(0,"P",8).z in point wrangle

    Hi, You can do it like this: @P.z = point(0,"P",8).z;
  25. Ray marching in COPs

    Very cool Konstantin!