Salome HOME
73153a340762edd37adf7744a828970ba3ecad0d
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_Intersection.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 // File:        FeaturesPlugin_Intersection.cpp
4 // Created:     15 Feb 2016
5 // Author:      Dmitry Bobylev
6
7 #include "FeaturesPlugin_Intersection.h"
8
9 #include <ModelAPI_Data.h>
10 #include <ModelAPI_Document.h>
11 #include <ModelAPI_BodyBuilder.h>
12 #include <ModelAPI_ResultBody.h>
13 #include <ModelAPI_AttributeSelectionList.h>
14
15 #include <GeomAlgoAPI_Intersection.h>
16 #include <GeomAPI_ShapeExplorer.h>
17
18 #include <sstream>
19
20 //=================================================================================================
21 FeaturesPlugin_Intersection::FeaturesPlugin_Intersection()
22 {
23 }
24
25 //=================================================================================================
26 void FeaturesPlugin_Intersection::initAttributes()
27 {
28   data()->addAttribute(FeaturesPlugin_Intersection::OBJECT_LIST_ID(),
29                        ModelAPI_AttributeSelectionList::typeId());
30   data()->addAttribute(FeaturesPlugin_Intersection::TOOL_LIST_ID(),
31                        ModelAPI_AttributeSelectionList::typeId());
32 }
33
34 //=================================================================================================
35 void FeaturesPlugin_Intersection::execute()
36 {
37   ListOfShape anObjects, aTools;
38
39   // Getting objects.
40   AttributeSelectionListPtr anObjectsSelList =
41     selectionList(FeaturesPlugin_Intersection::OBJECT_LIST_ID());
42   for (int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
43     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr =
44       anObjectsSelList->value(anObjectsIndex);
45     std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
46     if (!anObject.get()) {
47       return;
48     }
49     anObjects.push_back(anObject);
50   }
51
52   // Getting tools.
53   AttributeSelectionListPtr aToolsSelList =
54     selectionList(FeaturesPlugin_Intersection::TOOL_LIST_ID());
55   for (int aToolsIndex = 0; aToolsIndex < aToolsSelList->size(); aToolsIndex++) {
56     std::shared_ptr<ModelAPI_AttributeSelection> aToolAttr = aToolsSelList->value(aToolsIndex);
57     std::shared_ptr<GeomAPI_Shape> aTool = aToolAttr->value();
58     if (!aTool.get()) {
59       return;
60     }
61     aTools.push_back(aTool);
62   }
63
64   if(anObjects.empty() || aTools.empty()) {
65     setError("Error: Objects or tools are empty.");
66     return;
67   }
68
69   int aResultIndex = 0;
70
71   // Create result for each object.
72   for (ListOfShape::iterator
73        anObjectsIt = anObjects.begin(); anObjectsIt != anObjects.end(); anObjectsIt++) {
74     std::shared_ptr<GeomAPI_Shape> anObject = *anObjectsIt;
75     ListOfShape aListWithObject; aListWithObject.push_back(anObject);
76     GeomAlgoAPI_Intersection anIntersectionAlgo(aListWithObject, aTools);
77
78     // Checking that the algorithm worked properly.
79     if (!anIntersectionAlgo.isDone()) {
80       static const std::string aFeatureError = "Error: Intersection algorithm failed.";
81       setError(aFeatureError);
82       return;
83     }
84     if (anIntersectionAlgo.shape()->isNull()) {
85       static const std::string aShapeError = "Error: Resulting shape is Null.";
86       setError(aShapeError);
87       return;
88     }
89     if (!anIntersectionAlgo.isValid()) {
90       std::string aFeatureError = "Error: Resulting shape is not valid.";
91       setError(aFeatureError);
92       return;
93     }
94
95     std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data(), aResultIndex);
96     loadNamingDS(aResultBody, anObject, aTools, anIntersectionAlgo);
97     setResult(aResultBody, aResultIndex);
98     aResultIndex++;
99   }
100
101   // remove the rest results if there were produced in the previous pass
102   removeResults(aResultIndex);
103 }
104
105 //=================================================================================================
106 void FeaturesPlugin_Intersection::loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
107                                                const std::shared_ptr<GeomAPI_Shape> theBaseShape,
108                                                const ListOfShape& theTools,
109                                                GeomAlgoAPI_MakeShape& theMakeShape)
110 {
111   std::shared_ptr<GeomAPI_Shape> aResultShape = theMakeShape.shape();
112   theResultBody->storeModified(theBaseShape, aResultShape);
113
114   const int aDeletedVertexTag = 1;
115   const int aDeletedEdgeTag   = 2;
116   const int aDeletedFaceTag   = 3;
117
118   theResultBody->loadDeletedShapes(&theMakeShape,
119                                    theBaseShape,
120                                    GeomAPI_Shape::VERTEX,
121                                    aDeletedVertexTag);
122   theResultBody->loadDeletedShapes(&theMakeShape,
123                                    theBaseShape,
124                                    GeomAPI_Shape::EDGE,
125                                    aDeletedEdgeTag);
126   theResultBody->loadDeletedShapes(&theMakeShape,
127                                    theBaseShape,
128                                    GeomAPI_Shape::FACE,
129                                    aDeletedFaceTag);
130
131   ListOfShape aShapes = theTools;
132   aShapes.push_back(theBaseShape);
133   GeomAPI_DataMapOfShapeShape aShapesMap; // Map to store {result_shape, original_shape}
134   const int aShapeTypesNb = 2;
135   const GeomAPI_Shape::ShapeType aShapeTypes[aShapeTypesNb] = {GeomAPI_Shape::VERTEX, GeomAPI_Shape::EDGE};
136   for(ListOfShape::const_iterator anIt = aShapes.cbegin(); anIt != aShapes.cend(); ++anIt) {
137     const GeomShapePtr aShape = *anIt;
138     for(int anIndex = 0; anIndex < aShapeTypesNb; ++anIndex) {
139       for(GeomAPI_ShapeExplorer anOrigShapeExp(aShape, aShapeTypes[anIndex]);
140           anOrigShapeExp.more();
141           anOrigShapeExp.next()) {
142         ListOfShape aHistory;
143         const GeomShapePtr aSubShape = anOrigShapeExp.current();
144         theMakeShape.modified(aSubShape, aHistory);
145         for(ListOfShape::const_iterator aHistoryIt = aHistory.cbegin();
146             aHistoryIt != aHistory.cend();
147             ++aHistoryIt) {
148           aShapesMap.bind(*aHistoryIt, aSubShape);
149         }
150       }
151     }
152   }
153
154   int aModifiedVertexIndex(1),
155       aGeneratedVertexIndex(1),
156       aModifiedEdgeIndex(1),
157       aGeneratedEdgeIndex(1);
158   int aTag = 4;
159   GeomAPI_DataMapOfShapeShape aStoredShapes;
160   for(int anIndex = 0; anIndex < aShapeTypesNb; ++anIndex) {
161     for(GeomAPI_ShapeExplorer aShapeExp(aResultShape, aShapeTypes[anIndex]);
162         aShapeExp.more();
163         aShapeExp.next()) {
164       const GeomShapePtr aSubShape = aShapeExp.current();
165       if(aStoredShapes.isBound(aSubShape)) {
166         continue;
167       }
168       if(aShapesMap.isBound(aSubShape)) {
169         theResultBody->modified(aShapesMap.find(aSubShape),
170           aSubShape,
171           std::string("Modified_")
172             + (anIndex == 0 ? "Vertex_" : "Edge_")
173             + std::to_string((long long)(anIndex == 0 ? aModifiedVertexIndex++
174                                                       : aModifiedEdgeIndex++)),
175           aTag++);
176       } else {
177         theResultBody->generated(aSubShape,
178           std::string("Generated_")
179             + (anIndex == 0 ? "Vertex_" : "Edge_")
180             + std::to_string((long long)(anIndex == 0 ? aGeneratedVertexIndex++
181                                                       : aGeneratedEdgeIndex++)),
182           aTag++);
183       }
184       aStoredShapes.bind(aSubShape, aSubShape);
185     }
186   }
187 }