Drawings SDK: Extrude Entities

Oleksandr Bryzghalin

February 26, 2021

This article describes the extrusion functionality that can be applied to OdDbSubDMesh objects.

To extrude one or more subentities (vertices, edges, faces) to a given length in a given direction, use the extrudeConnectedFaces() method.

OdResult OdDbSubDMesh::extrudeConnectedFaces (const OdDbFullSubentPathArray & subentPaths, double length, const OdGeVector3d & dir, double taper)

It accepts an array of subentities, extrusion length and direction. There is also the angle parameter which indicates a taper, but currently it's not supported.

The length parameter can also accept negative values, in which case the extrusion is performed in the opposite direction, however, this is true only if the directional vector dir has a length of 0. If you do not specify the direction of extrusion (pass a vector of 0 length, such as kIdentity, there are default directions that are used for each subentity:

  • Face — Its normal is used.
  • Vertex — If a vertex coordinate is positive, a corresponding vector coordinate is computed as a sum of the vertex coordinate and the length of extrusion. If a vertex coordinate is 0 or negative, the extrusion length is subtracted.
  • Edge — Since an edge is a line between two vertices, the direction is counted for each vertex and the line moves as its vertices shift.

Examples

Extrude an Edge

This example demonstrates how to extrude an edge of a face.

Before you start the extrusion, get a mesh first. Below is a code fragment that creates one.

OdDbDatabasePtr pDb = pHostApp->createDatabase();
OdGePoint3dArray vertexArray;
OdInt32Array faceArray;
// fill vertices
vertexArray.setLogicalLength(18);
vertexArray[0].set(33.327391024158516, 155.94111693551429, -70.00000000000000);
vertexArray[1].set(33.327391024158501, 110.94598425745652, -53.62311101832843);
vertexArray[2].set(33.327391024158487, 87.004574224659720, -12.15537243668508);
vertexArray[3].set(33.327391024158480, 95.319338670603599, 35.000000000000036);
vertexArray[4].set(33.327391024158473, 131.99970690271749, 65.778483455013600);
vertexArray[5].set(33.327391024158473, 179.88252696831111, 65.778483455013600);
vertexArray[6].set(33.327391024158480, 216.56289520042500, 34.999999999999993);
vertexArray[7].set(33.327391024158487, 224.87765964636884, -12.15537243668512);
vertexArray[8].set(33.327391024158501, 200.93624961357204, -53.62311101832845);
vertexArray[9].set(27.927391024158510, 155.94111693551429, -70.00000000000000);
vertexArray[10].set(27.927391024158496, 200.93624961357204, -53.62311101832845);
vertexArray[11].set(27.927391024158485, 224.87765964636884, -12.15537243668512);
vertexArray[12].set(27.927391024158474, 216.56289520042500, 34.999999999999993);
vertexArray[13].set(27.927391024158464, 179.88252696831111, 65.778483455013600);
vertexArray[14].set(27.927391024158464, 131.99970690271749, 65.778483455013600);
vertexArray[15].set(27.927391024158474, 95.319338670603599, 35.000000000000036);
vertexArray[16].set(27.927391024158485, 87.004574224659720, -12.15537243668509);
vertexArray[17].set(27.927391024158496, 110.94598425745652, -53.62311101832843);

// fill faces
faceArray.setLogicalLength(45);
faceArray[0] = 4;   faceArray[1] = 0;   faceArray[2] = 1;   faceArray[3] = 17;   faceArray[4] = 9;
faceArray[5] = 4;   faceArray[6] = 1;   faceArray[7] = 2;   faceArray[8] = 16;   faceArray[9] = 17;
faceArray[10] = 4;  faceArray[11] = 2;  faceArray[12] = 3;  faceArray[13] = 15;  faceArray[14] = 16;
faceArray[15] = 4;  faceArray[16] = 3;  faceArray[17] = 4;  faceArray[18] = 14;  faceArray[19] = 15;
faceArray[20] = 4;  faceArray[21] = 4;  faceArray[22] = 5;  faceArray[23] = 13;  faceArray[24] = 14;
faceArray[25] = 4;  faceArray[26] = 5;  faceArray[27] = 6;  faceArray[28] = 12;  faceArray[29] = 13;
faceArray[30] = 4;  faceArray[31] = 6;  faceArray[32] = 7;  faceArray[33] = 11;  faceArray[34] = 12;
faceArray[35] = 4;  faceArray[36] = 7;  faceArray[37] = 8;  faceArray[38] = 10;  faceArray[39] = 11;
faceArray[40] = 4;  faceArray[41] = 8;  faceArray[42] = 0;  faceArray[43] = 9;   faceArray[44] = 10;

// Open the Block Table Record
OdDbBlockTableRecordPtr bBTR = pDb->getModelSpaceId().safeOpenObject(OdDb::kForWrite);
// Create a SubDMesh
OdDbSubDMeshPtr pSubDMesh = OdDbSubDMesh::createObject();
pSubDMesh->setDatabaseDefaults(bBTR->database());
pSubDMesh->setSubDMesh(vertexArray, faceArray, 0);
bBTR->appendOdDbEntity(pSubDMesh);

The resulting mesh is shown below:

 

initial mesh

 

Now, a face is extruded along the z-axis by a distance of 10. The chosen face is shown below:

 

direction



The next image shows the detail more closely, and the arrows specify the direction of extrusion.


OdDbFullSubentPathArray subentPaths;
double dLength(10.);
OdGeVector3d vecDir(OdGeVector3d::kZAxis);
double dTaper(0.);
pSubDMesh->getSubentPathsAtGsMarker(OdDb::kEdgeSubentType, 2, OdGePoint3d(), OdGeMatrix3d(), subentPaths);
OdResult res = pSubDMesh->extrudeConnectedFaces(subentPaths.at(0), dLength, vecDir, dTaper);

If the operation completes successfully, you get a mesh with an extruded edge:

 

extruded

 

Here, you can see that the selected edge has moved up by 10 units. In fact, two points that represent the start and end of this edge have shifted by 10 units along the z-axis. In this example, kZAxis is used as a directional vector, and its length isn't 0 so it doesn't matter whether dLength is positive or negative. But if kIdentity is used instead, the sign of dLength would matter.

Extrude a Face

The OdDbSubDMesh::extrudeConnectedFaces() method allows you to extrude faces as well as other subentities. This example demonstrates how to extrude several faces of the original mesh shown previously.

To extrude every other face of the original mesh, you can use the following code:


OdDbFullSubentPathArray subentPaths;
double dLength(10.);
double dTaper(0.);
OdGeVector2dArray arrNorms;
pSubDMesh->getSubentPath(-1, OdDb::kFaceSubentType, subentPaths);
for (int i = 0; i < subentPaths.length(); i+=2)
{
OdGePlane gePlane;
pSubDMesh->getFacePlane(subentPaths.at(i).subentId(), gePlane);
OdDbFullSubentPathArray subentCurr(1);
subentCurr.append(subentPaths.at(i));
OdResult res = pSubDMesh->extrudeConnectedFaces(subentCurr, dLength, gePlane.normal(), dTaper);
}

The result of the extruded faces is below:

 

face 1

 

Note that here each face is extruded individually. If you put all the needed faces into an array and perform an extrusion this way, the result will be different (see below).

OdDbFullSubentPathArray subentPaths, subentPathsToExtrude;
double dLength(10.);
double dTaper(0.);
OdGeVector2dArray arrNorms;
pSubDMesh->getSubentPath(-1, OdDb::kFaceSubentType, subentPaths);
for (int i = 0; i < subentPaths.length(); i += 2) {
subentPathsToExtrude.append(subentPaths.at(i));
}
OdResult res = pSubDMesh->extrudeConnectedFaces(subentPathsToExtrude, dLength, OdGeVector3d::kIdentity, dTaper);

 

extruded entities - face 2

 

This mesh has two connected faces, and in this case the extrusion produces a joint extruded face, which is opposite to the previous example where each face was extruded separately and, as a result, the extruded faces were separate as well.