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