本文介绍了可应用于 OdDbSubDMesh 对象的拉伸功能。
要将一个或多个子实体(顶点、边、面)沿给定方向拉伸到给定长度,请使用 extrudeConnectedFaces() 方法。
OdResult OdDbSubDMesh::extrudeConnectedFaces (const OdDbFullSubentPathArray & subentPaths, double length, const OdGeVector3d & dir, double taper)
它接受子实体数组、拉伸长度和方向。还有一个表示锥度的角度参数,但目前不支持。
长度参数也可以接受负值,在这种情况下,挤出操作将沿相反方向进行,但前提是方向向量 dir 的长度为 0。如果您未指定挤出方向(传递一个长度为 0 的向量,例如 kIdentity),则会为每个子实体使用默认方向:
- 面 — 使用其法线。
- 顶点 — 如果顶点坐标为正,则相应的向量坐标计算为顶点坐标与挤出长度之和。如果顶点坐标为 0 或负,则减去挤出长度。
- 边 — 由于边是两个顶点之间的一条线,因此会为每个顶点计算方向,并且线会随着其顶点的移动而移动。
示例
挤出边
此示例演示如何挤出面的边。
在开始拉伸之前,请先获取一个网格。下面是创建网格的代码片段。
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);
生成的网格如下所示:
现在,一个面沿 z 轴拉伸了 10 个单位。所选面如下所示:
下图更详细地显示了细节,箭头指示了拉伸方向。
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);
如果操作成功完成,您将获得一个带有拉伸边的网格:
在这里,您可以看到所选边向上移动了 10 个单位。实际上,代表该边起点和终点的两个点沿 z 轴移动了 10 个单位。在此示例中,kZAxis 用作方向向量,其长度不为 0,因此 dLength 是正还是负无关紧要。但如果改用 kIdentity,则 dLength 的符号将很重要。
拉伸面
OdDbSubDMesh::extrudeConnectedFaces() 方法允许您拉伸面以及其他子实体。此示例演示如何拉伸前面所示原始网格的多个面。
要拉伸原始网格的隔一个面,您可以使用以下代码:
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);
}
拉伸面的结果如下:
请注意,这里每个面都是单独拉伸的。如果您将所有需要的面放入一个数组并以这种方式执行拉伸,结果将有所不同(见下文)。
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);
此网格具有两个连接面,在这种情况下,挤出生成一个联合挤出面,这与之前的示例相反,在之前的示例中,每个面都是单独挤出的,因此,挤出面也是独立的。