Jump to content

Nurbs Numbness ...


Guest xionmark

Recommended Posts

Guest xionmark

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

Link to comment
Share on other sites

1. Create a NURBS curve

nurbs01.png

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

nurbs02.png

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)

nurbs03.png

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 :P) 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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

Guest xionmark

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. :blink:

--Mark

Link to comment
Share on other sites

Guest xionmark
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

Link to comment
Share on other sites

The Python code in the modules pntvec and splines is actually quite old (>10 years with funny German comments :P) 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.

Link to comment
Share on other sites

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 ...

Link to comment
Share on other sites

  • 3 weeks later...

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...