Drawings SDK Developer Guide > Working with .dwg Files > Working with Entities > Working with Specific Entitites > Working with NURBS Surfaces > Working with Control Points of NURBS Surfaces
Working with Control Points of NURBS Surfaces

Control points define the track along which the B-splines are drawn.

The OdDbNurbSurface class allows you to insert or delete the row or column of control points, get the location of each control point and fill the control points array.

In the following examples, the pNurbSurf variable stores a pointer to the NURBS surface object.

Note: The set methods work in SpaModeler.

Number of Control Points

A NURBS surface entity stores the number of rows and columns.

To get the number of rows (u-direction), use the getNumberOfControlPointsInU() method, which returns the number of rows as an integer value through its argument. To get the number of columns (v-direction), use the getNumberOfControlPointsInV() method, which returns the number of columns as an integer value through its argument.

For example:


// Get number of rows
int sizeU;
pNurbSurf->getNumberOfControlPointsInU(sizeU);
odPrintConsoleString(L"\nNumber of rows = %i", sizeU); 

// Get number of columns
int sizeV;
pNurbSurf->getNumberOfControlPointsInV(sizeV);
odPrintConsoleString(L"\nNumber of columns = %i", sizeV);

Get and Set an Array of Control Points

To set a new array of control points, use the setControlPoints() method, which requires three parameters: two integer values to determine the number of control points in the u- and v-directions and an array of OdGePoints as an array of control points. If the surface has n control points in the u-direction and m control points in the v-direction, the array looks like [0,0], [0,1], ...[0,m-1], ..., [n-1,0], [n-1,1], ...[n-1,m-1].

For example:


// Size of the matrix
int iUCount = 3;
int iVCount = 4;
int pntCount = iUCount * iVCount;
OdGePoint3d arrCP[] = {OdGePoint3d(0, 0, 1), OdGePoint3d(3, 0, 1), OdGePoint3d(4, 0, 1), OdGePoint3d(7, 0, 1),
                       OdGePoint3d(0, 3, 2), OdGePoint3d(3, 3, 2), OdGePoint3d(4, 3, 2), OdGePoint3d(7, 3, 2),
                       OdGePoint3d(0, 5, -1), OdGePoint3d(3, 5, -1), OdGePoint3d(4, 5, -1), OdGePoint3d(7, 5, -1)};
// Array of control points
OdGePoint3dArray controlPoints;
for (int i = 0; i < pntCount; i++)
{
  controlPoints.push_back(arrCP[i]);
}

// Set the data
pNurbSurf -> setControlPoints(iUCount, iVCount, controlPoints);

To get the control points and a number of the control points, use the getControlPoints() method, which requires three parameters: two integer values to return the number of control points in the u- and v-directions and an array of OdGePoints to return an array of control points.

For example:


int iUCount;
int iVCount;
int iNum = 0;
OdGePoint3dArray controlPoints;
// Get the data
pNurbSurf->getControlPoints(iUCount, iVCount, controlPoints);

for (int i = 0; i < iUCount; i++)
  for (int j = 0; j < iVCount; j++)
  {
    odPrintConsoleString(L"\nPoint[%i,%i] = %f; %f; %f", i, j, controlPoints[iNum].x, controlPoints[iNum].y, controlPoints[iNum].z);
    iNum++;
  }

Work with Rows and Columns of Control Points

To insert a row or column to a specified location, use the InsertControlPointsAtU() and InsertControlPointsAtV() methods, which require three parameters: one double value to specify the u- or v-location of the points to be inserted, an array of points that should be inserted, and an array of each point's weights.

For example:


// Set position
double dU = 1.5;
double dV = 2.1;

int numPntInRow = 4;
int numPntInCol = 4;
// Set arrays of points
OdGePoint3d arrCPU[] = {OdGePoint3d(0, 4, 0), OdGePoint3d(3, 4, 0), OdGePoint3d(4, 4, 0), OdGePoint3d(7, 4, 0)};
OdGePoint3d arrCPV[] = {OdGePoint3d(5, 0, 1), OdGePoint3d(5, 3, 2), OdGePoint3d(5, 4, 2), OdGePoint3d(5, 5, -1)};

