[返回博客](/cn/blog) # Drawings SDK：拉伸实体

Oleksandr Bryzghalin 二月 26, 2021 [\#getting started](/cn/blog/tag/getting-started) [\#extrusion](/cn/blog/tag/extrusion)

<a class="a2a_button_facebook"></a><a class="a2a_button_twitter"></a><a class="a2a_button_linkedin"></a>

本文介绍了可应用于 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);
```

生成的网格如下所示：

![initial mesh](/files/inline-images/td_extrudeEntities_initialMesh.png)现在，一个面沿 z 轴拉伸了 10 个单位。所选面如下所示：

![direction](/files/inline-images/direction.png)  

下图更详细地显示了细节，箭头指示了拉伸方向。

```

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);
```

如果操作成功完成，您将获得一个带有拉伸边的网格：

![extruded](/files/inline-images/td_extrudeEntities_EdgeFinish.png)在这里，您可以看到所选边向上移动了 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);
}
```

拉伸面的结果如下：

![face 1](/files/inline-images/td_extrudeEntities_Face1.png)请注意，这里每个面都是单独拉伸的。如果您将所有需要的面放入一个数组并以这种方式执行拉伸，结果将有所不同（见下文）。

```
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](/files/inline-images/td_extrudeEntities_Face2.png)此网格具有两个连接面，在这种情况下，挤出生成一个联合挤出面，这与之前的示例相反，在之前的示例中，每个面都是单独挤出的，因此，挤出面也是独立的。

## 今天就开始行动

**免费试用 ODA 软件 60 天。  
无风险，无需信用卡。**

[免费试用](https://www.opendesign.com/cn/free-trial)
