{"id":1046,"date":"2024-02-29T15:06:34","date_gmt":"2024-02-29T23:06:34","guid":{"rendered":"https:\/\/www.toadstorm.com\/blog\/?p=1046"},"modified":"2024-04-16T09:19:46","modified_gmt":"2024-04-16T16:19:46","slug":"dops-are-not-sops","status":"publish","type":"post","link":"https:\/\/www.toadstorm.com\/blog\/?p=1046","title":{"rendered":"DOPs are not SOPs"},"content":{"rendered":"\n<p>I wanted to make a post about a really common misconception regarding Houdini&#8217;s geometry context (SOPs) versus its dynamics context (DOPs). Houdini&#8217;s <a rel=\"noreferrer noopener\" href=\"https:\/\/www.sidefx.com\/docs\/houdini\/dyno\/top10_basics.html\" data-type=\"URL\" data-id=\"https:\/\/www.sidefx.com\/docs\/houdini\/dyno\/top10_basics.html\" target=\"_blank\">documentation<\/a> does explain a bit of basic information about DOPs, but not necessarily in the most readable way for Houdini newcomers who are first introduced to the software via the SOPs context.<\/p>\n\n\n\n<p>Anyways, here&#8217;s the core question that&#8217;s always asked: <strong>&#8220;why isn&#8217;t [some animated property of my object] updating during this simulation?&#8221;<\/strong><\/p>\n\n\n\n<p>To understand why, we need to step back a bit to talk about the core difference between SOPs and DOPs. There are a lot of differences that are mostly too complex to talk about here in terms of data and objects and subdata and relationships and the other things that will make your head explode, but the most fundamental thing to understand is that SOPs are solved in a <strong>time-independent<\/strong> manner, while DOPs are <strong>time-dependent<\/strong>. What happens in a SOP network on frame 1 absolutely not does matter as far as frame 2 is concerned; you could cook every single frame on different machines in any order and you will always get the same result. With simulations, though, the result of frame 2 depends very much on what happened in frame 1: sourcing new objects, integrating forces, reaping particles, etc.<\/p>\n\n\n\n<p>This means that in DOPs, by default, all you&#8217;re doing is setting the <strong>initial conditions<\/strong> of the simulation from SOPs. Once you make the handoff from SOPs to DOPs, the solver takes over and runs independently of anything that might be happening in the SOPs timeline.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">A simple visual example<\/h2>\n\n\n\n<p>Here&#8217;s a really simple example: a POP simulation. I&#8217;m not emitting anything; just starting from a grid of points and using them as the initial geometry of the simulation. The grid of points has an animated color (<code>Cd<\/code>) attribute, driven by a noise function. I&#8217;ve copied spheres to the points for better visibility. Here&#8217;s what the animation looks like in SOPs:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/sop_color_anim.gif\" alt=\"\"\/><figcaption class=\"wp-element-caption\">The color animating in SOPs, before the simulation.<\/figcaption><\/figure>\n\n\n\n<p>Now let&#8217;s use this SOP as the <strong>Initial Geometry<\/strong> (think about that parameter name for a second!) for a POP Object. The DOP network in this case is minimal: a POP Object wired to a POP Solver, ending in an Output. The SOP with the color animation is assigned as the Initial Geometry.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"582\" src=\"https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-1024x582.png\" alt=\"\" class=\"wp-image-1048\" srcset=\"https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-1024x582.png 1024w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-300x170.png 300w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-768x436.png 768w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image.png 1060w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">The DOP network using the above animated geometry as the Initial Geometry.<\/figcaption><\/figure>\n\n\n\n<p>Now here&#8217;s what the resulting simulation looks like:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"630\" src=\"https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-1-1024x630.png\" alt=\"\" class=\"wp-image-1049\" srcset=\"https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-1-1024x630.png 1024w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-1-300x185.png 300w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-1-768x473.png 768w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-1-1536x945.png 1536w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-1.png 1721w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Boring.<\/figcaption><\/figure>\n\n\n\n<p><strong>It&#8217;s very important to understand why this is happening!<\/strong> Or not happening in this case. The POP Object is created on the DOP network&#8217;s starting frame, which is frame 1. The Initial Geometry is sourced from the given SOP geometry at that creation frame. And then, barring any forces to integrate or other work to be done by a solver, absolutely nothing happens. You&#8217;re not giving the solver anything to do! It doesn&#8217;t care that your color attribute is animating in SOPs, because <strong>it&#8217;s not being told to fetch any data from SOPs beyond the initial state.<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">An even simpler (sort of) example<\/h2>\n\n\n\n<p>To give you a little more insight into DOPs, let&#8217;s strip this down even further. The SOPs animation here remains the same, but we&#8217;re going to change the DOP network to be as low-level as we can get. In an empty DOP network, create an Empty Object DOP and a SOP Geometry DOP. Set the SOP Path to the animated geometry from SOPs. Then create an Apply Data DOP and wire the Empty Object into the left input, and the SOP Geometry to the right input. This effectively applies the Geometry data from the SOP Geometry DOP to the empty DOP object we created. Wire that to an Output DOP and you should see your geometry in the viewport. Notice that it&#8217;s still not moving, for the same reason as the previous example.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"602\" src=\"https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-3-1024x602.png\" alt=\"\" class=\"wp-image-1051\" srcset=\"https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-3-1024x602.png 1024w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-3-300x176.png 300w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-3-768x452.png 768w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-3.png 1141w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">The stripped-down DOP network.<\/figcaption><\/figure>\n\n\n\n<p>What we&#8217;re doing here is creating a generic container (the Empty Object) that has some kind of simulation data on it (the <code>Geometry<\/code> data). If you crack open the POP Object DOP, you&#8217;ll see a similar but slightly more complex network. There are all kinds of data that you can attach to an object, but by far the most common data names you&#8217;ll encounter are <code>Geometry<\/code>, which implies typical SOP geometry used in simulation such as particles or RBDs or Vellum cloth, and <code>ConstraintGeometry<\/code>, which implies constraint primitives used by RBDs and Vellum. The various solvers in Houdini know to look for data of these specific names, look for attributes on that data (like <code>v<\/code>, <code>w<\/code>, <code>restlength<\/code>, and so on), and then use those attributes to integrate physical forces or other effects.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Updating data from SOPs<\/h2>\n\n\n\n<p>Now we want to get that animated color attribute in here. To do this, we need to instruct the DOP network to fetch the data from SOPs that we want, and apply it to the <code>Geometry<\/code> data of our simulation. The most straightforward way to do this is via the <strong>SOP Solver DOP<\/strong>. Create a SOP Solver DOP and a Multiple Solver DOP. The Multiple Solver is a convenient little node that you can wire an object into on the left (in this case, the output of the Apply Data DOP), and any number of solvers on the right (in this case, the SOP Solver DOP). The network now looks like this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"621\" src=\"https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-4-1024x621.png\" alt=\"\" class=\"wp-image-1052\" srcset=\"https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-4-1024x621.png 1024w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-4-300x182.png 300w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-4-768x466.png 768w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-4.png 1209w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Adding the SOP Solver into the network.<\/figcaption><\/figure>\n\n\n\n<p>If you take a closer look at the SOP Solver parameters, you can see that the default Data Name is <code>Geometry<\/code>. That means that anything that happens inside the SOP Solver will impact the <code>Geometry<\/code> data of the object, which is perfect because that&#8217;s what we&#8217;re seeing on the screen. Dive inside the SOP Solver and you&#8217;ll see something a little different:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"359\" src=\"https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-5-1024x359.png\" alt=\"\" class=\"wp-image-1053\" srcset=\"https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-5-1024x359.png 1024w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-5-300x105.png 300w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-5-768x269.png 768w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-5-1536x539.png 1536w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-5-2048x718.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Inside the SOP Solver DOP.<\/figcaption><\/figure>\n\n\n\n<p>The default <code>stamps<\/code> expressions here are a bit spooky, but they&#8217;re basically just telling this <code>dop_geometry<\/code> node to fetch whatever we told it to fetch from the object we&#8217;re connected to. If you middle-mouse click on the Geometry Data Path parameter, you&#8217;ll see the expression evaluates to <code>Geometry<\/code>. Also take a closer look at the node type of this node&#8230; it&#8217;s a DOP Import <strong>SOP<\/strong>. We&#8217;re back in SOPs! That&#8217;s the magic of this solver&#8230; we can take geometry-like data from a DOP object and manipulate it using SOP tools, in the middle of a simulation.<\/p>\n\n\n\n<p>In this example, what we want to do is get the animated <code>Cd<\/code> attribute from our original SOP timeline and apply it to our simulated geometry. Now that we&#8217;re back in SOPs, we can start to think in SOP terms again! How would you copy an attribute from one SOP to another&#8230;? You&#8217;d just merge that source geometry in from another network and use the Attribute Copy SOP!<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"600\" src=\"https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-6-1024x600.png\" alt=\"\" class=\"wp-image-1054\" srcset=\"https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-6-1024x600.png 1024w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-6-300x176.png 300w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-6-768x450.png 768w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-6.png 1224w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">Fetching the Cd attribute from SOPs and applying it to our Geometry data.<\/figcaption><\/figure>\n\n\n\n<p>If you play this back, you&#8217;ll see that now the colors are again animated as before.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Getting a little more complex<\/h2>\n\n\n\n<p>The SOP Solver DOP is incredibly powerful and intuitive once you understand what it&#8217;s doing; you can manipulate pretty much any aspect of the simulation during runtime using all the SOP tools you&#8217;re likely already familiar with. The only big downside is that it tends to have a bit of overhead. In this example you won&#8217;t really notice much, but if you start updating attributes on a much heavier simulation, you&#8217;ll notice a significant slowdown. <\/p>\n\n\n\n<p>If all you need to do is update attributes and not actually use SOP tools, there&#8217;s a much faster way to do it: the <strong>Geometry Wrangle<\/strong>. Unfortunately for those of you who are scared of code, this requires that you use a bit of VEX, but it&#8217;s really nothing too crazy for most cases. Disconnect the SOP Solver and wire up a Geometry Wrangle DOP in its place. What we want to do with the VEX is grab the <code>Cd<\/code> attribute from the SOP geometry using a <code>point()<\/code> expression, and then bind it to <code>Cd<\/code>. This is pretty straightforward:<\/p>\n\n\n\n<p><pre class=\"brush: plain; title: ; notranslate\" title=\"\">vector Cd = point(1, &quot;Cd&quot;, @ptnum);\nv@Cd = Cd;<\/pre><\/p>\n\n\n\n<p>If you&#8217;re used to Point Wrangles in SOPs, this syntax will look familiar. But what is input 1 in this case? We don&#8217;t have the usual four inputs on the node itself to use in DOPs, so instead you have to go to the Inputs tab and configure it there:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"444\" src=\"https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-7-1024x444.png\" alt=\"\" class=\"wp-image-1062\" srcset=\"https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-7-1024x444.png 1024w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-7-300x130.png 300w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-7-768x333.png 768w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-7-1536x666.png 1536w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-7.png 1757w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">The Inputs configuration for the Geometry Wrangle.<\/figcaption><\/figure>\n\n\n\n<p>Remember that the input numbered 1 in a Wrangle is referring to the <strong>second<\/strong> input, or Input 2 here. This is because in VEX terms, the inputs are an array starting at index 0, even though the UI labels them as inputs 1 through 4. This has always been confusing. The configured Input 2 shown above is what we&#8217;re referencing when we run that <code>point(1, \"Cd\", @ptnum)<\/code>; line.<\/p>\n\n\n\n<p>Finally, take a look at the Data Bindings tab. You don&#8217;t need to change anything here just yet, but this is where you&#8217;d set the name of the DOP data you intend to modify. By default this is <code>Geometry<\/code> which is exactly what we want. We&#8217;ll come back to this later. With that code in place, run the timeline and you will again get the glorious animated color attribute you&#8217;d always dreamed of:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/sop_color_anim.gif\" alt=\"\"\/><figcaption class=\"wp-element-caption\">Truly extraordinary.<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Getting weirder<\/h2>\n\n\n\n<p>Most people encounter the problem at the root of this blog post because they want to make silly wiggly Vellum things like they saw on Instagram or whatever. The way these are done is typically by manipulating the <code>restlength<\/code> or <code>stiffness<\/code> of various Vellum constraints to cause them to inflate or droop or anything you like. Where people get stuck is that they try to use some attribute they&#8217;ve carefully animated in SOPs to drive the constraint animation, not realizing that DOPs absolutely does not care about all the work you&#8217;ve done. Let&#8217;s do an example of this now where we take the techniques we&#8217;ve already learned and apply them to a slightly different bit of simulation data, <code>ConstraintGeometry<\/code>.<\/p>\n\n\n\n<p>Here&#8217;s a really simple Vellum setup. A remeshed pig head gets fed into a Vellum Configure Cloth SOP, with the stretch stiffness set pretty high: 1e+10. Following that, some animated Attribute Noise is used to create a float attribute on the constraint primitives called <code>restlengthscale<\/code>. The value is set to a minimum of 0.0 and a maximum of 2.0. This attribute is not actually one recognized by the Vellum solver&#8230; we could name it <code>catvomit<\/code> and it would have the same effect here. There&#8217;s also a Visualizer here to be able to better see the generated noise pattern. Finally, an Enumerate SOP is added here to create an <code>id<\/code> attribute on the constraint primitives. If you&#8217;re going to be manipulating constraints inside a Vellum Solver SOP, it&#8217;s very important that you have a <strong>primitive id attribute on the constraints<\/strong> because the constraint primitive order will be scrambled in the simulation due to all of the behind-the-scenes prep work that the Vellum Solver SOP handles for you. This isn&#8217;t necessary if you&#8217;re using an old-fashioned DOP network, but having an <code>id<\/code> on your primitives is still good practice! The network looks like this:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" loading=\"lazy\" width=\"1024\" height=\"641\" src=\"https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-8-1024x641.png\" alt=\"\" class=\"wp-image-1070\" srcset=\"https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-8-1024x641.png 1024w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-8-300x188.png 300w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-8-768x481.png 768w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-8-1536x962.png 1536w, https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/image-8-2048x1283.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\">The setup for animating constraint lengths in SOPs.<\/figcaption><\/figure>\n\n\n\n<p>What we need to do now is bring this <code>restlengthscale<\/code> (or <code>catvomit<\/code>) attribute into DOPs. It&#8217;s very possible to do this with a Geometry Wrangle just like before, but Houdini has a convenience node for you called <strong>Vellum Constraint Properties<\/strong> that makes setting certain properties like <code>restlength<\/code> much simpler. Unlike <code>restlengthscale<\/code>, <code>restlength<\/code> is actually recognized by the Vellum solver and will affect the constraint primitives.<\/p>\n\n\n\n<p>If you dive inside the Vellum Solver SOP and place a Vellum Constraint Properties node, you&#8217;ll see the familiar Bindings and Inputs tabs at the top. This is because internally this HDA is a Geometry Wrangle (it&#8217;s actually a Geometry VOP but close enough) with some shortcuts set up for you! Under the Bindings tab you can see that the Geometry parameter is set to <code>ConstraintGeometry<\/code>, so this operation will affect the constraint primitives and not the actual cloth primitives.<\/p>\n\n\n\n<p>Now under the Inputs tab, we want to again point to a particular SOP to fetch data from, just like before. Inputs 1 and 2 come pre-configured and we have two extra inputs anyways, so just set Input 3 to be a SOP and point it to the animated constraints in your SOP network. It&#8217;s important when using these nodes inside a SOP wrapper like the Vellum Solver SOP (as opposed to a DOP Network) to <strong>always use SOP paths rather than context geometry<\/strong>. The context geometry is meant to point to the inputs of the DOP network, but because the DOP network in this case is wrapped up in a SOP, it&#8217;s not going to point you to the input you&#8217;re expecting. Just use SOP paths.<\/p>\n\n\n\n<p>Finally, we need to go to the Properties tab and modify the Rest Length Scale. We want to only affect the <code>stretch<\/code> constraint group, so enable the Group parameter and give it the <code>stretch<\/code> group so we don&#8217;t change the bend constraints. Since we&#8217;re changing the rest length per-primitive we&#8217;ll leave the constant value at 1 and enable Use VEXpression. The VEXpression needs to do essentially exactly what we did before with fetching a point attribute, but instead we&#8217;re fetching a primitive attribute and we need to use the primitive <code>id<\/code> attribute rather than just the primitive number. The code looks like this:<\/p>\n\n\n\n<p><pre class=\"brush: plain; title: ; notranslate\" title=\"\">\n\/\/ get the matching primitive from SOPs based on id\nint primnum = idtoprim(2, i@id);\n\/\/ get the attribute we made in SOPs from this prim\nfloat scale = prim(2, &quot;restlengthscale&quot;, primnum);\n\/\/ override the Rest Length Scale parameter with this value\nrestscale = scale;\n<\/pre>\n<\/p>\n\n\n\n<p>If you&#8217;re not used to VEXpressions, the property we&#8217;re overriding, <code>restscale<\/code>, is the <strong>name of the parameter<\/strong> we&#8217;re setting values for on the Vellum Constraint Properties DOP. Under the hood, this node is reading that value and using it to set the <code>restlength<\/code> primitive attribute, based on the <code>restlengthorig<\/code> primitive attribute that&#8217;s automatically created. We could do this ourselves with a little arithmetic but this node just simplifies it for you.<\/p>\n\n\n\n<p>Here&#8217;s the result from animating those constraint lengths:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img decoding=\"async\" loading=\"lazy\" width=\"686\" height=\"800\" src=\"https:\/\/www.toadstorm.com\/blog\/wp-content\/uploads\/2024\/02\/vellum_constraint_restlength.gif\" alt=\"\" class=\"wp-image-1071\"\/><figcaption class=\"wp-element-caption\">TUT PLZ<\/figcaption><\/figure>\n\n\n\n<p>Incidentally, this whole process of importing an attribute from SOPs based on an id or name and binding it to some DOP geometry property is something I&#8217;ve simplified somewhat with <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/toadstorm\/MOPS\/wiki\/MOPsDOPs#mops-fetch-attributes-dop-plus\" data-type=\"URL\" data-id=\"https:\/\/github.com\/toadstorm\/MOPS\/wiki\/MOPsDOPs#mops-fetch-attributes-dop-plus\" target=\"_blank\">MOPs+ Fetch Attribute.<\/a> If you don&#8217;t feel like going through that whole process every time, or if you need to sneak a quick remap in there, it handles much of this for you.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Houdini (sometimes) will help you!<\/h2>\n\n\n\n<p>There are a few exceptions to this rule, mostly related to RBDs. If you look at the RBD Packed Object DOP, there&#8217;s an optional &#8220;Overwrite Attributes&#8221; parameter and a list of attributes you can overwrite. This is a shortcut to fetch attributes from your chosen Geometry Source (usually a SOP) and update them during the simulation. Similarly, RBD-specific attributes like <code>i@deforming<\/code> can force affected geometry to update its collision mesh based on any deformations happening in SOPs, and <code>i@animated<\/code> has a similar effect for animating the transform of each object. Shortcuts like this are the exception rather than the rule in Houdini, though, and it&#8217;s important to know that most of the time you&#8217;re responsible for updating the DOP geometry from SOPs.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Remember: DOPs are not SOPs<\/h2>\n\n\n\n<p>If there&#8217;s anything to take away from this article, it&#8217;s that <strong>SOPs and DOPs have their own timelines<\/strong>. If you want your simulation to have animated attributes from SOPs, you just have to fetch them yourself. Take the opportunity to play around a bit more with SOP Solver DOPs and Geometry Wrangles, though, because you really can mess around with just about any aspect of your simulation and create some really unexpected effects. <\/p>\n\n\n\n<p><a href=\"https:\/\/www.toadstorm.com\/freebies\/dops_are_not_sops.hip\" data-type=\"URL\" data-id=\"https:\/\/www.toadstorm.com\/freebies\/dops_are_not_sops.hip\">Here&#8217;s the .hip file<\/a>, and hope this was helpful!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I wanted to make a post about a really common misconception regarding Houdini&#8217;s geometry context (SOPs) versus its dynamics context (DOPs). Houdini&#8217;s documentation does explain a bit of basic information about DOPs, but not necessarily in the most readable way for Houdini newcomers who are first introduced to the software [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/www.toadstorm.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1046"}],"collection":[{"href":"https:\/\/www.toadstorm.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.toadstorm.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.toadstorm.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.toadstorm.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1046"}],"version-history":[{"count":25,"href":"https:\/\/www.toadstorm.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1046\/revisions"}],"predecessor-version":[{"id":1087,"href":"https:\/\/www.toadstorm.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/1046\/revisions\/1087"}],"wp:attachment":[{"href":"https:\/\/www.toadstorm.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1046"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.toadstorm.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1046"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.toadstorm.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1046"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}