[返回博客](/cn/blog) # 使用 B-Rep Builder 创建 ACIS Nurbs 曲面

Oleksandr Bryzghalin 十二月 05, 2017 [\#rvt](/cn/blog/tag/rvt) [\#rfa](/cn/blog/tag/rfa) [\#getting started](/cn/blog/tag/getting-started) [\#Example](/cn/blog/tag/example)

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

使用 Teigha，您可以使用 B-Rep Builder 接口创建 ACIS NURBS 曲面。目前 Teigha 有两种 B-Rep Builder 实现：一种在 Teigha Kernel 中名为 AcisBrepBuilder，另一种在 Teigha BIM 中名为 BmBrepBuilder。

尽管目前 AcisBrepBuilder 的功能有限（您只能创建一个面，并且边/共边几何体分别仅通过 OdGeNurbCurve3d/OdGeNurbCurve2d 设置），但其功能可以扩展，例如，用于将 3D 模型从一种格式转换为另一种格式。例如，要加载源文件，然后使用 Br 类获取和创建实体，您可以使用 AcisBrepBuilder 和 Br 实体作为输入。调用 OdRxObjectPtr OdBrepBuilder :: finish () 后，您将获得一个新的 ACIS 实体。

#### 这是如何工作的？

假设您正在使用 ACIS 内核。首先，您需要创建 AcisBrepBuilder。通常，您可以使用构造函数，然后 AcisBrepBuilder 的创建如下所示：

```
OdBrepBuilder brepBuilder;
new AcisBrepBuilder(brepType);

```

其中 brepType 是正在创建的实体的类型。目前它仅在 BmBrepBuilder 中使用，可以取以下值：

- kOpenShell — 如果输出几何体是开放壳。
- kSolid — 如果输出几何体是实体。
- kVoid — 如果输出几何体是空洞（即，反向实体）。

接下来，使用此方法设置将用于测试输入数据的公差：

```
void setValidatorParameters(BrepValidator* vparams)

```

其中 BrepValidator\* vparams 是指向包含必要公差的对象的指针。对于每个 BrepBuilder，您可以指定自己的类来包含所有必要的公差。

为了便于使用，BrepBuilder 的初始化已移至服务中，要初始化 AcisBrepBuilder，您只需调用此方法：

```
OdResult OdModelerGeometryCreatorABImpl::initBrepBuilder(OdBrepBuilder& brepBuilder, BrepType, OdGeTol& resTol, OdGeTol& distancetol)

```

#### 现在您可以直接进入 ACIS 模型的创建。

OdBrepBuilder 接口包含许多方法，要创建 ACIS 模型，您至少必须定义一个面，它是一个曲面，并且上面有一个修剪环。要设置面，请使用此方法：

```
BRepBuilderGeometryId addFace(OdGeSurface* pSurf, EntityDirection faceDirection)

```

第一个参数是指向曲面的指针；第二个参数是面相对于曲面的方向（同向或不同向）。因此，对于 AcisBrepBuilder 曲面，应该有一个 OdGeNurbSurface。作为输出，您将获得面 ID，该 ID 将用于稍后创建修剪环。它使用此方法创建：

```
BRepBuilderGeometryId OdBrepBuilder::addLoop(BRepBuilderGeometryId& faceId) 

```

在这里，输入参数是面标识符，因此修剪环将位于此特定面上。通常，一个面可以有多个环，例如，如果您需要在面上打一个孔，则可以创建多个环。

接下来指定环的几何形状。为此，使用以下方法：

```
BRepBuilderGeometryId OdBrepBuilder::addEdge(OdGeCurve3d* pCurveForEdge)
BRepBuilderGeometryId OdBrepBuilder::addCoedge(BRepBuilderGeometryId& loopId, BRepBuilderGeometryId& edgeId, EntityDirection codgeDirection = kForward, OdGeCurve2d* pParCur = NULL)

```

第一个方法创建具有给定几何形状的边，第二个方法创建共边。首先，创建一条边。为此，将边的几何形状设置为指向 3D 曲线的指针。在 AcisBrepBuilder 中，几何边使用 OdGeNubrCurve3d 指定。作为输出，获取创建共边所需的边 ID。调用 OdBrepBuilder::addCoedge 方法，并向其传递一个环 ID、一个边 ID、一个相对于边的方向，以及一个将实线区间映射到 2D 实向量空间（参数空间）的参数曲线。必须满足以下条件：参数曲线的区间必须与边上 3D 曲线的区间相同。因此，我们设置了创建面所需的最低要求。现在调用 OdRxObjectPtr OdBrepBuilder::finish () 并获取实体。

考虑使用 OdWriteEx 中的示例，通过 AcisBrepBuilder 创建 NURBS 曲面。以下是关键部分：

1\. 初始化。

```
/********************************************************************/
/* BrepBuilder initialization                                       */
/********************************************************************/
OdDbHostAppServices *pService = pDb->appServices();
BrepType bbType = kOpenShell;
OdBrepBuilder brep;
pService->brepBuilder(brep, bbType);

```

2\. 创建边/共边的几何体。下面没有包含所有代码，但曲线可以手动创建，也可以借助 Br 类获取。

```
OdGeNurbSurface nurbSurf;
OdArray<OdArray< OdGeNurbCurve3d*> > arrLoops;    //Array of loops
OdArray<OdArray< OdGeNurbCurve2d*> > arrLoopsPar; //Their parametric curves
OdDbNurbSurfacePtr pSurface = OdDbNurbSurface::createObject();//Resulting acis nurb surface
OdArray< OdGeNurbCurve3d*> currentLoop;    //The edge array of current loop 
OdArray< OdGeNurbCurve2d*> currentParLoop; //The coedges geometry of current loop 

```

3\. 创建 ACIS 模型的拓扑。在其上创建一个面和一个修剪环。修剪环由共边创建。之后，调用 brep.finish ()。

```
/********************************************************************/
/* Create NURBS Surface by BrepBuilder                              */
/********************************************************************/
try
{ 
  BRepBuilderGeometryId faceId = brep.addFace(&nurbSurf, OdBrepBuilder::kForward);
  ODA_ASSERT(arrLoops.size() == arrLoopsPar.size());
  for (unsigned int i = 0; i < arrLoops.size(); i++)
  {
    OdArray< OdGeNurbCurve3d*> currentLoop = arrLoops[i];
    OdArray< OdGeNurbCurve2d*> currentParLoop = arrLoopsPar[i];
    ODA_ASSERT(currentLoop.size() == currentParLoop.size());
    BRepBuilderGeometryId LoopId = brep.addLoop(faceId);
    for (unsigned int j = 0; j < currentLoop.length(); j++)
    {
      BRepBuilderGeometryId edgeId = brep.addEdge(currentLoop[j]);
      brep.addCoedge(LoopId, edgeId, OdBrepBuilder::kForward, currentParLoop[j]);
    }
  }
  OdRxObjectPtr pModelGeometry;
  pModelGeometry = brep.finish();
  pSurface->setBody(pModelGeometry);
}
catch (const OdError& e)
{
  odPrintConsoleString(L"\n\nException occurred: %ls\n", e.description().c_str());
}

```

完整的示例可以在您安装 Teigha 的 Examples 文件夹中的 OdWriteEx 示例中找到。

## 今天就开始行动

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

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