[返回博客](/cn/blog) # Teigha BIM：填充图案简介 \[第一部分\]

Daniil Zhirnov 七月 04, 2017 [\#rvt](/cn/blog/tag/rvt) [\#rfa](/cn/blog/tag/rfa) [\#Example](/cn/blog/tag/example)

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

OdBmFillPatternElem 通过 OdBmFace-&gt;OdBmGFilling-&gt;PatternId 绑定到面。因此，在 BrepRenderer 中遍历面时，对于每个面，我们通过 IBrFace-&gt;getFillPatternId() 获取一个 OdBmFillPatternElem ID。请参阅下面的代码：

```
OdUInt64 id;
if (face.getFillPatternId(id))
{
  if (pWd)
  {
    OdDbStub* pStub = pWd->context()->getStubByID(id);
    if (pStub)
    {
      OdGiDrawablePtr pDrawable = pWd->context()->openDrawable(pStub);
      if (!pDrawable.isNull())
      {
        pDrawable->setAtribute(&pWd->subEntityTraits());
      }
    }
  }
}

```

由于不能使用 BIM 特定类，此 ID 通过 GiContext 作为可绘制对象打开，并通过 setAttributes() 提供实体特性。这导致调用 OdBmFillPatternElem:: subSetAttributes(OdGiDrawableTraits\* pDrwTraits)，该调用负责提供正确的 OdGiFill 特性属性。这可以示意性地表示为：

```
if (m_pFill.isNull())
{
  m_pFill = OdGiHatchPattern::createObject();
  const OdBmFillPattern* pFillPattern = getFillPattern().get();
  if (pFillPattern)
  {
    // Do OdBmFillPattern to OdGiHatchPattern cobversion
  }
}

OdGiSubEntityTraits* pSub = static_cast< OdGiSubEntityTraits* >(pDrwTraits);
pSub->setFill(m_pFill);
if (m_pFill->patternLines().size() == 0)
{
  // Set solid fill attributes
}
```

OdGiHatchPatternPtr m\_pFill 作为成员实现，因此在后续调用中不再需要 OdBmFillPattern 到 OdGiHatchPattern 的转换。除了可以以新格式存储的简单图案外，转换非常简单。

```
double dx, d0 = (*i)->getDeltasItem(0);
double dy, d1 = (*i)->getDeltasItem(1);
if(OdZero(d0))
{
  double sina = fabs(sin(pl->m_dLineAngle));
  double cosa = fabs(cos(pl->m_dLineAngle));

  if (sina > cosa)
  {
    dx = d1 / sina;
    dy = 0.0;
  }
  else
  {
    dx = 0.0;
    dy = d1 / cosa;
  }
}
else
{
  dx = d0;
  dy = d1;
}
``` 

如果 DeltasItem\[0\] 为零，我们需要根据给定的 a 和 d = DeltasItem\[1\] 计算 x、y。

![image1](/files/inline-images/image004_0.png)最后，我们有带有 OdGiHatchPattern 的实体特性，它们被设置为填充属性，通常描述填充结构。这不足以正确渲染 FillPattern；还需要提供 OdBmFillPatternPlacer 数据，它提供面特定的填充起点和填充方向。因此，可能有许多面引用相同的 OdBmFillPatternElem，但绘制方式不同。OdGiFaceData 用于将 OdBmFillPatternPlacer 属性传递给 Gi 子系统。IBrFace 已扩展以支持 BrepRenderer 中的此属性访问。

```
OdGiFaceData FaceData;
OdGePoint2dArray fillOriginArr;
OdGeVector2dArray fillDirectionArr;
{
  OdGePoint2d faceFillOrigin;
  OdGeVector2d faceFillDirection;
  if (face.getFillingAttributes(faceFillOrigin, faceFillDirection))
  {
    fillOriginArr.resize(FAceList.size(), faceFillOrigin);
    FaceData.setFillOrigins(FillOriginArr.getPtr());

    fillDirectionArr.resize(FaceList.size(), faceFillDirection);
    FaceData.setFillDirections(fillDirectionArr.getPtr());
  }
}
```

Teigha BIM 对位于面平面上的填充图案使用 2D 坐标系。因此，每个面都有自己的坐标系，在计算填充原点 3D 坐标时必须考虑到这一点。此坐标系保存为相应 OdBmPlane 的 XVector、YVector 和 Origin，因此有助于使转换变得简单。

```
OdBmFillPatternPlacerPtr pPlacer = pFilling->getPlacer();
if (!pPlacer.isNull())
{
  OdGePoint2d baseOrigin = pFilling->getPlacer();
  OdBmPlanePtr pPlane = OdBmPlane::cast(((OdBmFace*)m_pImp)->getSurface());
  if (!pPlane.isNull())
  {
    origin = (pPlane->getOrigin() + baseOrigin.x * pPlane->getXVector() + baseOrigin.y * pPlane->getYVector()).convert2d();
  }
}
```

最后，所有必需的数据都已计算并设置，以便可以渲染填充图案。

## 今天就开始行动

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

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