void FeaturesPlugin_BooleanCommon::execute()
{
ListOfShape aPlanes;
- ObjectHierarchy anObjects, aTools;
+ GeomAPI_ShapeHierarchy anObjects, aTools;
bool isSimpleMode = false;
!processAttribute(TOOL_LIST_ID(), aTools, aPlanes))
return;
- if (anObjects.IsEmpty() || (!isSimpleMode && aTools.IsEmpty() && aPlanes.empty())) {
+ if (anObjects.empty() || (!isSimpleMode && aTools.empty() && aPlanes.empty())) {
std::string aFeatureError = "Error: Not enough objects for boolean operation.";
setError(aFeatureError);
return;
ListOfShape aResultShapesList;
if (isSimpleMode) {
- ObjectHierarchy::Iterator anObjectsIt = anObjects.Begin();
+ GeomAPI_ShapeHierarchy::iterator anObjectsIt = anObjects.begin();
GeomShapePtr aShape = *anObjectsIt;
- for (++anObjectsIt; anObjectsIt != anObjects.End(); ++anObjectsIt) {
+ for (++anObjectsIt; anObjectsIt != anObjects.end(); ++anObjectsIt) {
std::shared_ptr<GeomAlgoAPI_Boolean> aCommonAlgo(
new GeomAlgoAPI_Boolean(aShape,
*anObjectsIt,
std::shared_ptr<ModelAPI_ResultBody> aResultBody =
document()->createBody(data(), aResultIndex);
- ListOfShape anObjectList = anObjects.Objects();
+ ListOfShape anObjectList = anObjects.objects();
ListOfShape aToolsList;
FeaturesPlugin_Tools::loadModifiedShapes(aResultBody,
anObjectList,
}
bool isOk = true;
- for (ObjectHierarchy::Iterator anObjectsIt = anObjects.Begin();
- anObjectsIt != anObjects.End() && isOk;
+ for (GeomAPI_ShapeHierarchy::iterator anObjectsIt = anObjects.begin();
+ anObjectsIt != anObjects.end() && isOk;
++anObjectsIt)
{
GeomShapePtr anObject = *anObjectsIt;
- GeomShapePtr aParent = anObjects.Parent(anObject);
+ GeomShapePtr aParent = anObjects.parent(anObject);
if (aParent) {
GeomAPI_Shape::ShapeType aShapeType = aParent->shapeType();
if (aShapeType == GeomAPI_Shape::COMPOUND) {
// Compound handling
isOk = processCompound(GeomAlgoAPI_Tools::BOOL_COMMON,
- anObjects, aParent, aTools.Objects(),
+ anObjects, aParent, aTools.objects(),
aResultIndex, aResultBaseAlgoList, aResultShapesList,
aResultCompound);
}
else if (aShapeType == GeomAPI_Shape::COMPSOLID) {
// Compsolid handling
isOk = processCompsolid(GeomAlgoAPI_Tools::BOOL_COMMON,
- anObjects, aParent, aTools.Objects(), ListOfShape(),
+ anObjects, aParent, aTools.objects(), ListOfShape(),
aResultIndex, aResultBaseAlgoList, aResultShapesList,
aResultCompound);
}
} else {
// process object as is
isOk = processObject(GeomAlgoAPI_Tools::BOOL_COMMON,
- anObject, aTools.Objects(), aPlanes,
+ anObject, aTools.objects(), aPlanes,
aResultIndex, aResultBaseAlgoList, aResultShapesList,
aResultCompound);
}
}
- storeResult(anObjects.Objects(), aTools.Objects(), aResultCompound, aResultIndex,
+ storeResult(anObjects.objects(), aTools.objects(), aResultCompound, aResultIndex,
aMakeShapeList, aResultBaseAlgoList);
}
if (!aResultCompound)
aResultCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList);
FeaturesPlugin_Tools::loadDeletedShapes(aResultBaseAlgoList,
- aTools.Objects(),
+ aTools.objects(),
aResultCompound);
// remove the rest results if there were produced in the previous pass
//==================================================================================================
void FeaturesPlugin_BooleanCut::execute()
{
- ObjectHierarchy anObjects, aTools;
+ GeomAPI_ShapeHierarchy anObjects, aTools;
ListOfShape aPlanes;
// Getting objects and tools
int aResultIndex = 0;
- if(anObjects.IsEmpty() || aTools.IsEmpty()) {
+ if(anObjects.empty() || aTools.empty()) {
std::string aFeatureError = "Error: Not enough objects for boolean operation.";
setError(aFeatureError);
return;
// For solids cut each object with all tools.
bool isOk = true;
- for (ObjectHierarchy::Iterator anObjectsIt = anObjects.Begin();
- anObjectsIt != anObjects.End() && isOk;
+ for (GeomAPI_ShapeHierarchy::iterator anObjectsIt = anObjects.begin();
+ anObjectsIt != anObjects.end() && isOk;
++anObjectsIt) {
GeomShapePtr anObject = *anObjectsIt;
- GeomShapePtr aParent = anObjects.Parent(anObject);
+ GeomShapePtr aParent = anObjects.parent(anObject);
if (aParent) {
GeomAPI_Shape::ShapeType aShapeType = aParent->shapeType();
if (aShapeType == GeomAPI_Shape::COMPOUND) {
// Compound handling
isOk = processCompound(GeomAlgoAPI_Tools::BOOL_CUT,
- anObjects, aParent, aTools.Objects(),
+ anObjects, aParent, aTools.objects(),
aResultIndex, aResultBaseAlgoList, aResultShapesList,
aResultCompound);
}
else if (aShapeType == GeomAPI_Shape::COMPSOLID) {
// Compsolid handling
isOk = processCompsolid(GeomAlgoAPI_Tools::BOOL_CUT,
- anObjects, aParent, aTools.Objects(), ListOfShape(),
+ anObjects, aParent, aTools.objects(), ListOfShape(),
aResultIndex, aResultBaseAlgoList, aResultShapesList,
aResultCompound);
}
} else {
// process object as is
isOk = processObject(GeomAlgoAPI_Tools::BOOL_CUT,
- anObject, aTools.Objects(), aPlanes,
+ anObject, aTools.objects(), aPlanes,
aResultIndex, aResultBaseAlgoList, aResultShapesList,
aResultCompound);
}
}
- storeResult(anObjects.Objects(), aTools.Objects(), aResultCompound, aResultIndex,
+ storeResult(anObjects.objects(), aTools.objects(), aResultCompound, aResultIndex,
aMakeShapeList, aResultBaseAlgoList);
// Store deleted shapes after all results has been proceeded. This is to avoid issue when in one
if (!aResultCompound)
aResultCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList);
FeaturesPlugin_Tools::loadDeletedShapes(aResultBaseAlgoList,
- aTools.Objects(),
+ aTools.objects(),
aResultCompound);
// remove the rest results if there were produced in the previous pass
void FeaturesPlugin_BooleanFill::execute()
{
std::string anError;
- ObjectHierarchy anObjects, aTools;
+ GeomAPI_ShapeHierarchy anObjects, aTools;
ListOfShape aPlanes;
// Getting objects.
int aResultIndex = 0;
- if (anObjects.IsEmpty() || (aTools.IsEmpty() && aPlanes.empty())) {
+ if (anObjects.empty() || (aTools.empty() && aPlanes.empty())) {
std::string aFeatureError = "Error: Not enough objects for boolean operation.";
setError(aFeatureError);
return;
// For solids cut each object with all tools.
bool isOk = true;
- for (ObjectHierarchy::Iterator anObjectsIt = anObjects.Begin();
- anObjectsIt != anObjects.End() && isOk;
+ for (GeomAPI_ShapeHierarchy::iterator anObjectsIt = anObjects.begin();
+ anObjectsIt != anObjects.end() && isOk;
++anObjectsIt) {
GeomShapePtr anObject = *anObjectsIt;
- GeomShapePtr aParent = anObjects.Parent(anObject, false);
+ GeomShapePtr aParent = anObjects.parent(anObject, false);
if (aParent && aParent->shapeType() == GeomAPI_Shape::COMPSOLID) {
// get parent once again to mark it and the subs as processed
- aParent = anObjects.Parent(anObject);
+ aParent = anObjects.parent(anObject);
// compsolid handling
isOk = processCompsolid(GeomAlgoAPI_Tools::BOOL_PARTITION,
- anObjects, aParent, aTools.Objects(), aPlanes,
+ anObjects, aParent, aTools.objects(), aPlanes,
aResultIndex, aResultBaseAlgoList, aResultShapesList,
aResultCompound);
} else {
// process object as is
isOk = processObject(GeomAlgoAPI_Tools::BOOL_PARTITION,
- anObject, aTools.Objects(), aPlanes,
+ anObject, aTools.objects(), aPlanes,
aResultIndex, aResultBaseAlgoList, aResultShapesList,
aResultCompound);
}
}
- storeResult(anObjects.Objects(), aTools.Objects(), aResultCompound, aResultIndex,
+ storeResult(anObjects.objects(), aTools.objects(), aResultCompound, aResultIndex,
aMakeShapeList, aResultBaseAlgoList);
// Store deleted shapes after all results has been proceeded. This is to avoid issue when in one
if (!aResultCompound)
aResultCompound = GeomAlgoAPI_CompoundBuilder::compound(aResultShapesList);
FeaturesPlugin_Tools::loadDeletedShapes(aResultBaseAlgoList,
- aTools.Objects(),
+ aTools.objects(),
aResultCompound);
// remove the rest results if there were produced in the previous pass
void FeaturesPlugin_BooleanFuse::execute()
{
std::string anError;
- ObjectHierarchy anObjectsHierarchy, aToolsHierarchy;
+ GeomAPI_ShapeHierarchy anObjectsHierarchy, aToolsHierarchy;
ListOfShape aPlanes;
bool isSimpleCreation = false;
ListOfShape anObjects, aTools, anEdgesAndFaces;
// all objects except edges and faces
- anObjectsHierarchy.ObjectsByType(anEdgesAndFaces, anObjects,
+ anObjectsHierarchy.objectsByType(anEdgesAndFaces, anObjects,
GeomAPI_Shape::FACE, GeomAPI_Shape::EDGE);
- aToolsHierarchy.ObjectsByType(anEdgesAndFaces, aTools,
+ aToolsHierarchy.objectsByType(anEdgesAndFaces, aTools,
GeomAPI_Shape::FACE, GeomAPI_Shape::EDGE);
if ((anObjects.size() + aTools.size() + anEdgesAndFaces.size()) < 2) {
// in boolean operation and will be added to result.
bool isProcessCompsolid = !isSimpleCreation || !aFuseVersion.empty();
ListOfShape aShapesToAdd;
- for (ObjectHierarchy::Iterator anObjectsIt = anObjectsHierarchy.Begin();
- isProcessCompsolid && anObjectsIt != anObjectsHierarchy.End();
+ for (GeomAPI_ShapeHierarchy::iterator anObjectsIt = anObjectsHierarchy.begin();
+ isProcessCompsolid && anObjectsIt != anObjectsHierarchy.end();
++anObjectsIt) {
GeomShapePtr anObject = *anObjectsIt;
- GeomShapePtr aParent = anObjectsHierarchy.Parent(anObject, false);
+ GeomShapePtr aParent = anObjectsHierarchy.parent(anObject, false);
if (aParent && aParent->shapeType() == GeomAPI_Shape::COMPSOLID) {
// mark all subs of this parent as precessed to avoid handling twice
- aParent = anObjectsHierarchy.Parent(anObject);
+ aParent = anObjectsHierarchy.parent(anObject);
ListOfShape aUsed, aNotUsed;
- anObjectsHierarchy.SplitCompound(aParent, aUsed, aNotUsed);
+ anObjectsHierarchy.splitCompound(aParent, aUsed, aNotUsed);
aShapesToAdd.insert(aShapesToAdd.end(), aNotUsed.begin(), aNotUsed.end());
}
}
void FeaturesPlugin_BooleanSmash::execute()
{
std::string anError;
- ObjectHierarchy anObjectsHistory, aToolsHistory;
+ GeomAPI_ShapeHierarchy anObjectsHistory, aToolsHistory;
ListOfShape aPlanes;
// Getting objects and tools.
int aResultIndex = 0;
- if (anObjectsHistory.IsEmpty() || aToolsHistory.IsEmpty()) {
+ if (anObjectsHistory.empty() || aToolsHistory.empty()) {
std::string aFeatureError = "Error: Not enough objects for boolean operation.";
setError(aFeatureError);
return;
}
// Collecting all shapes which will be smashed.
- ListOfShape aShapesToSmash = anObjectsHistory.Objects();
+ ListOfShape aShapesToSmash = anObjectsHistory.objects();
// List of original shapes for naming.
ListOfShape anOriginalShapes;
anOriginalShapes.insert(anOriginalShapes.end(), aShapesToSmash.begin(), aShapesToSmash.end());
- ListOfShape aTools = aToolsHistory.Objects();
+ ListOfShape aTools = aToolsHistory.objects();
anOriginalShapes.insert(anOriginalShapes.end(), aTools.begin(), aTools.end());
// Collecting solids from compsolids which will not be modified in
// boolean operation and will be added to result.
ListOfShape aShapesToAdd;
- for (ObjectHierarchy::Iterator anIt = anObjectsHistory.Begin();
- anIt != anObjectsHistory.End();
+ for (GeomAPI_ShapeHierarchy::iterator anIt = anObjectsHistory.begin();
+ anIt != anObjectsHistory.end();
++anIt)
{
- GeomShapePtr aParent = anObjectsHistory.Parent(*anIt, false);
+ GeomShapePtr aParent = anObjectsHistory.parent(*anIt, false);
if (aParent) {
anOriginalShapes.push_back(aParent);
ListOfShape aUsed, aNotUsed;
- anObjectsHistory.SplitCompound(aParent, aUsed, aNotUsed);
+ anObjectsHistory.splitCompound(aParent, aUsed, aNotUsed);
aShapesToAdd.insert(aShapesToAdd.end(), aNotUsed.begin(), aNotUsed.end());
// add unused shapes of compounds/compsolids to the history,
// to avoid treating them as unused later when constructing a compound containing
// the result of Smash and all unused sub-shapes of multi-level compounds
for (ListOfShape::iterator anIt = aNotUsed.begin(); anIt != aNotUsed.end(); ++anIt)
- anObjectsHistory.AddObject(*anIt);
+ anObjectsHistory.addObject(*anIt);
}
}
//=================================================================================================
void FeaturesPlugin_Partition::execute()
{
- ObjectHierarchy anObjects;
+ GeomAPI_ShapeHierarchy anObjects;
ListOfShape aPlanes;
// Getting objects.
processAttribute(BASE_OBJECTS_ID(), anObjects, aPlanes);
- if(anObjects.IsEmpty()) {
+ if(anObjects.empty()) {
static const std::string aFeatureError = "Error: No objects for partition.";
setError(aFeatureError);
return;
}
- ListOfShape aBaseObjects = anObjects.Objects();
+ ListOfShape aBaseObjects = anObjects.objects();
aBaseObjects.insert(aBaseObjects.end(), aPlanes.begin(), aPlanes.end());
// resize planes to the bounding box of operated shapes
std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList());
- resizePlanes(anObjects.Objects(), aPlanes, aMakeShapeList);
+ resizePlanes(anObjects.objects(), aPlanes, aMakeShapeList);
// cut unused solids of composolids from the objects of partition
ListOfShape aTargetObjects, anUnusedSubs;
}
GeomShapePtr aResultCompound =
- keepUnusedSubsOfCompound(aFirstShape, anObjects, ObjectHierarchy(), aMakeShapeList);
+ keepUnusedSubsOfCompound(aFirstShape, anObjects, GeomAPI_ShapeHierarchy(), aMakeShapeList);
if (anIt.more()) {
if (aResultCompound->shapeType() != GeomAPI_Shape::COMPOUND) {
}
bool FeaturesPlugin_Partition::cutSubs(
- FeaturesPlugin_Partition::ObjectHierarchy& theHierarchy,
+ GeomAPI_ShapeHierarchy& theHierarchy,
ListOfShape& theUsed,
ListOfShape& theNotUsed,
std::shared_ptr<GeomAlgoAPI_MakeShapeList>& theMakeShapeList,
theUsed.clear();
theNotUsed.clear();
- ObjectHierarchy::Iterator anIt = theHierarchy.Begin();
+ GeomAPI_ShapeHierarchy::iterator anIt = theHierarchy.begin();
// compose a set of tools for the CUT operation:
// find the list of unused subs of the first argument or use itself
ListOfShape aToolsForUsed, aToolsForUnused;
- GeomShapePtr aFirstArgument = theHierarchy.Parent(*anIt, false);
+ GeomShapePtr aFirstArgument = theHierarchy.parent(*anIt, false);
if (aFirstArgument && aFirstArgument->shapeType() == GeomAPI_Shape::COMPSOLID) {
- theHierarchy.SplitCompound(aFirstArgument, theUsed, aToolsForUsed);
+ theHierarchy.splitCompound(aFirstArgument, theUsed, aToolsForUsed);
theNotUsed = aToolsForUsed;
}
else {
// cut subs
bool isOk = true;
- for (++anIt; anIt != theHierarchy.End() && isOk; ++anIt) {
+ for (++anIt; anIt != theHierarchy.end() && isOk; ++anIt) {
ListOfShape aUsed, aNotUsed;
- GeomShapePtr aParent = theHierarchy.Parent(*anIt, false);
+ GeomShapePtr aParent = theHierarchy.parent(*anIt, false);
if (aParent && aParent->shapeType() == GeomAPI_Shape::COMPSOLID) {
- aParent = theHierarchy.Parent(*anIt); // get parent once again to mark its subs as processed
- theHierarchy.SplitCompound(aParent, aUsed, aNotUsed);
+ aParent = theHierarchy.parent(*anIt); // get parent once again to mark its subs as processed
+ theHierarchy.splitCompound(aParent, aUsed, aNotUsed);
}
else
aUsed.push_back(*anIt);
/// Cut all of unused subs of compsolids by the full compsolid of the first selected object,
/// and vice versa, cut all objects of Partition by not used subs of the first selected object.
/// Store results of operation to the separated lists of shapes.
- bool cutSubs(ObjectHierarchy& theHierarchy,
+ bool cutSubs(GeomAPI_ShapeHierarchy& theHierarchy,
ListOfShape& theUsed,
ListOfShape& theNotUsed,
std::shared_ptr<GeomAlgoAPI_MakeShapeList>& theMakeShapeList,
//=================================================================================================
void FeaturesPlugin_Union::execute()
{
- ObjectHierarchy anObjects;
+ GeomAPI_ShapeHierarchy anObjects;
ListOfShape anEmptyList;
// Getting objects.
if (!processAttribute(BASE_OBJECTS_ID(), anObjects, anEmptyList))
return;
- if(anObjects.Objects().size() < 2) {
+ if(anObjects.objects().size() < 2) {
setError("Error: Not enough objects for operation. Should be at least 2.");
return;
}
// Fuse objects.
bool isOk = true;
- for (ObjectHierarchy::Iterator anObjectsIt = anObjects.Begin();
- anObjectsIt != anObjects.End() && isOk;
+ for (GeomAPI_ShapeHierarchy::iterator anObjectsIt = anObjects.begin();
+ anObjectsIt != anObjects.end() && isOk;
++anObjectsIt) {
GeomShapePtr anObject = *anObjectsIt;
- GeomShapePtr aParent = anObjects.Parent(anObject, false);
+ GeomShapePtr aParent = anObjects.parent(anObject, false);
if (aParent && aParent->shapeType() <= GeomAPI_Shape::COMPSOLID) {
// get parent once again to mark it and the subs as processed
- aParent = anObjects.Parent(anObject);
+ aParent = anObjects.parent(anObject);
// compsolid handling
isOk = processCompsolid(GeomAlgoAPI_Tools::BOOL_FUSE,
anObjects, aParent, anEmptyList, anEmptyList,
}
else {
// merge hierarchies of compounds containing objects and tools
- aShape = keepUnusedSubsOfCompound(aCIt.current(), anObjects, ObjectHierarchy(), aMakeShapeList);
+ aShape = keepUnusedSubsOfCompound(aCIt.current(), anObjects, GeomAPI_ShapeHierarchy(),
+ aMakeShapeList);
for (aCIt.next(); aCIt.more(); aCIt.next()) {
std::shared_ptr<GeomAlgoAPI_ShapeBuilder> aBuilder(new GeomAlgoAPI_ShapeBuilder);
aBuilder->add(aShape, aCIt.current());
// Store result and naming.
std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data());
- ListOfShape anObjectsList = anObjects.Objects();
+ ListOfShape anObjectsList = anObjects.objects();
aResultBody->storeModified(anObjectsList.front(), aShape);
for(ListOfShape::const_iterator anIter = anObjectsList.begin();
}
//=================================================================================================
-void FeaturesPlugin_VersionedBoolean::parentForShape(const GeomShapePtr& theShape,
- const ResultPtr& theContext,
- ObjectHierarchy& theShapesHierarchy)
-{
- ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(theContext);
- if (aResCompSolidPtr.get()) {
- std::shared_ptr<GeomAPI_Shape> aContextShape = aResCompSolidPtr->shape();
- if (aContextShape->shapeType() <= GeomAPI_Shape::COMPSOLID) {
- theShapesHierarchy.AddParent(theShape, aContextShape);
- parentForShape(aContextShape, aResCompSolidPtr, theShapesHierarchy);
- }
- }
-}
-
bool FeaturesPlugin_VersionedBoolean::processAttribute(const std::string& theAttributeName,
- ObjectHierarchy& theObjects,
+ GeomAPI_ShapeHierarchy& theObjects,
ListOfShape& thePlanesList)
{
AttributeSelectionListPtr anObjectsSelList = selectionList(theAttributeName);
return false;
}
- theObjects.AddObject(anObject);
+ theObjects.addObject(anObject);
ResultPtr aContext = anObjectAttr->context();
- parentForShape(anObject, aContext, theObjects);
+ ModelAPI_Tools::fillShapeHierarchy(anObject, aContext, theObjects);
}
return true;
}
//=================================================================================================
bool FeaturesPlugin_VersionedBoolean::processCompsolid(
const GeomAlgoAPI_Tools::BOPType theBooleanType,
- ObjectHierarchy& theCompsolidHierarchy,
+ GeomAPI_ShapeHierarchy& theCompsolidHierarchy,
const GeomShapePtr& theCompsolid,
const ListOfShape& theTools,
const ListOfShape& thePlanes,
{
ListOfShape aUsedInOperationSolids;
ListOfShape aNotUsedSolids;
- theCompsolidHierarchy.SplitCompound(theCompsolid, aUsedInOperationSolids, aNotUsedSolids);
+ theCompsolidHierarchy.splitCompound(theCompsolid, aUsedInOperationSolids, aNotUsedSolids);
std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList());
// Add result to not used solids from compsolid.
if (!aNotUsedSolids.empty()) {
- theCompsolidHierarchy.MarkProcessed(aNotUsedSolids);
+ theCompsolidHierarchy.markProcessed(aNotUsedSolids);
ListOfShape aShapesToAdd = aNotUsedSolids;
aShapesToAdd.push_back(aBoolAlgo->shape());
//=================================================================================================
bool FeaturesPlugin_VersionedBoolean::processCompound(
const GeomAlgoAPI_Tools::BOPType theBooleanType,
- ObjectHierarchy& theCompoundHierarchy,
+ GeomAPI_ShapeHierarchy& theCompoundHierarchy,
const GeomShapePtr& theCompound,
const ListOfShape& theTools,
int& theResultIndex,
{
ListOfShape aUsedInOperationShapes;
ListOfShape aNotUsedShapes;
- theCompoundHierarchy.SplitCompound(theCompound, aUsedInOperationShapes, aNotUsedShapes);
+ theCompoundHierarchy.splitCompound(theCompound, aUsedInOperationShapes, aNotUsedShapes);
if (theResultCompound) {
// Not necessary to keep all subs of the current compound,
// all unused solids are already stored in the result compound.
// Add result to not used shape from compound.
if (!aNotUsedShapes.empty()) {
- theCompoundHierarchy.MarkProcessed(aNotUsedShapes);
+ theCompoundHierarchy.markProcessed(aNotUsedShapes);
ListOfShape aShapesForResult = aNotUsedShapes;
if (aResultShape->shapeType() == GeomAPI_Shape::COMPOUND) {
//==================================================================================================
GeomShapePtr FeaturesPlugin_VersionedBoolean::keepUnusedSubsOfCompound(
const GeomShapePtr& theResult,
- const ObjectHierarchy& theObjectsHierarchy,
- const ObjectHierarchy& theToolsHierarchy,
+ const GeomAPI_ShapeHierarchy& theObjectsHierarchy,
+ const GeomAPI_ShapeHierarchy& theToolsHierarchy,
std::shared_ptr<GeomAlgoAPI_MakeShapeList> theMakeShapeList)
{
ListOfShape aCompounds;
- theObjectsHierarchy.CompoundsOfUnusedObjects(aCompounds);
- theToolsHierarchy.CompoundsOfUnusedObjects(aCompounds);
+ theObjectsHierarchy.compoundsOfUnusedObjects(aCompounds);
+ theToolsHierarchy.compoundsOfUnusedObjects(aCompounds);
GeomShapePtr aResultShape = theResult;
if (!aCompounds.empty()) {
*anIt = aTool;
}
}
-
-//=================================================================================================
-
-void FeaturesPlugin_VersionedBoolean::ObjectHierarchy::AddObject(const GeomShapePtr& theObject)
-{
- myObjects.push_back(theObject);
-}
-
-void FeaturesPlugin_VersionedBoolean::ObjectHierarchy::AddParent(const GeomShapePtr& theShape,
- const GeomShapePtr& theParent)
-{
- myParent[theShape] = theParent;
-
- MapShapeToIndex::iterator aFound = myParentIndices.find(theParent);
- size_t anIndex = myParentIndices.size();
- if (aFound == myParentIndices.end()) {
- myParentIndices[theParent] = anIndex;
- mySubshapes.push_back(ShapeAndSubshapes(theParent, ListOfShape()));
- } else
- anIndex = aFound->second;
-
- mySubshapes[anIndex].second.push_back(theShape);
-}
-
-GeomShapePtr FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Parent(const GeomShapePtr& theShape,
- bool theMarkProcessed)
-{
- MapShapeToParent::const_iterator aFound = myParent.find(theShape);
- GeomShapePtr aParent;
- if (aFound != myParent.end()) {
- aParent = aFound->second;
- if (theMarkProcessed) {
- // mark the parent and all its subs as processed by Boolean algorithm
- myProcessedObjects.insert(aParent);
- const ListOfShape& aSubs = mySubshapes[myParentIndices[aParent]].second;
- for (ListOfShape::const_iterator anIt = aSubs.begin(); anIt != aSubs.end(); ++anIt)
- myProcessedObjects.insert(*anIt);
- }
- }
- return aParent;
-}
-
-void FeaturesPlugin_VersionedBoolean::ObjectHierarchy::MarkProcessed(const GeomShapePtr& theShape)
-{
- myProcessedObjects.insert(theShape);
-}
-
-void FeaturesPlugin_VersionedBoolean::ObjectHierarchy::MarkProcessed(const ListOfShape& theShapes)
-{
- for (ListOfShape::const_iterator anIt = theShapes.begin(); anIt != theShapes.end(); ++anIt)
- MarkProcessed(*anIt);
-}
-
-void FeaturesPlugin_VersionedBoolean::ObjectHierarchy::ObjectsByType(
- ListOfShape& theShapesByType,
- ListOfShape& theOtherShapes,
- const GeomAPI_Shape::ShapeType theMinType,
- const GeomAPI_Shape::ShapeType theMaxType) const
-{
- if (theMinType > theMaxType)
- return ObjectsByType(theShapesByType, theOtherShapes, theMaxType, theMinType);
-
- // no need to select objects if whole range is specified
- if (theMinType == GeomAPI_Shape::COMPOUND && theMaxType == GeomAPI_Shape::SHAPE) {
- theShapesByType.insert(theShapesByType.end(), myObjects.begin(), myObjects.end());
- return;
- }
-
- for (ListOfShape::const_iterator anIt = myObjects.begin(); anIt != myObjects.end(); ++anIt) {
- GeomAPI_Shape::ShapeType aType = (*anIt)->shapeType();
- if (aType >= theMinType && aType <= theMaxType)
- theShapesByType.push_back(*anIt);
- else
- theOtherShapes.push_back(*anIt);
- }
-}
-
-
-void FeaturesPlugin_VersionedBoolean::ObjectHierarchy::SplitCompound(
- const GeomShapePtr& theCompShape,
- ListOfShape& theUsed,
- ListOfShape& theNotUsed) const
-{
- theUsed.clear();
- theNotUsed.clear();
-
- MapShapeToIndex::const_iterator aFoundIndex = myParentIndices.find(theCompShape);
- if (aFoundIndex == myParentIndices.end())
- return; // no such shape
-
- theUsed = mySubshapes[aFoundIndex->second].second;
- SetOfShape aSubsSet;
- aSubsSet.insert(theUsed.begin(), theUsed.end());
-
- for (GeomAPI_ShapeIterator anExp(theCompShape); anExp.more(); anExp.next()) {
- GeomShapePtr aCurrent = anExp.current();
- if (aSubsSet.find(aCurrent) == aSubsSet.end())
- theNotUsed.push_back(aCurrent);
- }
-}
-
-bool FeaturesPlugin_VersionedBoolean::ObjectHierarchy::IsEmpty() const
-{
- return myObjects.empty();
-}
-
-void FeaturesPlugin_VersionedBoolean::ObjectHierarchy::CompoundsOfUnusedObjects(
- ListOfShape& theDestination) const
-{
- SetOfShape aUsedObjects = myProcessedObjects;
- aUsedObjects.insert(myObjects.begin(), myObjects.end());
-
- for (std::vector<ShapeAndSubshapes>::const_iterator anIt = mySubshapes.begin();
- anIt != mySubshapes.end(); ++anIt) {
- MapShapeToParent::const_iterator aParent = myParent.find(anIt->first);
- if ((aParent == myParent.end() || !aParent->second) &&
- anIt->first->shapeType() == GeomAPI_Shape::COMPOUND) {
- // this is a top-level compound
- GeomShapePtr aCompound = collectUnusedSubs(anIt->first, aUsedObjects);
- // add to destination non-empty compounds only
- if (aCompound)
- theDestination.push_back(aCompound);
- }
- }
-}
-
-GeomShapePtr FeaturesPlugin_VersionedBoolean::ObjectHierarchy::collectUnusedSubs(
- GeomShapePtr theTopLevelCompound,
- const SetOfShape& theUsed) const
-{
- GeomShapePtr aResult = theTopLevelCompound->emptyCopied();
- bool isResultEmpty = true;
-
- for (GeomAPI_ShapeIterator aSub(theTopLevelCompound); aSub.more(); aSub.next()) {
- GeomShapePtr aCurrent = aSub.current();
- if (theUsed.find(aCurrent) != theUsed.end())
- continue; // already used
-
- MapShapeToIndex::const_iterator aFoundIndex = myParentIndices.find(aCurrent);
- if (aCurrent->shapeType() > GeomAPI_Shape::COMPOUND ||
- aFoundIndex == myParentIndices.end()) {
- bool isAddShape = true;
- // check compsolid is fully unused in the Boolean operation
- if (aCurrent->shapeType() == GeomAPI_Shape::COMPSOLID) {
- for (GeomAPI_ShapeIterator anIt(aCurrent); isAddShape && anIt.more(); anIt.next())
- isAddShape = theUsed.find(anIt.current()) == theUsed.end();
- }
-
- if (isAddShape) { // low-level shape, add it
- GeomAlgoAPI_ShapeBuilder::add(aResult, aCurrent);
- isResultEmpty = false;
- }
- } else {
- GeomShapePtr aCompound = collectUnusedSubs(aCurrent, theUsed);
- if (aCompound) {
- GeomAlgoAPI_ShapeBuilder::add(aResult, aCompound);
- isResultEmpty = false;
- }
- }
- }
- return isResultEmpty ? GeomShapePtr() : aResult;
-}
-
-
-FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Iterator
-FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Begin()
-{
- return Iterator(this);
-}
-
-FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Iterator
-FeaturesPlugin_VersionedBoolean::ObjectHierarchy::End()
-{
- return Iterator(this, false);
-}
-
-FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Iterator::Iterator(
- FeaturesPlugin_VersionedBoolean::ObjectHierarchy* theHierarchy, bool isBegin)
- : myHierarchy(theHierarchy)
-{
- if (isBegin) {
- myObject = myHierarchy->myObjects.begin();
- SkipAlreadyProcessed();
- } else
- myObject = myHierarchy->myObjects.end();
-}
-
-void FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Iterator::SkipAlreadyProcessed()
-{
- while (myObject != myHierarchy->myObjects.end() &&
- myHierarchy->myProcessedObjects.find(*myObject) != myHierarchy->myProcessedObjects.end())
- ++myObject;
-}
-
-bool FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Iterator::operator==(
- const Iterator& theOther) const
-{
- return myObject == theOther.myObject;
-}
-
-bool FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Iterator::operator!=(
- const Iterator& theOther) const
-{
- return !operator==(theOther);
-}
-
-FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Iterator&
-FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Iterator::operator++()
-{
- ++myObject;
- SkipAlreadyProcessed();
- return *this;
-}
-
-FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Iterator
-FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Iterator::operator++(int)
-{
- Iterator aCurrent;
- aCurrent.myHierarchy = myHierarchy;
- aCurrent.myObject = myObject;
-
- // increase iterator
- operator++();
-
- return aCurrent;
-}
-
-GeomShapePtr FeaturesPlugin_VersionedBoolean::ObjectHierarchy::Iterator::operator*() const
-{
- myHierarchy->myProcessedObjects.insert(*myObject);
- return *myObject;
-}
#include "FeaturesPlugin.h"
#include "FeaturesPlugin_Tools.h"
+#include <GeomAPI_ShapeHierarchy.h>
#include <GeomAlgoAPI_Tools.h>
#include <ModelAPI_Feature.h>
const std::shared_ptr<ModelAPI_Attribute> theToolsAttr
= std::shared_ptr<ModelAPI_Attribute>());
- /// Auxiliary class to store hierarchy of Boolean operation objects/tools
- /// and their parent shapes (compounds or compsolids)
- class ObjectHierarchy {
- typedef std::pair<GeomShapePtr, ListOfShape> ShapeAndSubshapes;
- typedef std::map<GeomShapePtr, GeomShapePtr, GeomAPI_Shape::Comparator> MapShapeToParent;
- typedef std::map<GeomShapePtr, size_t, GeomAPI_Shape::Comparator> MapShapeToIndex;
- typedef std::set<GeomShapePtr, GeomAPI_Shape::Comparator> SetOfShape;
-
- ListOfShape myObjects; ///< list of objects/tools of Boolean operation
- MapShapeToParent myParent; ///< refer a shape to compound/compsolid containing it
- /// indices of compounds/compsolids to keep the order of parent shapes
- /// corresponding to the order of objects
- MapShapeToIndex myParentIndices;
- /// list of shape and its subshapes stored according to the index of parent shape
- std::vector<ShapeAndSubshapes> mySubshapes;
-
- SetOfShape myProcessedObjects;
-
- public:
- /// Add object of Boolean opration
- void AddObject(const GeomShapePtr& theObject);
-
- /// Maps shape and its parent
- void AddParent(const GeomShapePtr& theShape, const GeomShapePtr& theParent);
-
- /// Return parent shape for the given, or empty if it is a high-level shape.
- /// By default, the parent and all its subshapes are marked as processed for further skip.
- GeomShapePtr Parent(const GeomShapePtr& theShape, bool theMarkProcessed = true);
-
- /// Marke the shape as already processed
- void MarkProcessed(const GeomShapePtr& theShape);
- /// Marke list ofshapes as already processed
- void MarkProcessed(const ListOfShape& theShapes);
-
- /// Split compound/compsolid shape for subshapes selected for Boolean operation and the other.
- void SplitCompound(const GeomShapePtr& theCompShape,
- ListOfShape& theUsed,
- ListOfShape& theNotUsed) const;
-
- /// Generates the list of top-level compounds, which contain the objects of Boolean operation.
- /// The generated list will contain only shapes unused during the Boolean operation.
- void CompoundsOfUnusedObjects(ListOfShape& theDestination) const;
-
- /// Return \c true if there is no object in hierarchy
- bool IsEmpty() const;
-
- /// Return list of objects
- const ListOfShape& Objects() const { return myObjects; }
- /// Separate objects of the given range of types and all other objects
- void ObjectsByType(ListOfShape& theShapesByType, ListOfShape& theOtherShapes,
- const GeomAPI_Shape::ShapeType theMinType = GeomAPI_Shape::COMPOUND,
- const GeomAPI_Shape::ShapeType theMaxType = GeomAPI_Shape::SHAPE) const;
-
- private:
- GeomShapePtr collectUnusedSubs(const GeomShapePtr theTopLevelCompound,
- const SetOfShape& theUsed) const;
-
- public:
- class Iterator {
- friend class ObjectHierarchy;
-
- ObjectHierarchy* myHierarchy;
- ListOfShape::iterator myObject;
-
- Iterator() {}
- Iterator(ObjectHierarchy* theHierarchy, bool isBegin = true);
-
- void SkipAlreadyProcessed();
-
- public:
- bool operator==(const Iterator&) const;
- bool operator!=(const Iterator&) const;
-
- Iterator& operator++();
- Iterator operator++(int);
-
- GeomShapePtr operator*() const;
- };
-
- Iterator Begin();
- Iterator End();
- };
-
/// Process SelectionList attribute and fill the objects hierarchy.
bool processAttribute(const std::string& theAttributeName,
- ObjectHierarchy& theObjects,
+ GeomAPI_ShapeHierarchy& theObjects,
ListOfShape& thePlanesList);
/// Perform Boolean operation of the object with the tools.
/// is added to this compound, and corresponding ResultBody is not generated.
/// \return \c false if something went wrong
bool processCompsolid(const GeomAlgoAPI_Tools::BOPType theBooleanType,
- ObjectHierarchy& theCompsolidHierarchy,
+ GeomAPI_ShapeHierarchy& theCompsolidHierarchy,
const GeomShapePtr& theCompsolid,
const ListOfShape& theTools,
const ListOfShape& thePlanes,
/// is added to this compound, and corresponding ResultBody is not generated.
/// \return \c false if something went wrong
bool processCompound(const GeomAlgoAPI_Tools::BOPType theBooleanType,
- ObjectHierarchy& theCompoundHierarchy,
+ GeomAPI_ShapeHierarchy& theCompoundHierarchy,
const GeomShapePtr& theCompound,
const ListOfShape& theTools,
int& theResultIndex,
/// into a single compound and add the result of the FUSE operation.
GeomShapePtr keepUnusedSubsOfCompound(
const GeomShapePtr& theResult,
- const ObjectHierarchy& theObjectsHierarchy,
- const ObjectHierarchy& theToolsHierarchy,
+ const GeomAPI_ShapeHierarchy& theObjectsHierarchy,
+ const GeomAPI_ShapeHierarchy& theToolsHierarchy,
std::shared_ptr<GeomAlgoAPI_MakeShapeList> theMakeShapeList);
-
-private:
- void parentForShape(const GeomShapePtr& theShape,
- const std::shared_ptr<ModelAPI_Result>& theContext,
- ObjectHierarchy& theShapesHierarchy);
};
#endif
GeomAPI_Torus.h
GeomAPI_Box.h
GeomAPI_WireExplorer.h
+ GeomAPI_ShapeHierarchy.h
)
SET(PROJECT_SOURCES
GeomAPI_Torus.cpp
GeomAPI_Box.cpp
GeomAPI_WireExplorer.cpp
+ GeomAPI_ShapeHierarchy.cpp
)
SET(PROJECT_LIBRARIES
--- /dev/null
+// Copyright (C) 2014-2020 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#include "GeomAPI_ShapeHierarchy.h"
+
+#include "GeomAPI_ShapeIterator.h"
+
+#include <BRep_Builder.hxx>
+#include <TopoDS_Shape.hxx>
+
+void GeomAPI_ShapeHierarchy::addObject(const GeomShapePtr& theObject)
+{
+ myObjects.push_back(theObject);
+}
+
+void GeomAPI_ShapeHierarchy::addParent(const GeomShapePtr& theShape,
+ const GeomShapePtr& theParent)
+{
+ myParent[theShape] = theParent;
+
+ MapShapeToIndex::iterator aFound = myParentIndices.find(theParent);
+ size_t anIndex = myParentIndices.size();
+ if (aFound == myParentIndices.end()) {
+ myParentIndices[theParent] = anIndex;
+ mySubshapes.push_back(ShapeAndSubshapes(theParent, ListOfShape()));
+ } else
+ anIndex = aFound->second;
+
+ mySubshapes[anIndex].second.push_back(theShape);
+}
+
+GeomShapePtr GeomAPI_ShapeHierarchy::parent(const GeomShapePtr& theShape,
+ bool theMarkProcessed)
+{
+ MapShapeToParent::const_iterator aFound = myParent.find(theShape);
+ GeomShapePtr aParent;
+ if (aFound != myParent.end()) {
+ aParent = aFound->second;
+ if (theMarkProcessed) {
+ // mark the parent and all its subs as processed by Boolean algorithm
+ markProcessed(aParent);
+ const ListOfShape& aSubs = mySubshapes[myParentIndices[aParent]].second;
+ for (ListOfShape::const_iterator anIt = aSubs.begin(); anIt != aSubs.end(); ++anIt)
+ markProcessed(*anIt);
+ }
+ }
+ return aParent;
+}
+
+void GeomAPI_ShapeHierarchy::markProcessed(const GeomShapePtr& theShape)
+{
+ myProcessedObjects.insert(theShape);
+}
+
+void GeomAPI_ShapeHierarchy::markProcessed(const ListOfShape& theShapes)
+{
+ for (ListOfShape::const_iterator anIt = theShapes.begin(); anIt != theShapes.end(); ++anIt)
+ markProcessed(*anIt);
+}
+
+void GeomAPI_ShapeHierarchy::objectsByType(
+ ListOfShape& theShapesByType,
+ ListOfShape& theOtherShapes,
+ const GeomAPI_Shape::ShapeType theMinType,
+ const GeomAPI_Shape::ShapeType theMaxType) const
+{
+ if (theMinType > theMaxType)
+ return objectsByType(theShapesByType, theOtherShapes, theMaxType, theMinType);
+
+ // no need to select objects if whole range is specified
+ if (theMinType == GeomAPI_Shape::COMPOUND && theMaxType == GeomAPI_Shape::SHAPE) {
+ theShapesByType.insert(theShapesByType.end(), myObjects.begin(), myObjects.end());
+ return;
+ }
+
+ for (ListOfShape::const_iterator anIt = myObjects.begin(); anIt != myObjects.end(); ++anIt) {
+ GeomAPI_Shape::ShapeType aType = (*anIt)->shapeType();
+ if (aType >= theMinType && aType <= theMaxType)
+ theShapesByType.push_back(*anIt);
+ else
+ theOtherShapes.push_back(*anIt);
+ }
+}
+
+
+void GeomAPI_ShapeHierarchy::splitCompound(
+ const GeomShapePtr& theCompShape,
+ ListOfShape& theUsed,
+ ListOfShape& theNotUsed) const
+{
+ theUsed.clear();
+ theNotUsed.clear();
+
+ MapShapeToIndex::const_iterator aFoundIndex = myParentIndices.find(theCompShape);
+ if (aFoundIndex == myParentIndices.end())
+ return; // no such shape
+
+ theUsed = mySubshapes[aFoundIndex->second].second;
+ SetOfShape aSubsSet;
+ aSubsSet.insert(theUsed.begin(), theUsed.end());
+
+ for (GeomAPI_ShapeIterator anExp(theCompShape); anExp.more(); anExp.next()) {
+ GeomShapePtr aCurrent = anExp.current();
+ if (aSubsSet.find(aCurrent) == aSubsSet.end())
+ theNotUsed.push_back(aCurrent);
+ }
+}
+
+bool GeomAPI_ShapeHierarchy::empty() const
+{
+ return myObjects.empty();
+}
+
+void GeomAPI_ShapeHierarchy::compoundsOfUnusedObjects(
+ ListOfShape& theDestination) const
+{
+ SetOfShape aUsedObjects = myProcessedObjects;
+ aUsedObjects.insert(myObjects.begin(), myObjects.end());
+
+ for (std::vector<ShapeAndSubshapes>::const_iterator anIt = mySubshapes.begin();
+ anIt != mySubshapes.end(); ++anIt) {
+ MapShapeToParent::const_iterator aParent = myParent.find(anIt->first);
+ if ((aParent == myParent.end() || !aParent->second) &&
+ anIt->first->shapeType() == GeomAPI_Shape::COMPOUND) {
+ // this is a top-level compound
+ GeomShapePtr aCompound = collectUnusedSubs(anIt->first, aUsedObjects);
+ // add to destination non-empty compounds only
+ if (aCompound)
+ theDestination.push_back(aCompound);
+ }
+ }
+}
+
+static void addSubShape(GeomShapePtr theTarget, GeomShapePtr theSub)
+{
+ if (!theTarget.get() || !theSub.get())
+ return;
+
+ TopoDS_Shape* aShape = theTarget->implPtr<TopoDS_Shape>();
+ const TopoDS_Shape& aShapeToAdd = theSub->impl<TopoDS_Shape>();
+
+ static BRep_Builder aBuilder;
+ aBuilder.Add(*aShape, aShapeToAdd);
+}
+
+GeomShapePtr GeomAPI_ShapeHierarchy::collectUnusedSubs(
+ GeomShapePtr theTopLevelCompound,
+ const SetOfShape& theUsed) const
+{
+ GeomShapePtr aResult = theTopLevelCompound->emptyCopied();
+ bool isResultEmpty = true;
+
+ for (GeomAPI_ShapeIterator aSub(theTopLevelCompound); aSub.more(); aSub.next()) {
+ GeomShapePtr aCurrent = aSub.current();
+ if (theUsed.find(aCurrent) != theUsed.end())
+ continue; // already used
+
+ MapShapeToIndex::const_iterator aFoundIndex = myParentIndices.find(aCurrent);
+ if (aCurrent->shapeType() > GeomAPI_Shape::COMPOUND ||
+ aFoundIndex == myParentIndices.end()) {
+ bool isAddShape = true;
+ // check compsolid is fully unused in the Boolean operation
+ if (aCurrent->shapeType() == GeomAPI_Shape::COMPSOLID) {
+ for (GeomAPI_ShapeIterator anIt(aCurrent); isAddShape && anIt.more(); anIt.next())
+ isAddShape = theUsed.find(anIt.current()) == theUsed.end();
+ }
+
+ if (isAddShape) { // low-level shape, add it
+ addSubShape(aResult, aCurrent);
+ isResultEmpty = false;
+ }
+ } else {
+ GeomShapePtr aCompound = collectUnusedSubs(aCurrent, theUsed);
+ if (aCompound) {
+ addSubShape(aResult, aCompound);
+ isResultEmpty = false;
+ }
+ }
+ }
+ return isResultEmpty ? GeomShapePtr() : aResult;
+}
+
+
+GeomAPI_ShapeHierarchy::iterator GeomAPI_ShapeHierarchy::begin()
+{
+ return iterator(this);
+}
+
+GeomAPI_ShapeHierarchy::iterator GeomAPI_ShapeHierarchy::end()
+{
+ return iterator(this, false);
+}
+
+GeomAPI_ShapeHierarchy::iterator::iterator(
+ GeomAPI_ShapeHierarchy* theHierarchy, bool isBegin)
+ : myHierarchy(theHierarchy)
+{
+ if (isBegin) {
+ myObject = myHierarchy->myObjects.begin();
+ skipAlreadyProcessed();
+ } else
+ myObject = myHierarchy->myObjects.end();
+}
+
+void GeomAPI_ShapeHierarchy::iterator::skipAlreadyProcessed()
+{
+ while (myObject != myHierarchy->myObjects.end() &&
+ myHierarchy->myProcessedObjects.find(*myObject) != myHierarchy->myProcessedObjects.end())
+ ++myObject;
+}
+
+bool GeomAPI_ShapeHierarchy::iterator::operator==(const iterator& theOther) const
+{
+ return myObject == theOther.myObject;
+}
+
+bool GeomAPI_ShapeHierarchy::iterator::operator!=(const iterator& theOther) const
+{
+ return !operator==(theOther);
+}
+
+GeomAPI_ShapeHierarchy::iterator& GeomAPI_ShapeHierarchy::iterator::operator++()
+{
+ ++myObject;
+ skipAlreadyProcessed();
+ return *this;
+}
+
+GeomAPI_ShapeHierarchy::iterator GeomAPI_ShapeHierarchy::iterator::operator++(int)
+{
+ iterator aCurrent;
+ aCurrent.myHierarchy = myHierarchy;
+ aCurrent.myObject = myObject;
+
+ // increase iterator
+ operator++();
+
+ return aCurrent;
+}
+
+GeomShapePtr GeomAPI_ShapeHierarchy::iterator::operator*() const
+{
+ myHierarchy->markProcessed(*myObject);
+ return *myObject;
+}
--- /dev/null
+// Copyright (C) 2014-2020 CEA/DEN, EDF R&D
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+#ifndef GeomAPI_ShapeHierarchy_H_
+#define GeomAPI_ShapeHierarchy_H_
+
+#include "GeomAPI.h"
+#include "GeomAPI_Shape.h"
+
+#include <map>
+#include <set>
+#include <vector>
+
+/// \class GeomAPI_ShapeHierarchy
+/// \ingroup Plugins
+/// \brief Storage for the hierarchy of shapes and their parents (compounds or compsolids)
+class GeomAPI_ShapeHierarchy
+{
+ typedef std::pair<GeomShapePtr, ListOfShape> ShapeAndSubshapes;
+ typedef std::map<GeomShapePtr, GeomShapePtr, GeomAPI_Shape::Comparator> MapShapeToParent;
+ typedef std::map<GeomShapePtr, size_t, GeomAPI_Shape::Comparator> MapShapeToIndex;
+ typedef std::set<GeomShapePtr, GeomAPI_Shape::Comparator> SetOfShape;
+
+ ListOfShape myObjects; ///< list of objects of some operation
+ MapShapeToParent myParent; ///< refer a shape to compound/compsolid containing it
+ /// indices of compounds/compsolids to keep the order of parent shapes
+ /// corresponding to the order of objects
+ MapShapeToIndex myParentIndices;
+ /// list of shape and its subshapes stored according to the index of parent shape
+ std::vector<ShapeAndSubshapes> mySubshapes;
+
+ SetOfShape myProcessedObjects;
+
+public:
+ /// Add an object of the operation (low-level shape in the hierarchy)
+ GEOMAPI_EXPORT void addObject(const GeomShapePtr& theObject);
+
+ /// Store link between shape and its parent.
+ /// Has to be called by high-level algorithm, because the parent compound/compsolid
+ /// is usually stored as a top-level result
+ GEOMAPI_EXPORT void addParent(const GeomShapePtr& theShape, const GeomShapePtr& theParent);
+
+ /// Return parent shape for the given, or empty if it is a high-level shape.
+ /// By default, the parent and all its subshapes are marked as processed for further skip.
+ GEOMAPI_EXPORT GeomShapePtr parent(const GeomShapePtr& theShape, bool theMarkProcessed = true);
+
+ /// Mark the shape as already processed
+ GEOMAPI_EXPORT void markProcessed(const GeomShapePtr& theShape);
+ /// Mark list ofshapes as already processed
+ GEOMAPI_EXPORT void markProcessed(const ListOfShape& theShapes);
+
+ /// Split compound/compsolid shape for subshapes selected for operation and the others.
+ GEOMAPI_EXPORT void splitCompound(const GeomShapePtr& theCompShape,
+ ListOfShape& theUsed,
+ ListOfShape& theNotUsed) const;
+
+ /// Generates the list of top-level compounds, which exclude the objects of operation.
+ GEOMAPI_EXPORT void compoundsOfUnusedObjects(ListOfShape& theDestination) const;
+
+ /// Return \c true if there is no object in hierarchy
+ GEOMAPI_EXPORT bool empty() const;
+
+ /// Return list of objects
+ const ListOfShape& objects() const { return myObjects; }
+ /// Separate objects of the given range of types and all other objects
+ GEOMAPI_EXPORT void objectsByType(ListOfShape& theShapesByType, ListOfShape& theOtherShapes,
+ const GeomAPI_Shape::ShapeType theMinType = GeomAPI_Shape::COMPOUND,
+ const GeomAPI_Shape::ShapeType theMaxType = GeomAPI_Shape::SHAPE) const;
+
+private:
+ GeomShapePtr collectUnusedSubs(const GeomShapePtr theTopLevelCompound,
+ const SetOfShape& theUsed) const;
+
+public:
+ class iterator : public std::iterator<std::forward_iterator_tag, GeomShapePtr>
+ {
+ public:
+ GEOMAPI_EXPORT iterator() {}
+
+ protected:
+ iterator(GeomAPI_ShapeHierarchy* theHierarchy, bool isBegin = true);
+
+ void skipAlreadyProcessed();
+
+ public:
+ GEOMAPI_EXPORT bool operator==(const iterator&) const;
+ GEOMAPI_EXPORT bool operator!=(const iterator&) const;
+
+ GEOMAPI_EXPORT iterator& operator++();
+ GEOMAPI_EXPORT iterator operator++(int);
+
+ GEOMAPI_EXPORT GeomShapePtr operator*() const;
+
+ private:
+ GeomAPI_ShapeHierarchy* myHierarchy;
+ ListOfShape::iterator myObject;
+
+ friend class GeomAPI_ShapeHierarchy;
+ };
+
+ GEOMAPI_EXPORT iterator begin();
+ GEOMAPI_EXPORT iterator end();
+};
+
+#endif
#include <Events_Loop.h>
#include <ModelAPI_Events.h>
+#include <GeomAPI_ShapeHierarchy.h>
+
#define RECURSE_TOP_LEVEL 50
//#define DEBUG_REMOVE_FEATURES
return aParents;
}
+void fillShapeHierarchy(const GeomShapePtr& theShape,
+ const ResultPtr& theContext,
+ GeomAPI_ShapeHierarchy& theHierarchy)
+{
+ ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(theContext);
+ if (aResCompSolidPtr.get()) {
+ std::shared_ptr<GeomAPI_Shape> aContextShape = aResCompSolidPtr->shape();
+ if (aContextShape->shapeType() <= GeomAPI_Shape::COMPSOLID) {
+ theHierarchy.addParent(theShape, aContextShape);
+ fillShapeHierarchy(aContextShape, aResCompSolidPtr, theHierarchy);
+ }
+ }
+}
+
+
void removeResults(const std::list<ResultPtr>& theResults)
{
// collect all documents where the results must be removed
class ModelAPI_ResultBody;
class GeomAPI_Shape;
+class GeomAPI_ShapeHierarchy;
#include <memory>
#include <vector>
MODELAPI_EXPORT std::set<std::shared_ptr<ModelAPI_Feature> >
getParents(const std::shared_ptr<ModelAPI_Feature>& theFeature);
+/*! Store shape and its parent shape to the hierarchy data structure
+ * \param[in] theShape the shape to store
+ * \param[in] theContext the result (parent shape) for the given shape
+ * \param[out] theHierarchy container for shape hierarchy
+ */
+MODELAPI_EXPORT void fillShapeHierarchy(
+ const std::shared_ptr<GeomAPI_Shape>& theShape,
+ const std::shared_ptr<ModelAPI_Result>& theContext,
+ GeomAPI_ShapeHierarchy& theHierarchy);
+
/*! Creates a remove result features with the given results
*/
MODELAPI_EXPORT void removeResults(const std::list<std::shared_ptr<ModelAPI_Result> >& theResults);