The OpenNURBS library does provide the code for evaluating the 3D point location of a surface at a particular u,v NURBS parameter location. So that method would actually probably involve writing less new code on your part.
The tricky part may just be navigating through the structure of a NURBS model if you are not familiar with that.
Here is a quick overview that should jump start you.
First, you need to download the OpenNURBS toolkit, this is a library that lets you read the contents of .3dm files, that's at
http://opennurbs.org
There is an example project in there called example_read, that shows the basic steps to open a .3dm file and read it into memory. Basically you open a file, then define an ON_BinaryFile object that takes the file pointer, and then there is kind of a high level helper class called ONX_Model that sort of represents the entire model file contents, which can be populated by a call to ONX_Model::Read().
ONX_Model has a member called m_object_table, this is an array that holds all the objects that were sucked out of the .3dm file, each entry in the array is an ONX_Model_Object.
There are various types of objects, like a curve object, a brep object, etc... - you'll want to look for a brep object. I guess you'll probably expect to have just a single surface saved in the file.
ONX_Model_Object has a member m_object, which is an ON_Object, this is the generic base class for the various object types.
To test if the object is a brep, you do something like this:
ON_Brep* pBrep = ON_Brep::Cast( m_object );
if ( pBrep != NULL )
{
// It's a brep, use it.
}
Basically that tests if the generic object is actually a brep object and then casts it to a brep pointer so now you have a brep to work with.
If you're assuming that the brep is made up of just a single surface, you can access that surface by calling
ON_Surface* pSrf = pBrep->m_S[0]; // Grab the first surface of the brep.
Now that you have the surface, you can evaluate points on it. First you need to get the boundaries of the surface's uv space. Surfaces don't necessary have uvs that start at 0 and go to 1, they can be between any range. So to grab the ranges:
double UMin, UMax, VMin, VMax;
pSrf->GetDomain( 0, &UMin, UMax );
pSrf->GetDomain( 1, &VMin, VMax );
Now to evaluate points - you'll step between those ranges. So for example if you want to evaluate 16 steps along the surface, you will go in sixteenth increments between UMin and UMax for the u coordinate, same for v. So that gives you numbers for a u,v point.
Now you can get the 3D point for this UV parameter value by calling:
ON_3dPoint pt = pSrf->PointAt( u, v );
And that's your x,y,z point for that one spot.
Note that I just wrote this up quickly, I didn't test anything so there may be typos above. But those are the basic steps.
If you give it a try, I can probably help you out if you get stuck on something.
- Michael