1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
3 // File: FeaturesPlugin_Partition.cpp
4 // Created: 31 Jul 2015
5 // Author: Natalia ERMOLAEVA
7 #include "FeaturesPlugin_Partition.h"
9 #include <ModelAPI_Data.h>
10 #include <ModelAPI_Document.h>
11 #include <ModelAPI_AttributeBoolean.h>
12 #include <ModelAPI_AttributeReference.h>
13 #include <ModelAPI_AttributeInteger.h>
14 #include <ModelAPI_BodyBuilder.h>
15 #include <ModelAPI_ResultBody.h>
16 #include <ModelAPI_AttributeSelectionList.h>
17 #include <ModelAPI_Session.h>
18 #include <ModelAPI_Validator.h>
20 #include <GeomAlgoAPI_CompoundBuilder.h>
21 #include <GeomAlgoAPI_Partition.h>
22 #include <GeomAlgoAPI_MakeShapeCustom.h>
23 #include <GeomAlgoAPI_MakeShapeList.h>
24 #include <GeomAlgoAPI_ShapeTools.h>
26 #include <GeomAPI_Face.h>
27 #include <GeomAPI_ShapeExplorer.h>
28 #include <GeomAPI_ShapeIterator.h>
33 static GeomShapePtr findBase(const GeomShapePtr theObjectShape,
34 const GeomShapePtr theResultShape,
35 const GeomAPI_Shape::ShapeType theShapeType,
36 const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape);
38 //=================================================================================================
39 FeaturesPlugin_Partition::FeaturesPlugin_Partition()
43 //=================================================================================================
44 void FeaturesPlugin_Partition::initAttributes()
46 data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
49 //=================================================================================================
50 void FeaturesPlugin_Partition::execute()
52 ListOfShape anObjects, aPlanes;
55 AttributeSelectionListPtr anObjectsSelList = selectionList(BASE_OBJECTS_ID());
56 for(int anIndex = 0; anIndex < anObjectsSelList->size(); ++anIndex) {
57 AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anIndex);
58 GeomShapePtr anObject = anObjectAttr->value();
60 // It could be a construction plane.
61 ResultPtr aContext = anObjectAttr->context();
62 aPlanes.push_back(anObjectAttr->context()->shape());
64 anObjects.push_back(anObject);
68 if(anObjects.empty()) {
69 static const std::string aFeatureError = "Error: No objects for partition.";
70 setError(aFeatureError);
74 std::list<std::shared_ptr<GeomAPI_Pnt> > aBoundingPoints =
75 GeomAlgoAPI_ShapeTools::getBoundingBox(anObjects, 1.0);
79 std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList());
80 for(ListOfShape::const_iterator anIt = aPlanes.cbegin(); anIt != aPlanes.cend(); ++anIt) {
81 GeomShapePtr aPlane = *anIt;
82 GeomShapePtr aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPlane, aBoundingPoints);
83 std::shared_ptr<GeomAlgoAPI_MakeShapeCustom> aMkShCustom(new GeomAlgoAPI_MakeShapeCustom);
84 aMkShCustom->addModified(aPlane, aTool);
85 aMakeShapeList->appendAlgo(aMkShCustom);
86 aTools.push_back(aTool);
89 // Create single result.
90 std::shared_ptr<GeomAlgoAPI_Partition> aPartitionAlgo(
91 new GeomAlgoAPI_Partition(anObjects, aTools));
93 // Checking that the algorithm worked properly.
94 if (!aPartitionAlgo->isDone()) {
95 static const std::string aFeatureError = "Error: Partition algorithm failed.";
96 setError(aFeatureError);
99 if (aPartitionAlgo->shape()->isNull()) {
100 static const std::string aShapeError = "Error: Resulting shape is Null.";
101 setError(aShapeError);
104 if (!aPartitionAlgo->isValid()) {
105 std::string aFeatureError = "Error: Resulting shape is not valid.";
106 setError(aFeatureError);
109 aMakeShapeList->appendAlgo(aPartitionAlgo);
110 GeomShapePtr aResultShape = aPartitionAlgo->shape();
112 int aResultIndex = 0;
113 if(aResultShape->shapeType() == GeomAPI_Shape::COMPOUND) {
114 for(GeomAPI_ShapeIterator anIt(aResultShape); anIt.more(); anIt.next()) {
115 storeResult(anObjects, aPlanes, anIt.current(), aMakeShapeList, aResultIndex);
119 storeResult(anObjects, aPlanes, aResultShape, aMakeShapeList, aResultIndex);
123 // Remove the rest results if there were produced in the previous pass.
124 removeResults(aResultIndex);
127 //=================================================================================================
128 void FeaturesPlugin_Partition::storeResult(
129 ListOfShape& theObjects, ListOfShape& thePlanes,
130 const GeomShapePtr theResultShape,
131 const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
134 // Find base. The most complicated is the real modified object (#1799 if box is partitioned by
135 // two planes the box is the base, not planes, independently on the order in the list).
136 GeomShapePtr aBaseShape;
137 for(ListOfShape::const_iterator anIt = theObjects.cbegin(); anIt != theObjects.cend(); ++anIt) {
138 GeomShapePtr anObjectShape = *anIt;
139 GeomShapePtr aCandidate =
140 findBase(anObjectShape, theResultShape, GeomAPI_Shape::VERTEX, theMakeShape);
141 if(!aCandidate.get()) {
142 aCandidate = findBase(anObjectShape, theResultShape, GeomAPI_Shape::EDGE, theMakeShape);
144 if (!aCandidate.get())
145 aCandidate = findBase(anObjectShape, theResultShape, GeomAPI_Shape::FACE, theMakeShape);
147 if(aCandidate.get()) {
148 if (!aBaseShape.get() || aBaseShape->shapeType() > aCandidate->shapeType()) {
149 aBaseShape = aCandidate;
154 // Create result body.
155 ResultBodyPtr aResultBody = document()->createBody(data(), theIndex);
157 // Store modified shape.
158 if(!aBaseShape.get() || aBaseShape->isEqual(theResultShape)) {
159 aResultBody->store(theResultShape);
160 setResult(aResultBody, theIndex);
164 const int aDelTag = 1;
165 /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids
166 const int aSubTag = 2;
167 int aModTag = aSubTag + 10000;
168 const std::string aModName = "Modified";
170 aResultBody->storeModified(aBaseShape, theResultShape, aSubTag);
172 std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfSubShapes = theMakeShape->mapOfSubShapes();
173 theObjects.insert(theObjects.end(), thePlanes.begin(), thePlanes.end());
175 for(ListOfShape::const_iterator anIt = theObjects.cbegin(); anIt != theObjects.cend(); ++anIt) {
176 GeomShapePtr aShape = *anIt;
177 std::string aModEdgeName = aModName + "_Edge_" + std::to_string((long long)anIndex);
178 std::string aModFaceName = aModName + "_Face_" + std::to_string((long long)anIndex++);
179 aResultBody->loadAndOrientModifiedShapes(theMakeShape.get(), aShape, GeomAPI_Shape::EDGE,
180 aModTag, aModEdgeName, *aMapOfSubShapes.get(), true);
182 aResultBody->loadAndOrientModifiedShapes(theMakeShape.get(), aShape, GeomAPI_Shape::FACE,
183 aModTag, aModFaceName, *aMapOfSubShapes.get(), true);
185 aResultBody->loadDeletedShapes(theMakeShape.get(), aShape, GeomAPI_Shape::EDGE, aDelTag);
186 aResultBody->loadDeletedShapes(theMakeShape.get(), aShape, GeomAPI_Shape::FACE, aDelTag);
189 setResult(aResultBody, theIndex);
193 //=================================================================================================
194 GeomShapePtr findBase(const GeomShapePtr theObjectShape,
195 const GeomShapePtr theResultShape,
196 const GeomAPI_Shape::ShapeType theShapeType,
197 const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape)
199 GeomShapePtr aBaseShape;
200 std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfSubShapes = theMakeShape->mapOfSubShapes();
201 for(GeomAPI_ShapeExplorer anObjectSubShapesExp(theObjectShape, theShapeType);
202 anObjectSubShapesExp.more();
203 anObjectSubShapesExp.next()) {
204 GeomShapePtr anObjectSubShape = anObjectSubShapesExp.current();
205 ListOfShape aModifiedShapes;
206 theMakeShape->modified(anObjectSubShape, aModifiedShapes);
207 for(ListOfShape::const_iterator
208 aModIt = aModifiedShapes.cbegin(); aModIt != aModifiedShapes.cend(); ++aModIt) {
209 GeomShapePtr aModShape = *aModIt;
210 if(aMapOfSubShapes->isBound(aModShape)) {
211 aModShape = aMapOfSubShapes->find(aModShape);
213 if(theResultShape->isSubShape(aModShape)) {
214 aBaseShape = theObjectShape;
218 if(aBaseShape.get()) {