Salome HOME
Translations for BuildPlugin and FeaturesPlugin
[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
60   if(anObjects.empty()) {
61     static const std::string aFeatureError = "Error: No objects for partition.";
62     setError(aFeatureError);
63     return;
64   }
65
66   std::list<std::shared_ptr<GeomAPI_Pnt> > aBoundingPoints = GeomAlgoAPI_ShapeTools::getBoundingBox(anObjects, 1.0);
67
68   // Resize planes.
69   ListOfShape aTools;
70   std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeShapeList(new GeomAlgoAPI_MakeShapeList());
71   for(ListOfShape::const_iterator anIt = aPlanes.cbegin(); anIt != aPlanes.cend(); ++anIt) {
72     GeomShapePtr aPlane = *anIt;
73     GeomShapePtr aTool = GeomAlgoAPI_ShapeTools::fitPlaneToBox(aPlane, aBoundingPoints);
74     std::shared_ptr<GeomAlgoAPI_MakeShapeCustom> aMkShCustom(new GeomAlgoAPI_MakeShapeCustom);
75     aMkShCustom->addModified(aPlane, aTool);
76     aMakeShapeList->appendAlgo(aMkShCustom);
77     aTools.push_back(aTool);
78   }
79
80   // Create single result.
81   std::shared_ptr<GeomAlgoAPI_Partition> aPartitionAlgo(new GeomAlgoAPI_Partition(anObjects, aTools));
82
83   // Checking that the algorithm worked properly.
84   if (!aPartitionAlgo->isDone()) {
85     static const std::string aFeatureError = "Error: Partition algorithm failed.";
86     setError(aFeatureError);
87     return;
88   }
89   if (aPartitionAlgo->shape()->isNull()) {
90     static const std::string aShapeError = "Error: Resulting shape is Null.";
91     setError(aShapeError);
92     return;
93   }
94   if (!aPartitionAlgo->isValid()) {
95     std::string aFeatureError = "Error: Resulting shape is not valid.";
96     setError(aFeatureError);
97     return;
98   }
99   aMakeShapeList->appendAlgo(aPartitionAlgo);
100   GeomShapePtr aResultShape = aPartitionAlgo->shape();
101
102   int aResultIndex = 0;
103   anObjects.insert(anObjects.end(), aPlanes.begin(), aPlanes.end());
104   if(aResultShape->shapeType() == GeomAPI_Shape::COMPOUND) {
105     for(GeomAPI_ShapeIterator anIt(aResultShape); anIt.more(); anIt.next()) {
106       storeResult(anObjects, anIt.current(), aMakeShapeList, aResultIndex);
107       ++aResultIndex;
108     }
109   } else {
110     storeResult(anObjects, aResultShape, aMakeShapeList, aResultIndex);
111     ++aResultIndex;
112   }
113
114   // Remove the rest results if there were produced in the previous pass.
115   removeResults(aResultIndex);
116 }
117
118 //=================================================================================================
119 void FeaturesPlugin_Partition::storeResult(const ListOfShape& theObjects,
120                                            const GeomShapePtr theResultShape,
121                                            const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
122                                            const int theIndex)
123 {
124   // Find base.
125   GeomShapePtr aBaseShape;
126   for(ListOfShape::const_iterator anIt = theObjects.cbegin(); anIt != theObjects.cend(); ++anIt) {
127     GeomShapePtr anObjectShape = *anIt;
128     ListOfShape aModifiedShapes;
129     theMakeShape->modified(anObjectShape, aModifiedShapes);
130     for(ListOfShape::const_iterator aModIt = aModifiedShapes.cbegin(); aModIt != aModifiedShapes.cend(); ++aModIt) {
131       GeomShapePtr aModShape = *aModIt;
132       if(theResultShape->isSubShape(aModShape)) {
133         aBaseShape = anObjectShape;
134         break;
135       }
136     }
137     if(aBaseShape.get()) {
138       break;
139     }
140   }
141
142   // Create result body.
143   ResultBodyPtr aResultBody = document()->createBody(data(), theIndex);
144
145   // Store modified shape.
146   if(!aBaseShape.get() || aBaseShape->isEqual(theResultShape)) {
147     aResultBody->store(theResultShape);
148     setResult(aResultBody, theIndex);
149     return;
150   }
151
152   const int aDelTag = 1;
153   const int aSubTag = 2; /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids
154   int aModTag = aSubTag + 10000;
155   const std::string aModName = "Modified";
156
157   aResultBody->storeModified(aBaseShape, theResultShape, aSubTag);
158
159   std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfSubShapes = theMakeShape->mapOfSubShapes();
160   int anIndex = 1;
161   for(ListOfShape::const_iterator anIt = theObjects.cbegin(); anIt != theObjects.cend(); ++anIt) {
162     std::ostringstream aStream;
163     aStream << aModName << "_" << anIndex++;
164     aResultBody->loadAndOrientModifiedShapes(theMakeShape.get(), *anIt, GeomAPI_Shape::EDGE,
165                                              aModTag, aStream.str(), *aMapOfSubShapes.get(), true);
166     aResultBody->loadAndOrientModifiedShapes(theMakeShape.get(), *anIt, GeomAPI_Shape::FACE,
167                                              aModTag, aStream.str(), *aMapOfSubShapes.get(), true);
168     aResultBody->loadDeletedShapes(theMakeShape.get(), *anIt, GeomAPI_Shape::EDGE, aDelTag);
169     aResultBody->loadDeletedShapes(theMakeShape.get(), *anIt, GeomAPI_Shape::FACE, aDelTag);
170     aModTag += 10000;
171   }
172
173   setResult(aResultBody, theIndex);
174 }