[SESI logo]

Houdini Development Toolkit - Version 6.5

Side Effects Software Inc. 2004

Geometry

Surfaces (Mesh, Bezier & NURBS)

A surface is a generic term describing open or wrapped polygonal meshes, NURBS (Non Uniform B-Splines) surfaces, and Bezier surfaces. NURBS and Bezier surfaces belong to a class of surfaces called Splines.

Basic Functionality

The common functionality of all three surface types is reflected in the base class, GEO_Hull:
  • virtual int insertRow(unsigned int where, int appendpts=1)
  • virtual int insertCol(unsigned int where, int appendpts=1)
  • virtual int deleteRow(unsigned int which)
  • virtual int deleteCol(unsigned int which)
    These methods insert and delete a row or column specified by a row or column index respectively. The Spline classes derive methods to adjust the basis accordingly. The row/column index is returned upon successful completion. If the operation fails, it returns -1.

  • void setRowCol(unsigned int nrows, unsigned int ncols)
    Adjust the size of the vertex matrix. This method does not adjust the Spline bases.

  • const GEO_Vertex &operator()(unsigned int r, unsigned int c) const
  • GEO_Vertex &operator()(unsigned int r, unsigned int c)
  • const GEO_Vertex &getVertex(unsigned int r, unsigned int c) const
  • void setVertex(unsigned int r, unsigned int c, GEO_Point *pt)
    These are subscript operators. The get/set methods check for out-of-bounds errors. operator() does not check for errors but is faster.

  • unsigned isWrappedU() const
  • unsigned isWrappedV() const
  • virtual void wrapU(int rounded = 1, int preserveshape = 0)
  • virtual void openU(int preserveshape = 0, int safe = 0)
  • virtual void wrapV(int rounded = 1, int preserveshape = 0)
  • virtual void openV(int preserveshape = 0, int safe = 0)
    Query the closed/open state of the surface, or set it. The rounded and shape preservation options are meaningful for the Spline surfaces.

  • virtual void reverse (void)
  • virtual void reverseU(void)
  • virtual void reverseV(void)
    Reverse the surface's columns (U) or rows (V), or both. The U/V basis will be reversed too, if necessary.

  • virtual int cycleU(int amount, int = 1)
  • virtual int cycleV(int amount, int = 1)
    Shift the rows or columns an offset and wrap around. The offset can be either negative or positive.

  • virtual int unrollU(void)
  • virtual int unrollV(void)
    Assuming the surface is closed in U/V, "unroll" it so that the CVs that are shared to form a wrapped surface are made unique. Also, the surface becomes open. If the surface is not closed, the method returns -1. Otherwise it returns 0.

  • virtual void transpose()
    Reverse the roles of rows and columns.

  • int getNumRows() const
  • int getNumCols() const
    Find the number of rows or columns.

  • GEO_SurfaceType getSurfaceType() const
  • void setSurfaceType(GEO_SurfaceType t)
    Query or set the surface type. Its value must be one of:
    Surface Type Description
    GEO_PATCH_ROWS Just rows
    GEO_PATCH_COLS Just columns
    GEO_PATCH_ROWCOL Both rows and columns
    GEO_PATCH_TRIANGLE Solid surface of triangles
    GEO_PATCH_QUADS Solid surface of quadrilaterals (default)
    GEO_PATCH_ALTTRIANGLE Triangles, but with common corners

    Even is a surface is built as only rows or columns, it does not become a set of independent curve or polygonal primitives. It is still a surface primitive. Therefore, currently, the surface type is mostly a visual aid and is taken into consideration when converting the surface to other primitive types.


  • Parametric Operations

    To enable a transparent use of all three surface types in a parametric fashion, we define an implicit domain for the mesh type and use the basis domain for the spline types. The size of the polygonal domain is given directly by the number of columns (U) and rows (V).

    As a rule, the U parametric direction is associated with the column array, while the V parametric direction is associated with the column array.

    The following is a list of parametric (domain oriented) methods shared by all surface types:

  • virtual void unitToRealDomain(float u_unit, float v_unit, float &u_real, float &v_real) const
  • virtual void realToUnitDomain(float u_real, float v_real, float &u_unit, float &v_unit) const
    Go from a normalized domain ([0,1]) to the real domain or vice versa.

  • virtual int refineU(float k, int=0)
  • virtual int refineUWAttrib(float k, const GB_FloatOffsets &foffsets, int=0)
  • virtual int refineV(float k, int=0)
  • virtual int refineVWAttrib (float k, const GB_FloatOffsets &foffsets, int=0)
    Change the multiplicity of the domain value by inserting it after checking its current multiplicity. Return -1 if invalid, otherwise return the index of the inserted knot.

  • void homogenize (int startrow = 0, int endrow = -1, int startcol = 0, int endcol = -1)
  • void dehomogenize(int startrow = 0, int endrow = -1, int startcol = 0, int endcol = -1)
  • void homogenizeWAttrib(const GB_FloatOffsets &foffsets, int startrow = 0, int endrow = -1, int startcol = 0, int endcol = -1)
  • void dehomogenizeWAttrib(const GB_FloatOffsets &foffsets, int startrow = 0, int endrow = -1, int startcol = 0, int endcol = -1)
    Express the points in homogeneous coordinates or vice-versa. endcv can be greater than the number of rows or columns or smaller than startcv. In both cases we will wrap the index. The last two methods operate on attributes as well.

  • virtual void weights(unsigned short onoff)
    Turn CV weight checking on or off. While this method is irrelevant for meshes, it determines whether a spline is treated as a rational surface or not. Turning weights off will assume the surface is non-rational (all weights equal) in all subsequent operations.


  • Other important parametric methods are defined only at the Spline surface level, predominantly in GEO_TPSurf (the base class of NURBS and Bezier types):

  • int evaluate(float u, float v, UT_Vector4 &pos, unsigned du=0, unsigned dv=0, int uoffset=-1, int voffset=-1) const
  • int evaluateWAttrib(float u, float v, UT_Vector4 &pos, GB_AttributeData &adata, const GB_FloatOffsets &foffsets, unsigned du=0, unsigned dv=0, int uoffset=-1, int voffset=-1) const
    Evaluate the position or the derivative at domain point (u,v), where u and v must be in the [0,1] interval. Return 0 if OK and -1 otherwise. The second method evaluates the float attributes whose offsets are provided in the GB_FloatOffsets array.

  • virtual int evaluateNormal(float u,float v, UT_Vector3 &nml) const
    Evaluate the unit normal at (u,v) in the domain.

  • virtual int curvature(float u,float v, float &curv) const
    Evaluate the Gaussian curvature at (u,v) in the domain.

  • virtual void reparameterizeU(GB_ParmType ptype) = 0
  • virtual void reparameterizeV(GB_ParmType ptype) = 0
    Reparameterize the U or V basis. Reparameterization can be uniform, chord length, or centripetal.

  • int isRational(void) const
    Find out if the surface is rational, meaning that it has unequal CV weights.

  • int setUBasis(GB_Basis *ub)
  • int setVBasis(GB_Basis *vb)
  • GB_Basis *getUBasis(void) const
  • GB_Basis *getVBasis(void) const
    Query or set the Spline basis. Before a new basis is set, it is tested for validity. If the test fails, the old basis is kept and the methods return -1.

  • unsigned getUOrder(void) const
  • unsigned getVOrder(void) const
    Query the basis order (degree+1). Valid orders range between 2 and 11.

  • int hasProfiles(void) const
  • GEO_Profiles *profiles(void) const
    Find out if the surface contains profile curves, also known as curves on surface.


  • Class Instantiation

    The only non-abstract surface classes are GU_PrimMesh, GU_PrimNURBSurf, and GU_PrimRBezSurf. Although they all have constructors, we recommend that you use the static ::build() methods defined in each class instead. This way the objects will be properly initialized.

    All ::build() methods require a pointer to the primitive container (GU_Detail), a number of rows, and a number or columns. The connectivity and the closed/open flags are optional, as is the option to create GEO_Points. By default, a GEO_Point is created for each vertex.

    Here is an example of how to build a surface of each type:

    GU_Detail gdp; GU_PrimMesh *mesh; GU_PrimNURBSurf *nurbsurf; GU_PrimRBezSurf *beziersurf; // // Build a polygonal mesh with 10 rows, 5 columns, wrapped in U and // open in V: // mesh = GU_PrimMesh::build(&gdp, 10, 5, GU_PATCH_QUADS, 1, 0); // // Build a NURBS surface with 10 rows, 5 columns, order 3 in U, order 4 in // U, open in both parametric directions, and clamped in U. A clamped NURBS // surface is one that touches its end rows or columns. // nurbsurf = GU_PrimNURBSurf::build(&gdp, 10, 5, 3, 4, 0, 0, 1, 0); // // Build a Bezier surface with 10 rows, 5 columns, order 3 in U, order 4 in // U, and open in both parametric directions. // beziersurf = GU_PrimRBezSurf::build(&gdp, 10, 5, 4, 3); // // Since the surfaces were built with automatically generated GEO_Points, // we can assign coordinates to those points as follows: // for (int r = 0; r < mesh->getNumRows(); r++) for (int c = 0; c < mesh->getNumCols(); c++) (*mesh)(r,c).getPos().assign(r,c,0,1); // // To build a surface without automatically generated GEO_Points, add one // more parameter to the build() method and set it to 0: // mesh = GU_PrimMesh::build(&gdp, 10, 5, GU_PATCH_QUADS, 1, 0, 0); // // Points need to be created and assigned to the vertices explicitly: // GEO_Point *ppt; for (int r = 0; r < mesh->getNumRows(); r++) for (int c = 0; c < mesh->getNumCols(); c++) { ppt = gdp.appendPoint(); *ppt = UT_Vector4(r,c,0,1); (*mesh)(r,c).setPt(ppt); } Always check the result of the ::build() method for failure. A surface will not be created unless given valid parameters. A Bezier surface, for example, is particularly strict about the number of CVs for a given basis order.

    NURBS and Bezier surfaces are built with uniform bases in a [0,1] domain. The size and the parameterization of the domain can be changed with GEO_TPSurf::reparameterizeU/V() or by accessing the basis pointers directly with GEO_TPSurf::getU/VBasis().


    Table of Contents
    Operators | Surface Operations | Particle Operations | Composite Operators | Channel Operators
    Material & Texture | Objects | Command and Expression | Render Output |
    Mantra Shaders | Utility Classes | Geometry Library | Image Library | Clip Library
    Customizing UI | Questions & Answers

    Copyright © 2004 Side Effects Software Inc.
    477 Richmond Street West, Toronto, Ontario, Canada M5V 3E7