Push curve to surface

   3782   6   3
User Avatar
Member
79 posts
Joined: 2月 2008
Offline
So I have these curves that are penetrating in and out of some geometry and I'm looking for a way to push the points on the surface of that geometry without completely destroying the smoothness of the curve. Here is a simplified example of the type of situation I have to deal with :



Now, I usually convert the mesh to a VDB and use an attribute wrangle to push the points outside the mesh using VEX code that looks like this:

float dist = volumesample(1, 0, @P);
vector dir = volumegradient(1, 0, @P);
if (dist < 0)
    @P += -1 * dist * dir;

...problem is, certain points on the curves are closer to the surface on one side of the mesh while others are closer to the other side of the mesh, so this gives me a broken curve that goes through the volume and looks like this:



..What I am looking for is something that would look more like this:




Any tips on how to get these type of curves pushed out to the same side of a mesh?

Attachments:
Original_curve.JPG (19.6 KB)
result.JPG (18.9 KB)
goal.JPG (17.0 KB)

User Avatar
Member
471 posts
Joined: 7月 2005
Offline
Hi,

taking the average of all (closest)directions of the inner part of the curve to the object can be an option.

@btw taking the v@up is another option (orientation along curve attribute), which can be modified by rotation matrix.
Edited by Aizatulin - 2021年4月17日 08:45:14

Attachments:
curve_along_surface.hipnc (94.7 KB)
curve_along_surfaceA.hipnc (105.2 KB)

User Avatar
Member
191 posts
Joined: 10月 2018
Offline
You could probably give the curve normals that are facing the same direction as the side of the geo you want it to stick to, then use the Ray SOP to snap them to the surface using Intersect Farthest Surface if necessary.
User Avatar
Member
897 posts
Joined: 7月 2018
Offline
You should step through the curve points to avoid the sudden pops. This lets you keep track of what side the curve is on and use that in the projection.

Store the difference in position between a point and the previous on in an attribute. Walk over the points in a prim wrangler. For every point, apply the stored offset. (here the output should be identical to the input). Now also apply the projection from this position, set the result as the points P value and use it as reference for the next point in the loop.

This will avoid the sudden jump you have. It might give some issues when the curves comes back out from the shape again but this more subtle and can be handled by letting the wrangler also affect the outside points and/or blending in the original P attrib.
B.Henriksson, DICE
User Avatar
Member
142 posts
Joined: 8月 2009
Offline
Ray sop minimum Dist

Attachments:
sdfss.jpg (263.3 KB)

User Avatar
Member
79 posts
Joined: 2月 2008
Offline
Thanks all for the tips and recommendations. I ended up blending a few of your ideas and cooking up my own which seems to do the job. We'll see when it's applied to multiple shots if I need to revisit this solution, but you input has been highly useful so thank you very much.
User Avatar
Member
16 posts
Joined: 10月 2017
Offline
Hey, I'm a bit late but you can also take advantage of the xyzdist() function like this :

float dist = volumesample(1, 0, @P);

if(dist < 0.0f)
{
    int c_prim;
    vector v_uv;
    xyzdist(2, @P, c_prim, c_uv);
    @P = primuv(2, "P", c_prim, c_uv);
}

Cheers,
  • Quick Links