OdBmFillPatternElem 通过 OdBmFace->OdBmGFilling->PatternId 绑定到面。因此,在 BrepRenderer 中遍历面时,对于每个面,我们通过 IBrFace->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。
最后,我们有带有 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();
}
}
最后,所有必需的数据都已计算并设置,以便可以渲染填充图案。