Salome HOME
6000c9d8431e8cc102bd828e01f2ddbafd2c7910
[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_AttributeReference.h>
12 #include <ModelAPI_AttributeInteger.h>
13 #include <ModelAPI_BodyBuilder.h>
14 #include <ModelAPI_ResultBody.h>
15 #include <ModelAPI_AttributeSelectionList.h>
16 #include <ModelAPI_Session.h>
17 #include <ModelAPI_Validator.h>
18
19 #include <GeomAlgoAPI_Partition.h>
20 #include <GeomAlgoAPI_MakeShapeList.h>
21 #include <GeomAlgoAPI_ShapeTools.h>
22
23 //=================================================================================================
24 FeaturesPlugin_Partition::FeaturesPlugin_Partition()
25 {
26 }
27
28 //=================================================================================================
29 void FeaturesPlugin_Partition::initAttributes()
30 {
31   AttributeSelectionListPtr aSelection =
32     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
33     FeaturesPlugin_Partition::OBJECT_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
34   aSelection->setSelectionType("SOLID");
35
36   aSelection =
37     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
38     FeaturesPlugin_Partition::TOOL_LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
39   aSelection->setSelectionType("SOLID");
40
41   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), OBJECT_LIST_ID());
42   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), TOOL_LIST_ID());
43 }
44
45 //=================================================================================================
46 std::shared_ptr<GeomAPI_Shape> FeaturesPlugin_Partition::getShape(const std::string& theAttrName)
47 {
48   std::shared_ptr<ModelAPI_AttributeReference> aObjRef =
49       std::dynamic_pointer_cast<ModelAPI_AttributeReference>(data()->attribute(theAttrName));
50   if (aObjRef) {
51     std::shared_ptr<ModelAPI_ResultBody> aConstr =
52         std::dynamic_pointer_cast<ModelAPI_ResultBody>(aObjRef->value());
53     if (aConstr)
54       return aConstr->shape();
55   }
56   return std::shared_ptr<GeomAPI_Shape>();
57 }
58
59 //=================================================================================================
60 void FeaturesPlugin_Partition::execute()
61 {
62   ListOfShape anObjects, aTools;
63
64   // Getting objects.
65   AttributeSelectionListPtr anObjectsSelList = selectionList(FeaturesPlugin_Partition::OBJECT_LIST_ID());
66   for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
67     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr = anObjectsSelList->value(anObjectsIndex);
68     std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
69     if (!anObject.get()) {
70       return;
71     }
72     anObjects.push_back(anObject);
73   }
74
75   // Getting tools.
76   AttributeSelectionListPtr aToolsSelList = selectionList(FeaturesPlugin_Partition::TOOL_LIST_ID());
77   for (int aToolsIndex = 0; aToolsIndex < aToolsSelList->size(); aToolsIndex++) {
78     std::shared_ptr<ModelAPI_AttributeSelection> aToolAttr = aToolsSelList->value(aToolsIndex);
79     std::shared_ptr<GeomAPI_Shape> aTool = aToolAttr->value();
80     if (!aTool.get()) {
81       // it could be a construction plane
82       ResultPtr aContext = aToolAttr->context();
83       if (aContext.get()) {
84         aTool = GeomAlgoAPI_ShapeTools::faceToInfinitePlane(aContext->shape());
85       }
86     }
87     if (!aTool.get()) {
88       return;
89     }
90     aTools.push_back(aTool);
91   }
92
93   int aResultIndex = 0;
94
95   if (anObjects.empty() || aTools.empty()) {
96     std::string aFeatureError = "Not enough objects for partition operation";
97     setError(aFeatureError);
98     return;
99   }
100
101   // Cut each object with all tools
102   for (ListOfShape::iterator anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) {
103     std::shared_ptr<GeomAPI_Shape> anObject = *anObjectsIt;
104     ListOfShape aListWithObject; aListWithObject.push_back(anObject);
105     GeomAlgoAPI_Partition aPartitionAlgo(aListWithObject, aTools);
106
107     // Checking that the algorithm worked properly.
108     if (!aPartitionAlgo.isDone()) {
109       static const std::string aFeatureError = "Partition algorithm failed";
110       setError(aFeatureError);
111       return;
112     }
113     if (aPartitionAlgo.shape()->isNull()) {
114       static const std::string aShapeError = "Resulting shape is Null";
115       setError(aShapeError);
116       return;
117     }
118     if (!aPartitionAlgo.isValid()) {
119       std::string aFeatureError = "Warning: resulting shape is not valid";
120       setError(aFeatureError);
121       return;
122     }
123
124     if (GeomAlgoAPI_ShapeTools::volume(aPartitionAlgo.shape()) > 1.e-7) {
125       std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data(), aResultIndex);
126       aResultBody->store(aPartitionAlgo.shape());
127       loadNamingDS(aResultBody, anObject, aTools, aPartitionAlgo);
128       setResult(aResultBody, aResultIndex);
129       aResultIndex++;
130     }
131   }
132
133   // remove the rest results if there were produced in the previous pass
134   removeResults(aResultIndex);
135 }
136
137 //=================================================================================================
138 void FeaturesPlugin_Partition::loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
139                                             const std::shared_ptr<GeomAPI_Shape> theBaseShape,
140                                             const ListOfShape& theTools,
141                                             const GeomAlgoAPI_Partition& thePartitionAlgo)
142 {
143   //load result
144   if(theBaseShape->isEqual(thePartitionAlgo.shape())) {
145     theResultBody->store(thePartitionAlgo.shape());
146   } else {
147     const int aModifyTag = 1;
148     const int aDeletedTag = 2;
149     const int aSubsolidsTag = 3; /// sub solids will be placed at labels 3, 4, etc. if result is compound of solids
150
151     theResultBody->storeModified(theBaseShape, thePartitionAlgo.shape(), aSubsolidsTag);
152
153     std::shared_ptr<GeomAlgoAPI_MakeShape> aMkShape = thePartitionAlgo.makeShape();
154     std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfShapes = thePartitionAlgo.mapOfShapes();
155
156     std::string aModName = "Modified";
157     theResultBody->loadAndOrientModifiedShapes(aMkShape.get(), theBaseShape, GeomAPI_Shape::FACE,
158                                                aModifyTag, aModName, *aMapOfShapes.get());
159     theResultBody->loadDeletedShapes(aMkShape.get(), theBaseShape, GeomAPI_Shape::FACE, aDeletedTag);
160
161     for(ListOfShape::const_iterator anIter = theTools.begin(); anIter != theTools.end(); anIter++) {
162       theResultBody->loadAndOrientModifiedShapes(aMkShape.get(), *anIter, GeomAPI_Shape::FACE,
163                                                  aModifyTag, aModName, *aMapOfShapes.get());
164       theResultBody->loadDeletedShapes(aMkShape.get(), *anIter, GeomAPI_Shape::FACE, aDeletedTag);
165     }
166   }
167 }