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 aResultBody->generated(aV1, aV1History.front(), aGenName + "Edge_1", aGenTag++);
262 aResultBody->generated(aV2, aV2History.front(), aGenName + "Edge_2", aGenTag++);
264 case GeomAPI_Shape::FACE:
265 case GeomAPI_Shape::SHELL: {
266 aShapeTypeToExplode = GeomAPI_Shape::EDGE;
271 aResultBody->loadAndOrientGeneratedShapes(&thePipeAlgo, theBaseShape, aShapeTypeToExplode, aGenTag++, aGenName, *aMapOfSubShapes.get());
273 // Store from shapes.
274 int aFromTag = aGenTag;
275 storeShapes(aResultBody, aBaseShapeType, aMapOfSubShapes, thePipeAlgo.fromShapes(), "From_", aFromTag);
278 int aToTag = aFromTag;
279 storeShapes(aResultBody, aBaseShapeType, aMapOfSubShapes, thePipeAlgo.toShapes(), "To_", aToTag);
281 setResult(aResultBody, theResultIndex);
284 //=================================================================================================
285 void FeaturesPlugin_Pipe::storeResult(const ListOfShape& theBaseShapes,
286 GeomAlgoAPI_Pipe& thePipeAlgo,
287 const int theResultIndex)
289 // Create result body.
290 ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
292 // Store generated shape.
293 aResultBody->storeGenerated(theBaseShapes.front(), thePipeAlgo.shape());
295 // Store generated edges/faces.
297 std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfSubShapes = thePipeAlgo.mapOfSubShapes();
299 for(ListOfShape::const_iterator anIter = theBaseShapes.cbegin(); anIter != theBaseShapes.cend(); anIter++) {
300 GeomShapePtr aBaseShape = *anIter;
301 GeomAPI_Shape::ShapeType aBaseShapeType = aBaseShape->shapeType();
302 GeomAPI_Shape::ShapeType aShapeTypeToExplode;
303 std::string aGenName = "Generated_";
304 switch(aBaseShapeType) {
305 case GeomAPI_Shape::VERTEX: {
306 aShapeTypeToExplode = GeomAPI_Shape::VERTEX;
310 case GeomAPI_Shape::EDGE:
311 case GeomAPI_Shape::WIRE: {
312 std::shared_ptr<GeomAPI_Vertex> aV1, aV2;
313 GeomAlgoAPI_ShapeTools::findBounds(aBaseShape, aV1, aV2);
314 ListOfShape aV1History, aV2History;
315 thePipeAlgo.generated(aV1, aV1History);
316 thePipeAlgo.generated(aV2, aV2History);
317 aResultBody->generated(aV1, aV1History.front(), aGenName + "Edge_1", aGenTag++);
318 aResultBody->generated(aV2, aV2History.front(), aGenName + "Edge_2", aGenTag++);
320 case GeomAPI_Shape::FACE:
321 case GeomAPI_Shape::SHELL: {
322 aShapeTypeToExplode = GeomAPI_Shape::EDGE;
327 aResultBody->loadAndOrientGeneratedShapes(&thePipeAlgo, aBaseShape, aShapeTypeToExplode, aGenTag++, aGenName, *aMapOfSubShapes.get());
330 // Store from shapes.
331 int aFromTag = aGenTag;
332 storeShapes(aResultBody, theBaseShapes.front()->shapeType(), aMapOfSubShapes, thePipeAlgo.fromShapes(), "From", aFromTag);
335 int aToTag = aFromTag;
336 storeShapes(aResultBody, theBaseShapes.back()->shapeType(), aMapOfSubShapes, thePipeAlgo.toShapes(), "To", aToTag);
339 setResult(aResultBody, theResultIndex);
342 //=================================================================================================
343 void FeaturesPlugin_Pipe::storeShapes(ResultBodyPtr theResultBody,
344 const GeomAPI_Shape::ShapeType theBaseShapeType,
345 const std::shared_ptr<GeomAPI_DataMapOfShapeShape> theMapOfSubShapes,
346 const ListOfShape& theShapes,
347 const std::string theName,
350 GeomAPI_Shape::ShapeType aShapeTypeToExplore = GeomAPI_Shape::FACE;
351 std::string aShapeTypeStr = "Face";
352 switch(theBaseShapeType) {
353 case GeomAPI_Shape::VERTEX: {
354 aShapeTypeToExplore = GeomAPI_Shape::VERTEX;
355 aShapeTypeStr = "Vertex";
358 case GeomAPI_Shape::EDGE:
359 case GeomAPI_Shape::WIRE: {
360 aShapeTypeToExplore = GeomAPI_Shape::EDGE;
361 aShapeTypeStr = "Edge";
364 case GeomAPI_Shape::FACE:
365 case GeomAPI_Shape::SHELL: {
366 aShapeTypeToExplore = GeomAPI_Shape::FACE;
367 aShapeTypeStr = "Face";
374 std::string aName = theName + aShapeTypeStr;
375 for(ListOfShape::const_iterator anIt = theShapes.cbegin(); anIt != theShapes.cend(); ++anIt) {
376 std::shared_ptr<GeomAPI_Shape> aShape = *anIt;
377 for(GeomAPI_ShapeExplorer anExp(aShape, aShapeTypeToExplore); anExp.more(); anExp.next()) {
378 std::shared_ptr<GeomAPI_Shape> aSubShape = anExp.current();
379 if(theMapOfSubShapes->isBound(aSubShape)) {
380 aSubShape = theMapOfSubShapes->find(aSubShape);
382 std::ostringstream aStr;
383 aStr << aName << "_" << aShapeIndex++;
384 theResultBody->generated(aSubShape, aStr.str(), theTag++);