Guest xionmark Posted March 1, 2007 Share Posted March 1, 2007 Hello there, I'm getting a bit of a headache trying to figure out a problem with NURBS curves in the HDK. Essentially I need to be able to accurately places points on a NURBS curve. Problem is there are various "forms" of a NURBS curve that breaks all the ideas I've tried so far. I've had a bit of success using arcLength() to find the length of the curve but when trying to use the result of this function to determine where along the curve to place the points, I see the "strange/funkiness" of NURBS. I need to be able to place points along any NURBS curve based on a set of rules that are usually quite varied. As a very simple example, let's say I want to uniformily place a set of points along the curve. Dividing up the length returned by arcLength() and using those values to locate the desired location seems reasonable and obvious, but is trashing my assumptions ... I've been told this isn't all too unusual, so I find comfort in others confusions as well. With a simple "flat" curve, it's all pretty groovy, not exact, but close; I can divide the curve up uniformliy, but when more curvature is introduced, things start to "break". int counter = 0; float start, end; my_curve->validRange(start, end); float arc_len_curve = my_curve->arcLength(start, end); float arc_div = float(arc_len_curve/num_divs); std::cout << "start: " << start << " end: " << end << std::endl; std::cout << "arc_len_curve: " << arc_len_curve << " arc_div: " << arc_div << std::endl; while (counter <= num_divs) { div = float((counter) * float(1.0/num_divs)); realval = my_curve->unitToRealDomain(div); arc_len = my_curve->arcLength(start, realval); my_curve->evaluatePoint(pos, div); GEO_Point *geoPoint = gdp->appendPoint(); UT_Vector4 &point = geoPoint->getPos(); point[0] = pos[0]; point[1] = pos[1]; point[2] = pos[2]; point[3] = 1.0; counter++; } Any NURBS gurus out there to steer me in the correct direction? Mega advanced thanks! --Mark Quote Link to comment Share on other sites More sharing options...
wahn Posted March 2, 2007 Share Posted March 2, 2007 1. Create a NURBS curve 2. Split NURBS curve in piecewise Bezier curves 3. Recursively subdivide the Bezier curves until they are flat enough 4. Combine all pieces to a polyline 5. Measure the length of the polyline (by adding all vectors and their length) 6. Redistribute as many point as you want on the polyline (based on the length and step size) 7. Make SESI implement that algorithm (called chord length) import pntvec import splines if __name__ == "__main__": ctrlpts = [pntvec.Point( -1.0, 0.0, 0.0), pntvec.Point(-2.0/3.0, 2.5, 0.0), pntvec.Point( 0.0, -1.0, 0.0), pntvec.Point( 2.0/3.0, -0.5, 0.0), pntvec.Point( 1.0, 0.0, 0.0)] knots = [0.0, 0.0, 0.0, 0.0, 0.5, 1.0, 1.0, 1.0, 1.0] curve = splines.BSplineCurve(ctrlpts, 3, knots) print curve curve.createPath() print curve.length() points = curve.evaluate(0.005) # output for Houdini count = 2 print ("opparm add1 points (%s) " % (len(points) + count)), for point in points: print ("usept%s (on) pt%s (%s %s %s)" % (count, count, point[0], point[1], point[2])), count = count + 1 # chord length pnts = len(points) points = curve.chordLength(pnts) print print "-" * 79 # output for Houdini count = 0 print ("opparm add2 points (%s) " % (len(points) + count)), for point in points: print ("usept%s (on) pt%s (%s %s %s)" % (count, count, point[0], point[1], point[2])), count = count + 1 The Python code in the modules pntvec and splines is actually quite old (>10 years with funny German comments ) and was developed at that time for a real-time application using an Onyx 2 machine to fly over virtual Berlin and the so-called Potsdamer Platz (before the Sony building etc. was actually build there). The spline curves were build on the fly (wherever the user of that 8 DOF joystick was flying to) and connected to pre-calculated "fly-in landing" curves. Cheers, Jan Quote Link to comment Share on other sites More sharing options...
edward Posted March 3, 2007 Share Posted March 3, 2007 float arc_len_curve = my_curve->arcLength(start, end); I'm just guessing here, but you're not passing any values to the default arguments of arcLength(). Try turning on/off forward differencing and increasing the number number of divisions. You might also want to look at GEO_Curve::fillCurve() as well. Quote Link to comment Share on other sites More sharing options...
Guest xionmark Posted March 5, 2007 Share Posted March 5, 2007 Hi Jan! Thanks for the lessons in NURBS! It's starting to make a whole lot more sense now, but I can't find the functions I would need in the HDK and will likely have to link to another library and/or use python and your modules. There's doesn't seem to be anything that returns the chord length, I've looked and tried a number of things, but no luck. Sure would be nice to have some docs ... or maybe more comments that would be exposed while generating Doxygen docs. Maybe with all the changes in H9's API there will be more information to glean, it really takes a long to sort out areas of the HDK that you've never used before. It pains me every time a Maya developer asks, "Doesn't Houdini have dev/API docs?" ... ouch. Fortunately Conference Room T was the perfect place to explore the issue more in depth with you, a few "Liberty Ales" later, it all made more sense ... that is until Saturday morning, oh my head hurt! From your excellent examples I think I can figure it out .. I hope. --Mark Quote Link to comment Share on other sites More sharing options...
Guest xionmark Posted March 5, 2007 Share Posted March 5, 2007 I'm just guessing here, but you're not passing any values to the default arguments of arcLength(). Try turning on/off forward differencing and increasing the number number of divisions. Doesn't seem to make any difference, but I think it's related to the various NURBS curves being processed and how much curvature per segment. Still can't find a way to get the knot sequence, though I can find all kinds of info about knots, multiplicity, etc. Still hunting. > You might also want to look at GEO_Curve::fillCurve() as well. I don't think this is really what I need, as I want to be able to place a point precisely along the curve, the uniform distribution example was a simple implementation of that idea. Ultimately the placement will be based on various attributes and other state information to determine distribution. I'll look at it though, may be faster for some tasks; thanks for the tip. --Mark Quote Link to comment Share on other sites More sharing options...
Guest xionmark Posted March 6, 2007 Share Posted March 6, 2007 Attached is a hip file with Jan's example. Very instructive! Cheers, Mark Quote Link to comment Share on other sites More sharing options...
peliosis Posted March 7, 2007 Share Posted March 7, 2007 The Python code in the modules pntvec and splines is actually quite old (>10 years with funny German comments ) and was developed at that time for a real-time application using an Onyx 2 machine to fly over virtual Berlin and the so-called Potsdamer Platz (before the Sony building etc. was actually build there). The spline curves were build on the fly (wherever the user of that 8 DOF joystick was flying to) and connected to pre-calculated "fly-in landing" curves. Do you have any links to that modules and their story? Google gave me nothing. Quote Link to comment Share on other sites More sharing options...
wahn Posted March 8, 2007 Share Posted March 8, 2007 Do you have any links to that modules and their story? The Virtual City story can still be found here. The Python modules I did send to Mark but if other people are interested in having a look I could make it downloadable on my web page ... Quote Link to comment Share on other sites More sharing options...
antoinedurr Posted March 28, 2007 Share Posted March 28, 2007 7. Make SESI implement that algorithm (called chord length) Isn't that what the resample SOP does? -- Antoine Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.