Salome HOME
7d5e2e90c5f23d1e5f5ad882df715cc45b17f50f
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_Partition.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 // File:        FeaturesPlugin_Partition.cpp
4 // Created:     31 Jul 2015
5 // Author:      Natalia ERMOLAEVA
6
7 #include "FeaturesPlugin_Partition.h"
8
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>
19
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>
25
26 #include <GeomAPI_ShapeIterator.h>
27
28 #include <sstream>
29
30 //=================================================================================================
31 FeaturesPlugin_Partition::FeaturesPlugin_Partition()
32 {
33 }
34
35 //=================================================================================================
36 void FeaturesPlugin_Partition::initAttributes()
37 {
38   data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
39 }
40
41 //=================================================================================================
42 void FeaturesPlugin_Partition::execute()
43 {
44   ListOfShape anObjects, aPlanes;
45
46   // Getting objects.
47   AttributeSelectionListPtr anObjectsSelList = selectionList(BASE_OBJECTS_ID());
48   for(int anIndex = 0; anIndex < anObjectsSelList->size(); ++anIndex) {
49     AttributeSelectionPtr anObjectAttr = anObjectsSelList->value(anIndex);
50     GeomShapePtr anObject = anObjectAttr->value();
51     if(!anObject.get()) {
52       // It could be a construction plane.
53       ResultPtr aContext = anObjectAttr->context();
54       aPlanes.push_back(anObjectAttr->context()->shape());
55     } else {
56       anObjects.push_back(anObject);
57     }
58   }
59   std::list<std::shared_ptr<GeomAPI_Pnt> > aBoundingPoints = GeomAlgoAPI_ShapeTools::getBoundingBox(anObjects, 1.0);
60
61   // Resize planes.
62   ListOfShape aTools;
63   std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList());
64   for(ListOfShape::const_iterator anIt = aPlanes.cbegin(); anIt != aPlanes.cend(); ++anIt) {
65     GeomShapePtr aPlane = *anIt;
66     GeomShapePtr aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPlane, aBoundingPoints);
67     std::shared_ptr<GeomAlgoAPI_MakeShapeCustom> aMkShCustom(new GeomAlgoAPI_MakeShapeCustom);
68     aMkShCustom->addModified(aPlane, aTool);
69     aMakeShapeList->appendAlgo(aMkShCustom);
70     aTools.push_back(aTool);
71   }
72
73   // Create single result.
74   std::shared_ptr<GeomAlgoAPI_Partition> aPartitionAlgo(new GeomAlgoAPI_Partition(anObjects, aTools));
75
76   // Checking that the algorithm worked properly.
77   if (!aPartitionAlgo->isDone()) {
78     static const std::string aFeatureError = "Error: Partition algorithm failed.";
79     setError(aFeatureError);
80     return;
81   }
82   if (aPartitionAlgo->shape()->isNull()) {
83     static const std::string aShapeError = "Error: Resulting shape is Null.";
84     setError(aShapeError);
85     return;
86   }
87   if (!aPartitionAlgo->isValid()) {
88     std::string aFeatureError = "Error: Resulting shape is not valid.";
89     setError(aFeatureError);
90     return;
91   }
92   aMakeShapeList->appendAlgo(aPartitionAlgo);
93   GeomShapePtr aResultShape = aPartitionAlgo->shape();
94
95   int aResultIndex = 0;
96   anObjects.insert(anObjects.end(), aPlanes.begin(), aPlanes.end());
97   if(aResultShape->shapeType() == GeomAPI_Shape::COMPOUND) {
98     for(GeomAPI_ShapeIterator anIt(aResultShape); anIt.more(); anIt.next()) {
99       storeResult(anObjects, anIt.current(), aMakeShapeList, aResultIndex);
100       ++aResultIndex;
101     }
102   } else {
103     storeResult(anObjects, aResultShape, aMakeShapeList, aResultIndex);
104     ++aResultIndex;
105   }
106
107   // Remove the rest results if there were produced in the previous pass.
108   removeResults(aResultIndex);
109 }
110
111 //=================================================================================================
112 void FeaturesPlugin_Partition::storeResult(const ListOfShape& theObjects,
113                                            const GeomShapePtr theResultShape,
114                                            const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
115                                            const int theIndex)
116 {
117   // Find base.
118   GeomShapePtr aBaseShape;
119   for(ListOfShape::const_iterator anIt = theObjects.cbegin(); anIt != theObjects.cend(); ++anIt) {
120     GeomShapePtr anObjectShape = *anIt;
121     ListOfShape aModifiedShapes;
122     theMakeShape->modified(anObjectShape, aModifiedShapes);
123     for(ListOfShape::const_iterator aModIt = aModifiedShapes.cbegin(); aModIt != aModifiedShapes.cend(); ++aModIt) {
124       GeomShapePtr aModShape = *aModIt;
125       if(theResultShape->isSubShape(aModShape)) {
126         aBaseShape = anObjectShape;
127         break;
128       }
129     }
130     if(aBaseShape.get()) {
131       break;
132     }
133   }
134
135   // Create result body.
136   ResultBodyPtr aResultBody = document()->createBody(data(), theIndex);
137
138   // Store modified shape.
139   if(aBaseShape->isEqual(theResultShape)) {
140     aResultBody->store(theResultShape);
141     return;
142   }
143
144   const int aDelTag = 1;
145   const int aSubTag = 2; /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids
146   int aModTag = aSubTag + 10000;
147   const std::string aModName = "Modified";
148
149   aResultBody->storeModified(aBaseShape, theResultShape, aSubTag);
150
151   std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfSubShapes = theMakeShape->mapOfSubShapes();
152   int anIndex = 1;
153   for(ListOfShape::const_iterator anIt = theObjects.cbegin(); anIt != theObjects.cend(); ++anIt) {
154     std::ostringstream aStream;
155     aStream << aModName << "_" << anIndex++;
156     aResultBody->loadAndOrientModifiedShapes(theMakeShape.get(), *anIt, GeomAPI_Shape::EDGE,
157                                              aModTag, aStream.str(), *aMapOfSubShapes.get(), true);
158     aResultBody->loadAndOrientModifiedShapes(theMakeShape.get(), *anIt, GeomAPI_Shape::FACE,
159                                              aModTag, aStream.str(), *aMapOfSubShapes.get(), true);
160     aResultBody->loadDeletedShapes(theMakeShape.get(), *anIt, GeomAPI_Shape::EDGE, aDelTag);
161     aResultBody->loadDeletedShapes(theMakeShape.get(), *anIt, GeomAPI_Shape::FACE, aDelTag);
162     aModTag += 10000;
163   }
164
165   setResult(aResultBody, theIndex);
166 }