opennurbsfaq
Last changed: dale@mcneel.com-204.177.179.95

.
DeveloperopenNURBS

Background:

The openNURBS Toolkit consists of C++ source code for a library that will read and write a openNURBS 3-D model files (.3dm). More than 400 software development teams and applications, including Rhino, exchange 3-D models using the openNURBS (.3dm) file format.

For more information abount the openNURBS Initiative, please visit http://www.openNURBS.org

Audience:

The openNURBS Toolkit is intended for use by skilled C++ programmers. The openNURBS Toolkit includes complete source code to create a library that will read and write openNURBS .3dm files. In addition, source code for several example programs is included.

Overview:

Currently, the openNURBS Toolkit will read and write all information in version 2, 3, and 4 files and read version 1 files. Version 1 files were created by Rhino 1 and the Rhino I/O toolkit, the predecessor to openNURBS.

In addition, the openNURBS Toolkit provides NURBS evaluation tools and elementary geometric and 3d view manipulation tools.

Instructions:

Four makefiles are included:

If you are using another comipler, then modify makefile to work with your compiler.

Note Well:

Getting Started:

If your goal is to read and write 3dm files, then you may find that the class ONX_Model::Read() and ONX_Model::Write() to be an easy way to attain your goal. See example_read.cpp and example_write.cpp for more details.

  1. Compile the openNURBS Toolkit library. In order to compile the example programs you must link with the openNURBS Toolkit library. Compile the library as described in the first paragraph of the Instructions section.
  2. Study example_read\example_read.cpp. All of the openNURBS geometry classes are derived from the ON_Geometry class. If you need generic attribute information, there is probably a ON_Geometry member function that will answer your query. See the Dump() function in example_read.cpp for code that demonstrates how to use the Cast() function to get at the actual class definitions.
  3. Study example_write\example_write.cpp. If you want to write points, meshes, NURBS curves, NURBS surfaces, or trimmed NURBS surfaces, you should be able to cut and paste most of what you need from the functions in example_write.cpp. If you want to write trimmed surfaces or b-reps, then please study example_brep.cpp.
  4. Study example_brep\example_brep.cpp. If you want to write solid models or more general b-reps, then you should first work through example_write.cpp and then work through example_brep.cpp.
  5. The comments in the openNURBS Toolkit header files are intended to be the primary source of documentation. I suggest that you use a development environment that has high quality tags capabilities and a good class browser.

Support

If you have a question concerning the openNURBS Toolkit that is not answered here or covered in the examples, then please post your question on the support newsgroup at news://news.mcneel.com/opennurbs If you are at a location that does not permit access to news://news.mcneel.com/opennurbs, then you can use the web version of the newsgroup at http://news2.mcneel.com/scripts/dnewsweb.exe?cmd=xover&group=opennurbs You can search archived newsgroup messages at http://news2.mcneel.com/scripts/dnewsweb.exe?cmd=f_search&utag=

Endianness:

The openNURBS Toolkit is works correctly on both big and little endian CPUs. (Generally, Intel CPUs use little endian byte order and MIPS, Motorola, and Sparc CPUs use big endian byte order.)

Examples:

Versions of 3DM files

  1. Version 1 3DM files. The openNURBS toolkit will read version 1 files. Rhino 1 and other applications using the old Rhino I/O toolkit create version 1 files.
  2. Version 2 3DM files. The openNURBS toolkit will read and write version 2 files. Rhino 2 and applications using an openNURBS toolkit released on or after December 2000 create version 2 files. (Rhino 1 and the old Rhino I/O toolkit will not read version 2 files.)
  3. Version 3 3DM files. The openNURBS toolkit will read and write version 3 files. Rhino 3 and applications using an openNURBS toolkit released on or after October 2002 create version 3 files. (Rhino 1 and Rhino 2 will not read version 2 files.)
  4. Version 4 3DM files. The openNURBS toolkit will read and write version 4 files. Rhino 4 and applications using an openNURBS toolkit released on or after September 2006 create version 4 files. (Rhino 1, Rhino 2, and Rhino 3 will not read version 4 files.)

Supported compilers

The openNURBS toolkit has been successfully used with the following compilers:

The openNURBS C++ source code is clean and fairly simple. You should be able to use any good C++ compiler that has 32-bit integers and 32-bit pointers.

OpenNURBS works with 32 or 64 bit pointers.

OpenNURBS uses UNICODE to store text information in 3DM files. At the time of this release, support for UNICODE / ASCII conversion on UNIX platforms is spotty at best.

Excellent compilers and make utilities are available from The Free Software Foundation <http://www.fsf.org>. You have the option of using these tools free of charge.

If you are using a good quality C++ compiler and run into some toolkit code that causes problems, please let us know and we'll attempt to change the code to accommodate the compiler.

Visual Studio 6 Users

If you get a compile bug error c2676 binary != not defined for struct _GUID, then you are not using the November 2001 Platform SDK or the platform SDK is not first in your includes and libraries list.

Vertex ordering in ON_Mesh faces

All faces in a ON_Mesh are stored with vertices listed in counter-clockwise order. In particular, for quads the vertices are ordered as

  v3-----v2
  |       |
  v0-----v1

The quads may be non-planar.

The definition of

  void ON_GL( const ON_Mesh& )

in opennurbs_gl.cpp demonstrates how to go through an ON_Mesh and render all the quads as two triangles.

Compiling the Open GL example:

Carefully read the three paragraphs in the readme.txt file that cover example.cpp.

  1. Your system must have the Open GL header files and libraries, including the auxiliary library (usually contains the Open GL

NURBS rendering stuff) and the utility library. Consult your documentation or local GL whiz for details.

  1. To create the example_gl program you must compile two openNURBS toolkit files (example_gl.cpp and opennurbs_gl.cpp) and link both resulting objects with the openNURBS library and Open GL libraries. If you get unresolved references to ON_GL() functions, then you

probably forgot compile opennurbs_gl.cpp or forgot to link with opennurbs_gl.o/obj.

Orientation of ON_Brep faces

The "UV" orientation of surfaces in a Brep is arbitrary. If the

  BOOL ON_BrepFace::m_bRev

member is FALSE, then the face's orientation agrees with the surface's natural Du X Dv orientation. When the member is TRUE, the face's orientation is opposite the surface's natural Du X Dv orientation.

If your application cannot handle ON_BrepFaces that have a TRUE m_bRev flag, then call ON_Brep::FlipReversedSurfaces(). See the comments in ON_Brep::FlipReversedSurfaces() and ON_Brep::SwapFaceParameters() for details.

Trimming loop order and nesting

The ON_BrepLoop::m_type member records the type of boundary (inner, outer, etc.). A ON_BrepFace has exactly one outer loop and it is the first loop referenced in the ON_BrepFace::m_li[] array. The inner loops all define "holes" in the ON_BrepFace. All of the inner holes lie inside of the outer loop. A ON_BrepFace is always path connected. In particular, inner loops are not "nested".

Surfaces in Rhino are read as ON_Breps

Internally, Rhino stores all surfaces as some type of b-rep and the openNURBS toolkit reads these objects as b-reps. To see if an entire

ON_Brep is really just a surface, use

  BOOL ON_Brep::IsSurface()

If ON_Brep::IsSurface() returns TRUE, then the b-rep geometry is the same as the surface ON_Brep::m_S[0].

To see of a particular face in a b-rep is really just a surface, use

  BOOL ON_Brep::FaceIsSurface( face_index )

If ON_Brep::FaceIsSurface( face_index ) returns TRUE, then the face's geometry is the same as the surface ON_Brep::m_S[face.m_si].