OdGePoint3dArray controlPointsU, controlPointsV;
for (int i = 0; i < numPntInRow; i++)
{
  controlPointsU.push_back(arrCPU[i]);
}
for (int i = 0; i < numPntInCol; i++)
{
  controlPointsV.push_back(arrCPV[i]);
}

// Set arrays of weights
OdGeDoubleArray uWeights, vWeights;

double arrUWeights[] = {3, 4, 3, 4};
double arrVWeights[] = {4, 3, 4, 2};

for (int i = 0; i < numPntInRow; i++)
{
  uWeights.push_back(arrUWeights[i]);
}
for (int i = 0; i < numPntInCol; i++)
{
  vWeights.push_back(arrVWeights[i]);
}

// Insert the row
pNurbSurf->InsertControlPointsAtU(dU, controlPointsU, uWeights);

// Insert the column
pNurbSurf->InsertControlPointsAtV(dV, controlPointsV, vWeights);

To remove an array of control points from a specified row or column, use the RemoveControlPointsAtU() and RemoveControlPointsAtV() methods, which require one integer argument to specify the number of the row or column.

For example:


// Remove second row
pNurbSurf->RemoveControlPointsAtU(1);

// Remove third column
pNurbSurf->RemoveControlPointsAtV(2);

Work with a Specified Control Point

To get a point at a specified position, use the getControlPointAt() method, which requires three parameters: two integer values to specify the number of the row and column and an OdGePoint3d object though which the point is returned.

For example:


OdGePoint3d cntrPnt;
// Get the first control point
pNurbSurf->getControlPointAt(0, 0, cntrPnt);
odPrintConsoleString(L"\nFirst control point is (%f; %f; %f)", cntrPnt.x, cntrPnt.y, cntrPnt.z);

To change a point at a specified position, use the setControlPointAt() method, which requires three parameters: two integer values to specify the number of the row and column and an OdGePoint3d object to specify the new control point data.

For example:


OdGePoint3d cntrPnt;
// Get the first control point
pNurbSurf->getControlPointAt(0, 0, cntrPnt);
// Change the position
cntrPnt.x +=0.5;
cntrPnt.y +=0.5;
cntrPnt.z +=0.5;

// Set new point to the start of the arrays
pNurbSurf->setControlPointAt(0, 0, cntrPnt);

Get the Parameters of a Surface Point

If you know the point on a surface, you can get its u and v parameters using the getParameterOfPoint() method, which requires three parameters: an OdGePoint3d object to specify the point on the surface, and two double values to return the u and v parameters.

For example:


OdGePoint3d point = OdgePoint3d(3, 0, 1);
pNurbSurf->getParameterOfPoint(point, dU, dV);

odPrintConsoleString(L"\nPoint has next parameters: dU=%f; dV =%f", dU, dV);

Work with Weights of Points

The weight of a control point is the value that controls the curve shape near it. If the weight is near zero, the curve is near to being a straight line. If the weight decreases, the curve deviates from the point. If the weight increases, the curve approaches the point. A NURBS surface is called rational when all of its controls points have weights.

To get the weight of a specified point, use the getWeight() method, which requires three parameters: two integer values to specify the index of the row and column and one double value through which the weight is returned.

For example:


double weight;
pNurbSurf->getWeight(1, 2, weight);

odPrintConsoleString(L"\nWeight of point [1,2] is %f",weight);

To set a weight for a specified point, use the setWeight() method, which requires three parameters: two integer values to specify the index of the row and column and one double value to specify the point weight.

For example:


double weight = 1.5;
pNurbSurf->setWeight(1, 2, weight);

Verify a Point that Belongs to a Surface

You can check whether a point belongs to a NURBS surface. To do so, use the isPointOnSurface() method, which requires two parameters: an OdGePoint3d object to specify the point and a bool value through which the result of this check is returned.

For example:


OdGePoint3d point = OdgePoint3d(2, 1, 0);
bool bOnSurface;
pNurbSurf->isPointOnSurface(point, bOnSurface);

odPrintConsoleString(L"\npoint is %s surface", ((bOnSurface) ? L"on the" : L" not on the"));

See Also

Working with NURBS Surfaces

Copyright © 2002 – 2020. Open Design Alliance. All rights reserved.