By Adam Nagy
Entities like windows, doors can have various sub parts like frame, glass, etc. If you want to get back those parts separately then you can create your own class derived from AecStreamAcad and collect each body there.
In the below sample we also collect the color of each body and then use that to change the color of the mass entity we create from them.
class AecStreamCollectColors : public AecStreamAcad
{
public:
AcArray<Body> bodies;
AcArray<AcCmColor> colors;
AecStreamCollectColors(AcDbDatabase* pdb)
:AecStreamAcad(pdb)
{
}
virtual void
streamWcs(const AcGePoint3d& start, const AcGePoint3d& end)
{
}
virtual void
streamWcs(Body& body, AecStreamColorToPropsMap* colorToPropsMap)
{
bodies.append(body);
colors.append(this->trueColor());
}
};
void CollectBodiesWithColor()
{
Acad::ErrorStatus es;
AcDbDatabase* pDb =
acdbHostApplicationServices()->workingDatabase();
// Select an architectural entity
AecUiPrEntitySetSingle prEnt(L"Select an architectural entity");
prEnt.addAllowedClass(AecDbGeo::desc());
if(prEnt.go() != AecUiPr::kOk)
return;
AcDbObjectPointer<AecDbGeo>
pEnt(prEnt.objectId(), AcDb::kForRead);
if (Acad::eOk != pEnt.openStatus())
return;
AecStreamCollectColors stream(pDb);
AcDbObjectId modelViewSetId =
AecDictDispRepSet::getStandardViewSet(
AecDictDispRepSet::standardModelName(), pDb);
AcDbObjectPointer<AecDbDispRepSet>
viewSet(modelViewSetId, AcDb::kForRead);
if (Acad::eOk != viewSet.openStatus())
return;
stream.pushViewSet(viewSet.object());
stream.stream(pEnt.object());
for (int i = 0; i < stream.bodies.length(); i++)
{
Body & b = stream.bodies.at(i);
acutPrintf(L"Face count = %d\n", b.faceCount());
AecDbMassElem *pMass = AecDbMassElem::create(AecMassElem::kBrep);
pMass->setBody(b);
AcCmColor c = stream.colors.at(i);
pMass->setColor(c);
es = Aec::addToModelSpaceAndClose(pMass, pDb);
}
}
If you wanted to collect the bodies of the components based on their material then you could use the existing AecStreamCollectMaterials class for that.
void CollectBodiesWithMaterial()
{
Acad::ErrorStatus es;
AcDbDatabase * pDb =
acdbHostApplicationServices()->workingDatabase();
// Select an architectural entity
AecUiPrEntitySetSingle prEnt(L"Select an architectural entity");
prEnt.addAllowedClass(AecDbGeo::desc());
if(AecUiPr::kOk != prEnt.go())
return;
AcDbObjectPointer<AecDbGeo>
pEnt(prEnt.objectId(), AcDb::kForRead);
if (pEnt.openStatus() != Acad::eOk)
return;
AecStreamCollectMaterials stream(pDb);
stream.setCombineBodies(true);
AcDbObjectId modelViewSetId =
AecDictDispRepSet::getStandardViewSet(
AecDictDispRepSet::standardModelName(), pDb);
AcDbObjectPointer<AecDbDispRepSet>
viewSet(modelViewSetId, AcDb::kForRead);
if (Acad::eOk != viewSet.openStatus())
return;
stream.pushViewSet(viewSet.object());
stream.stream(pEnt.object());
for (int i = 0; i < stream.materialCount(); i++)
{
AcDbObjectId id = stream.getMaterialAt(i);
Body * body;
stream.getBody(id, body);
acutPrintf(L"Face count = %d\n", body->faceCount());
AecDbMassElem *pMass = AecDbMassElem::create(AecMassElem::kBrep);
pMass->setBody(*body);
es = Aec::addToModelSpaceAndClose(pMass, pDb);
}
}