This article explains how to convert OdDb entities
based on B-Reps (e.g. OdDb3dSolid
, OdDbRegion
, etc.) and SAT data to BimRv DirectShape entities.
Just like any other conversion, the conversion is performed using
OdBrepBuilderFiller
.
However, OdDb entity topology is very different from a DirectShape entity.
DirectShape doesn't allow for periodic faces and edges, so entities such as a full sphere
or a full circle are impossible.
Moreover, OdDb topology can have separation loops so there are no seam edges,
and complex fixes are required.
The conversion is performed using intermediate conversion to ODA Solid Modeler's OdMdBody
.
OdMdBody
has restrictions between OdDb and DirectShape; while it allows for periodic faces and edges, it forbids separation loops and requires seam edges.
DirectShape doesn't have colors but materials instead. OdDb face materials
are not supported currently, but face colors are supported in both RGB and color indices.
To convert them, pass an instance of
OdBaseMaterialAndColorHelper
to
OdBrepBuilderFiller
.
You can use OdDb2BmMaterialAndColorHelper
to convert entities from a .dwg file to OdMdBody
and from OdMdBody
to DirectShape.
If you work with SAT data, you can use OdSat2MdForBmMaterialAndColorHelper
and
OdMd2BmFromSatMaterialAndColorHelper
for conversion from SAT to OdMdBody
and from OdMdBody
to DirectShape respectively.
Face color is converted to OdMdBody
as-is. A new material with this color is created for the DirectShape.
The input entity color is passed to the DirectShape directly, bypassing OdMdBody
.
The following section contains an example conversion to DirectShape.
OdBrBrep
from an input file.
brep()
method:
OdDbDatabasePtr pDwgDb = pHostApp->readFile(fileName);
OdDbBlockTableRecordPtr pMs = pDwgDb->getModelSpaceId().safeOpenObject(OdDb::kForWrite);
for (OdDbObjectIteratorPtr pObjIt = pMs->newIterator(); !pObjIt->done(); pObjIt->step())
{
OdDbEntityPtr inputEntity = pObjIt->entity();
if (!inputEntity.isNull())
{
OdBrBrep brep;
BrepType bType = kOpenShell;
if (inputEntity->isA() == OdDbRegion::desc())
{
OdDbRegionPtr pBody = inputEntity;
pBody->brep(brep);
}
/*other geometry types of OdDbEntity*/
/*conversion*/
}
}
For SAT files, use the
acisIn()
method to get an OdDbEntity
or use
ISATConverter
:
for (unsigned idx = 0; idx < out.size(); ++idx)
{
OdBrBrep brep;
ISATConverter* pIS = out[idx];
brep.set(pIS->getIBr());
/*conversion*/
}
OdBrBrep
to OdMdBody
using OdBrepBuilderFiller
:
OdBrepBuilder mdBrepBuilder;
std::unique_ptr attribSetter(createDwgAttribSetter());
initMDBrepBuilder(mdBrepBuilder, bType, attribSetter.get());
OdGeMatrix3d mx;
bool hasTransform = brep.getTransformation(mx);
OdBrepBuilderFiller BBFiller;
BBFiller.params().setupFor(OdBrepBuilderFillerParams::kBrepAcisDwg, OdBrepBuilderFillerParams::kBrepMd);
OdResult res = BBFiller.initFrom(mdBrepBuilder, brep);
if (res == eOk)
{
mdBrepBuilder.enableValidator(false);
OdMdBodyResultPtr pMdBody;
try
{
pMdBody = OdMdBodyResult::cast(mdBrepBuilder.finish());
}
catch (...)
{
res = eGeneralModelingFailure;
}
}
OdMdBody
to the BimRv format and get a new OdBrBrep
:
OdBrBrep mdBrep;
if (eOk == res && !pMdBody.isNull())
{
if (hasTransform)
res = transformMdBody(pMdBody, mx);
if (eOk == res)
{
res = convertToBimRvFormat(pMdBody);
if (eOk == res)
{
res = getBrepFromMdBody(pMdBody, mdBrep);
}
}
}
OdBrBrep
to DirectShape and add it to a BimRv database:
OdBrepBuilder bmBrepBuilder;
res = pBmDb->appServices()->brepBuilder(bmBrepBuilder, bType);
if (res == eOk)
{
BBFiller.params().setupFor(OdBrepBuilderFillerParams::kBrepAcisDwg, pDwgDb, pBmDb);
res = BBFiller.initFrom(bmBrepBuilder, mdBrep, bmMaterialHelper);
if (res == eOk)
{
try
{
OdBmGeometryPtr resultGeometry = OdBmGeometry::cast(bmBrepBuilder.finish());
if (!resultGeometry.isNull())
{
OdArray aFaces;
resultGeometry->getFaces(aFaces);
OdArray aEdges;
resultGeometry->getEdges(aEdges);
if (aFaces.size() != 0 || aEdges.size() != 0)
{
ODBM_TRANSACTION_BEGIN(t, pBmDb)
t.start();
OdBmGNodePtrArray nodes;
nodes.append(resultGeometry);
OdBmDirectShapePtr pDirectShape = OdBmDirectShape::createObject();
OdBmObjectId retId = pBmDb->addElement(pDirectShape);
pDirectShape->setOwningElementId(pBmDb->getOwnerFamilyId());
res = pDirectShape->setShape(nodes);
t.commit();
ODBM_TRANSACTION_END()
}
}
}
catch (...)
{
res = eGeneralModelingFailure;
}
}
}
You can find examples in the DwgDirectShapeImportEx
and SatDirectShapeImportEx
samples, which
are provided with the archives and can be found in the CommonApplications/BimRv
directory.
These examples contain code that convert OdDb entities that are based on B-Rep entities in .dwg files
or SAT data in SAT files to DirectShapes in RVT or RFA files.
They require an empty RFA or RVT file to get the BimRv's input database.
Copyright © 2002 – 2020. Open Design Alliance. All rights reserved.
|