1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
3 // File: FeaturesPlugin_Pipe.cpp
4 // Created: 16 March 2016
5 // Author: Dmitry Bobylev
7 #include "FeaturesPlugin_Pipe.h"
9 #include <ModelAPI_AttributeSelection.h>
10 #include <ModelAPI_AttributeSelectionList.h>
11 #include <ModelAPI_AttributeString.h>
12 #include <ModelAPI_ResultConstruction.h>
13 #include <ModelAPI_Session.h>
14 #include <ModelAPI_Validator.h>
16 #include <GeomAlgoAPI_CompoundBuilder.h>
17 #include <GeomAlgoAPI_Pipe.h>
18 #include <GeomAPI_ShapeExplorer.h>
19 #include <GeomAlgoAPI_ShapeTools.h>
23 //=================================================================================================
24 FeaturesPlugin_Pipe::FeaturesPlugin_Pipe()
28 //=================================================================================================
29 void FeaturesPlugin_Pipe::initAttributes()
31 data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
33 data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
34 data()->addAttribute(PATH_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
36 data()->addAttribute(BINORMAL_ID(), ModelAPI_AttributeSelection::typeId());
38 data()->addAttribute(LOCATIONS_ID(), ModelAPI_AttributeSelectionList::typeId());
39 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), LOCATIONS_ID());
42 //=================================================================================================
43 void FeaturesPlugin_Pipe::execute()
45 // Getting creation method.
46 std::string aCreationMethod = string(CREATION_METHOD())->value();
48 // Getting base objects.
49 ListOfShape aBaseShapesList, aBaseFacesList;
50 AttributeSelectionListPtr aBaseObjectsSelectionList = selectionList(BASE_OBJECTS_ID());
51 if(!aBaseObjectsSelectionList.get()) {
52 setError("Error: Could not get base objects selection list.");
55 if(aBaseObjectsSelectionList->size() == 0) {
56 setError("Error: Base objects list is empty.");
59 for(int anIndex = 0; anIndex < aBaseObjectsSelectionList->size(); anIndex++) {
60 AttributeSelectionPtr aBaseObjectSelection = aBaseObjectsSelectionList->value(anIndex);
61 if(!aBaseObjectSelection.get()) {
62 setError("Error: One of the selected base objects is empty.");
65 std::shared_ptr<GeomAPI_Shape> aBaseShape = aBaseObjectSelection->value();
66 if(aBaseShape.get() && !aBaseShape->isNull()) {
67 aBaseShape->shapeType() == GeomAPI_Shape::FACE ? aBaseFacesList.push_back(aBaseShape) :
68 aBaseShapesList.push_back(aBaseShape);
70 // This may be the whole sketch result selected, check and get faces.
71 ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aBaseObjectSelection->context());
72 if(!aConstruction.get()) {
73 setError("Error: One of selected sketches does not have results.");
76 int aFacesNum = aConstruction->facesNum();
78 // Probably it can be construction.
79 aBaseShape = aConstruction->shape();
80 if(aBaseShape.get() && !aBaseShape->isNull()) {
81 aBaseShape->shapeType() == GeomAPI_Shape::FACE ? aBaseFacesList.push_back(aBaseShape) :
82 aBaseShapesList.push_back(aBaseShape);
85 for(int aFaceIndex = 0; aFaceIndex < aFacesNum; aFaceIndex++) {
86 std::shared_ptr<GeomAPI_Shape> aBaseFace = std::dynamic_pointer_cast<GeomAPI_Shape>(aConstruction->face(aFaceIndex));
87 if(!aBaseFace.get() || aBaseFace->isNull()) {
88 setError("Error: One of the faces on selected sketch is Null.");
91 aBaseFacesList.push_back(aBaseFace);
97 // Searching faces with common edges.
98 if(aCreationMethod == "simple") {
100 ListOfShape aFreeFaces;
101 std::shared_ptr<GeomAPI_Shape> aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseFacesList);
102 GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, aShells, aFreeFaces);
103 aBaseShapesList.insert(aBaseShapesList.end(), aFreeFaces.begin(), aFreeFaces.end());
104 aBaseShapesList.insert(aBaseShapesList.end(), aShells.begin(), aShells.end());
106 aBaseShapesList.insert(aBaseShapesList.end(), aBaseFacesList.begin(), aBaseFacesList.end());
110 AttributeSelectionPtr aPathSelection = selection(PATH_OBJECT_ID());
111 if(!aPathSelection.get()) {
112 setError("Error: Path selection is empty.");
115 std::shared_ptr<GeomAPI_Shape> aPathShape = std::dynamic_pointer_cast<GeomAPI_Shape>(aPathSelection->value());
116 if(!aPathShape.get()) {
117 // Probaply it is a construction.
118 aPathShape = aPathSelection->context()->shape();
120 if(!aPathShape.get() || aPathShape->isNull()) {
121 setError("Error: Path shape is null.");
126 std::shared_ptr<GeomAPI_Shape> aBiNormal;
127 if(aCreationMethod == "binormal") {
128 AttributeSelectionPtr aBiNormalSelection = selection(BINORMAL_ID());
129 if(!aBiNormalSelection.get()) {
130 setError("Error: Bi-Normal selection is empty.");
133 aBiNormal = std::dynamic_pointer_cast<GeomAPI_Shape>(aBiNormalSelection->value());
134 if(!aBiNormal.get()) {
135 // Probably it is a construction.
136 aBiNormal = aBiNormalSelection->context()->shape();
138 if(!aBiNormal.get() || aBiNormal->isNull()) {
139 setError("Error: Bi-Normal shape is null.");
144 // Getting locations.
145 ListOfShape aLocations;
146 if(aCreationMethod == "locations") {
147 AttributeSelectionListPtr aLocationsSelectionList = selectionList(LOCATIONS_ID());
148 if(!aLocationsSelectionList.get()) {
149 setError("Error: Could not get locations selection list.");
152 for(int anIndex = 0; anIndex < aLocationsSelectionList->size(); anIndex++) {
153 AttributeSelectionPtr aLocationSelection = aLocationsSelectionList->value(anIndex);
154 if(!aLocationSelection.get()) {
155 setError("Error: One of the selected location is empty.");
158 std::shared_ptr<GeomAPI_Shape> aLocationShape = aLocationSelection->value();
159 if(!aLocationShape.get()) {
160 // Probably it is a construction.
161 aLocationShape = aLocationSelection->context()->shape();
163 if(!aLocationShape.get() || aLocationShape->isNull()) {
164 setError("Error: One of the selected location shape is null.");
167 aLocations.push_back(aLocationShape);
171 // Generating result for each object.
172 int aResultIndex = 0;
173 if(aCreationMethod == "simple" || aCreationMethod == "binormal") {
174 for(ListOfShape::const_iterator anIter = aBaseShapesList.cbegin(); anIter != aBaseShapesList.cend(); anIter++) {
175 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anIter;
177 GeomAlgoAPI_Pipe aPipeAlgo = aCreationMethod == "simple" ? GeomAlgoAPI_Pipe(aBaseShape, aPathShape) :
178 GeomAlgoAPI_Pipe(aBaseShape, aPathShape, aBiNormal);
180 if(!aPipeAlgo.isDone()) {
181 setError("Error: Pipe algorithm failed.");
186 // Check if shape is valid
187 if(!aPipeAlgo.shape().get() || aPipeAlgo.shape()->isNull()) {
188 setError("Error: Resulting shape is Null.");
192 if(!aPipeAlgo.isValid()) {
193 setError("Error: Resulting shape is not valid.");
198 storeResult(aBaseShape, aPipeAlgo, aResultIndex++);
200 } else if(aCreationMethod == "locations") {
201 GeomAlgoAPI_Pipe aPipeAlgo = GeomAlgoAPI_Pipe(aBaseShapesList, aLocations, aPathShape);
203 if(!aPipeAlgo.isDone()) {
204 setError("Error: Pipe algorithm failed.");
209 // Check if shape is valid
210 if(!aPipeAlgo.shape().get() || aPipeAlgo.shape()->isNull()) {
211 setError("Error: Resulting shape is Null.");
215 if(!aPipeAlgo.isValid()) {
216 setError("Error: Resulting shape is not valid.");
221 storeResult(aBaseShapesList, aPipeAlgo, aResultIndex++);
223 setError("Error: Wrong creation method.");
227 removeResults(aResultIndex);
230 //=================================================================================================
231 void FeaturesPlugin_Pipe::storeResult(const std::shared_ptr<GeomAPI_Shape> theBaseShape,
232 GeomAlgoAPI_Pipe& thePipeAlgo,
233 const int theResultIndex)
235 // Create result body.
236 ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
238 // Store generated shape.
239 aResultBody->storeGenerated(theBaseShape, thePipeAlgo.shape());
241 // Store generated edges/faces.
242 GeomAPI_Shape::ShapeType aBaseShapeType = theBaseShape->shapeType();
243 GeomAPI_Shape::ShapeType aShapeTypeToExplode;
245 std::string aGenName = "Generated_";
247 std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfSubShapes = thePipeAlgo.mapOfSubShapes();
248 switch(aBaseShapeType) {
249 case GeomAPI_Shape::VERTEX: {
250 aShapeTypeToExplode = GeomAPI_Shape::VERTEX;
254 case GeomAPI_Shape::EDGE:
255 case GeomAPI_Shape::WIRE: {
256 std::shared_ptr<GeomAPI_Vertex> aV1, aV2;
257 GeomAlgoAPI_ShapeTools::findBounds(theBaseShape, aV1, aV2);
258 ListOfShape aV1History, aV2History;
259 thePipeAlgo.generated(aV1, aV1History);
260 thePipeAlgo.generated(aV2, aV2History);
261 if(!aV1History.empty()) {
262 aResultBody->generated(aV1, aV1History.front(), aGenName + "Edge_1", aGenTag++);
264 if(!aV2History.empty()) {
265 aResultBody->generated(aV2, aV2History.front(), aGenName + "Edge_2", aGenTag++);
268 case GeomAPI_Shape::FACE:
269 case GeomAPI_Shape::SHELL: {
270 aShapeTypeToExplode = GeomAPI_Shape::EDGE;
275 aResultBody->loadAndOrientGeneratedShapes(&thePipeAlgo, theBaseShape, aShapeTypeToExplode, aGenTag++, aGenName, *aMapOfSubShapes.get());
277 // Store from shapes.
278 int aFromTag = aGenTag;
279 storeShapes(aResultBody, aBaseShapeType, aMapOfSubShapes, thePipeAlgo.fromShapes(), "From_", aFromTag);
282 int aToTag = aFromTag;
283 storeShapes(aResultBody, aBaseShapeType, aMapOfSubShapes, thePipeAlgo.toShapes(), "To_", aToTag);
285 setResult(aResultBody, theResultIndex);
288 //=================================================================================================
289 void FeaturesPlugin_Pipe::storeResult(const ListOfShape& theBaseShapes,
290 GeomAlgoAPI_Pipe& thePipeAlgo,
291 const int theResultIndex)
293 // Create result body.
294 ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
296 // Store generated shape.
297 aResultBody->storeGenerated(theBaseShapes.front(), thePipeAlgo.shape());
299 // Store generated edges/faces.
301 std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfSubShapes = thePipeAlgo.mapOfSubShapes();
303 for(ListOfShape::const_iterator anIter = theBaseShapes.cbegin(); anIter != theBaseShapes.cend(); anIter++) {
304 GeomShapePtr aBaseShape = *anIter;
305 GeomAPI_Shape::ShapeType aBaseShapeType = aBaseShape->shapeType();
306 GeomAPI_Shape::ShapeType aShapeTypeToExplode;
307 std::string aGenName = "Generated_";
308 switch(aBaseShapeType) {
309 case GeomAPI_Shape::VERTEX: {
310 aShapeTypeToExplode = GeomAPI_Shape::VERTEX;
314 case GeomAPI_Shape::EDGE:
315 case GeomAPI_Shape::WIRE: {
316 std::shared_ptr<GeomAPI_Vertex> aV1, aV2;
317 GeomAlgoAPI_ShapeTools::findBounds(aBaseShape, aV1, aV2);
318 ListOfShape aV1History, aV2History;
319 thePipeAlgo.generated(aV1, aV1History);
320 thePipeAlgo.generated(aV2, aV2History);
321 aResultBody->generated(aV1, aV1History.front(), aGenName + "Edge_1", aGenTag++);
322 aResultBody->generated(aV2, aV2History.front(), aGenName + "Edge_2", aGenTag++);
324 case GeomAPI_Shape::FACE:
325 case GeomAPI_Shape::SHELL: {
326 aShapeTypeToExplode = GeomAPI_Shape::EDGE;
331 aResultBody->loadAndOrientGeneratedShapes(&thePipeAlgo, aBaseShape, aShapeTypeToExplode, aGenTag++, aGenName, *aMapOfSubShapes.get());
334 // Store from shapes.
335 int aFromTag = aGenTag;
336 storeShapes(aResultBody, theBaseShapes.front()->shapeType(), aMapOfSubShapes, thePipeAlgo.fromShapes(), "From", aFromTag);
339 int aToTag = aFromTag;
340 storeShapes(aResultBody, theBaseShapes.back()->shapeType(), aMapOfSubShapes, thePipeAlgo.toShapes(), "To", aToTag);
343 setResult(aResultBody, theResultIndex);
346 //=================================================================================================
347 void FeaturesPlugin_Pipe::storeShapes(ResultBodyPtr theResultBody,
348 const GeomAPI_Shape::ShapeType theBaseShapeType,
349 const std::shared_ptr<GeomAPI_DataMapOfShapeShape> theMapOfSubShapes,
350 const ListOfShape& theShapes,
351 const std::string theName,
354 GeomAPI_Shape::ShapeType aShapeTypeToExplore = GeomAPI_Shape::FACE;
355 std::string aShapeTypeStr = "Face";
356 switch(theBaseShapeType) {
357 case GeomAPI_Shape::VERTEX: {
358 aShapeTypeToExplore = GeomAPI_Shape::VERTEX;
359 aShapeTypeStr = "Vertex";
362 case GeomAPI_Shape::EDGE:
363 case GeomAPI_Shape::WIRE: {
364 aShapeTypeToExplore = GeomAPI_Shape::EDGE;
365 aShapeTypeStr = "Edge";
368 case GeomAPI_Shape::FACE:
369 case GeomAPI_Shape::SHELL: {
370 aShapeTypeToExplore = GeomAPI_Shape::FACE;
371 aShapeTypeStr = "Face";
378 std::string aName = theName + aShapeTypeStr;
379 for(ListOfShape::const_iterator anIt = theShapes.cbegin(); anIt != theShapes.cend(); ++anIt) {
380 std::shared_ptr<GeomAPI_Shape> aShape = *anIt;
381 for(GeomAPI_ShapeExplorer anExp(aShape, aShapeTypeToExplore); anExp.more(); anExp.next()) {
382 std::shared_ptr<GeomAPI_Shape> aSubShape = anExp.current();
383 if(theMapOfSubShapes->isBound(aSubShape)) {
384 aSubShape = theMapOfSubShapes->find(aSubShape);
386 std::ostringstream aStr;
387 aStr << aName << "_" << aShapeIndex++;
388 theResultBody->generated(aSubShape, aStr.str(), theTag++);