bool FeaturesPlugin_Boolean::processAttribute(const std::string& theAttributeName,
ObjectHierarchy& theObjects,
- ListOfShape& thePlanesList,
- ListOfShape& theEdgesAndFaces)
+ ListOfShape& thePlanesList)
{
AttributeSelectionListPtr anObjectsSelList = selectionList(theAttributeName);
for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
return false;
}
- if (anObject->shapeType() == GeomAPI_Shape::EDGE ||
- anObject->shapeType() == GeomAPI_Shape::FACE) {
- theEdgesAndFaces.push_back(anObject);
- continue;
- }
-
theObjects.AddObject(anObject);
ResultPtr aContext = anObjectAttr->context();
return aParent;
}
+void FeaturesPlugin_Boolean::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_Boolean::ObjectHierarchy::SplitCompound(const GeomShapePtr& theCompShape,
ListOfShape& theUsed,
ListOfShape& theNotUsed) 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;
public:
class Iterator {
/// Process SelectionList attribute and fill the objects hierarchy.
bool processAttribute(const std::string& theAttributeName,
ObjectHierarchy& theObjects,
- ListOfShape& thePlanesList,
- ListOfShape& theEdgesAndFaces);
+ ListOfShape& thePlanesList);
/// Perform Boolean operation of the object with the tools
/// \return \c false if something went wrong
//==================================================================================================
void FeaturesPlugin_BooleanCommon::execute()
{
- ListOfShape aPlanes, anEdgesAndFaces;
+ ListOfShape aPlanes;
ObjectHierarchy anObjects, aTools;
bool isSimpleMode = false;
}
// Getting objects.
- if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes, anEdgesAndFaces))
+ if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes))
return;
// Planes are not supported as objects of COMMON operation
aPlanes.clear();
// Getting tools.
if (!isSimpleMode &&
- !processAttribute(TOOL_LIST_ID(), aTools, aPlanes, anEdgesAndFaces))
+ !processAttribute(TOOL_LIST_ID(), aTools, aPlanes))
return;
if (anObjects.IsEmpty() || (!isSimpleMode && aTools.IsEmpty() && aPlanes.empty())) {
void FeaturesPlugin_BooleanCut::execute()
{
ObjectHierarchy anObjects, aTools;
- ListOfShape aPlanes, anEdgesAndFaces;
+ ListOfShape aPlanes;
// Getting objects and tools
- if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes, anEdgesAndFaces) ||
- !processAttribute(TOOL_LIST_ID(), aTools, aPlanes, anEdgesAndFaces))
+ if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes) ||
+ !processAttribute(TOOL_LIST_ID(), aTools, aPlanes))
return;
int aResultIndex = 0;
{
std::string anError;
ObjectHierarchy anObjects, aTools;
- ListOfShape aPlanes, anEdgesAndFaces;
+ ListOfShape aPlanes;
// Getting objects.
- if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes, anEdgesAndFaces))
+ if (!processAttribute(OBJECT_LIST_ID(), anObjects, aPlanes))
return;
// Planes are not supported as objects of FILL operation
aPlanes.clear();
// Getting tools.
- if (!processAttribute(TOOL_LIST_ID(), aTools, aPlanes, anEdgesAndFaces))
+ if (!processAttribute(TOOL_LIST_ID(), aTools, aPlanes))
return;
int aResultIndex = 0;
{
std::string anError;
ObjectHierarchy anObjectsHierarchy, aToolsHierarchy;
- ListOfShape aPlanes, anEdgesAndFaces;
+ ListOfShape aPlanes;
bool isSimpleCreation = false;
}
// Getting objects.
- if (!processAttribute(OBJECT_LIST_ID(), anObjectsHierarchy, aPlanes, anEdgesAndFaces))
+ if (!processAttribute(OBJECT_LIST_ID(), anObjectsHierarchy, aPlanes))
return;
// Getting tools.
if (!isSimpleCreation &&
- !processAttribute(TOOL_LIST_ID(), aToolsHierarchy, aPlanes, anEdgesAndFaces))
+ !processAttribute(TOOL_LIST_ID(), aToolsHierarchy, aPlanes))
return;
- ListOfShape anObjects = anObjectsHierarchy.Objects();
- ListOfShape aTools = aToolsHierarchy.Objects();
+ ListOfShape anObjects, aTools, anEdgesAndFaces;
+ // all objects except edges and faces
+ anObjectsHierarchy.ObjectsByType(anEdgesAndFaces, anObjects,
+ GeomAPI_Shape::FACE, GeomAPI_Shape::EDGE);
+ aToolsHierarchy.ObjectsByType(anEdgesAndFaces, aTools,
+ GeomAPI_Shape::FACE, GeomAPI_Shape::EDGE);
if ((anObjects.size() + aTools.size() + anEdgesAndFaces.size()) < 2) {
std::string aFeatureError = "Error: Not enough objects for boolean operation.";
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);
+
ListOfShape aUsed, aNotUsed;
anObjectsHierarchy.SplitCompound(aParent, aUsed, aNotUsed);
aShapesToAdd.insert(aShapesToAdd.end(), aNotUsed.begin(), aNotUsed.end());
aMakeShapeList->appendAlgo(aCutAlgo);
}
}
+ anOriginalShapes.insert(anOriginalShapes.end(), anEdgesAndFaces.begin(),
+ anEdgesAndFaces.end());
// If we have compsolids then cut with not used solids all others.
if (!aShapesToAdd.empty()) {
}
}
- anOriginalShapes.insert(anOriginalShapes.end(), anEdgesAndFaces.begin(),
- anEdgesAndFaces.end());
-
if (!aSolidsToFuse.empty()) {
anObjects.clear();
anObjects.push_back(aSolidsToFuse.back());