Salome HOME
Errors messages correction.
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_Extrusion.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 // File:        FeaturesPlugin_Extrusion.cpp
4 // Created:     30 May 2014
5 // Author:      Vitaly SMETANNIKOV
6
7 #include "FeaturesPlugin_Extrusion.h"
8
9 #include <ModelAPI_Session.h>
10 #include <ModelAPI_Validator.h>
11 #include <ModelAPI_ResultConstruction.h>
12 #include <ModelAPI_ResultBody.h>
13 #include <ModelAPI_AttributeDouble.h>
14 #include <ModelAPI_AttributeSelection.h>
15 #include <ModelAPI_AttributeSelectionList.h>
16 #include <ModelAPI_AttributeString.h>
17
18 #include <GeomAlgoAPI_CompoundBuilder.h>
19 #include <GeomAlgoAPI_Prism.h>
20 #include <GeomAlgoAPI_ShapeTools.h>
21
22 #include <sstream>
23
24 //=================================================================================================
25 FeaturesPlugin_Extrusion::FeaturesPlugin_Extrusion()
26 {
27 }
28
29 //=================================================================================================
30 void FeaturesPlugin_Extrusion::initAttributes()
31 {
32   AttributeSelectionListPtr aSelection = 
33     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
34     LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
35   // extrusion works with faces always
36   aSelection->setSelectionType("FACE");
37
38   data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
39
40   data()->addAttribute(TO_SIZE_ID(), ModelAPI_AttributeDouble::typeId());
41   data()->addAttribute(FROM_SIZE_ID(), ModelAPI_AttributeDouble::typeId());
42
43   data()->addAttribute(TO_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
44   data()->addAttribute(TO_OFFSET_ID(), ModelAPI_AttributeDouble::typeId());
45
46   data()->addAttribute(FROM_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
47   data()->addAttribute(FROM_OFFSET_ID(), ModelAPI_AttributeDouble::typeId());
48
49   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), TO_OBJECT_ID());
50   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), FROM_OBJECT_ID());
51 }
52
53 //=================================================================================================
54 void FeaturesPlugin_Extrusion::execute()
55 {
56   // Getting faces.
57   ListOfShape aFacesList;
58   AttributeSelectionListPtr aFacesSelectionList = selectionList(LIST_ID());
59   for(int anIndex = 0; anIndex < aFacesSelectionList->size(); anIndex++) {
60     AttributeSelectionPtr aFaceSel = aFacesSelectionList->value(anIndex);
61     std::shared_ptr<GeomAPI_Shape> aFaceShape = aFaceSel->value();
62     if(aFaceShape.get() && !aFaceShape->isNull()) { // Getting face.
63       aFacesList.push_back(aFaceShape);
64     } else { // This may be the whole sketch result selected, check and get faces.
65       ResultPtr aContext = aFaceSel->context();
66       std::shared_ptr<GeomAPI_Shape> aContextShape = aContext->shape();
67       if(!aContextShape.get()) {
68         static const std::string aContextError = "Error: The selection context is bad.";
69         setError(aContextError);
70         return;
71       }
72       ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
73       if(!aConstruction.get()) {
74         static const std::string aFaceError = "Error: Can not find basis for extrusion.";
75         setError(aFaceError);
76         return;
77       }
78       int aFacesNum = aConstruction->facesNum();
79       for(int aFaceIndex = 0; aFaceIndex < aFacesNum || aFacesNum == -1; aFaceIndex++) {
80         aFaceShape = std::dynamic_pointer_cast<GeomAPI_Shape>(aConstruction->face(aFaceIndex));
81         aFacesList.push_back(aFaceShape);
82       }
83     }
84   }
85
86   // Getting sizes.
87   double aToSize = 0.0;
88   double aFromSize = 0.0;
89
90   if(string(CREATION_METHOD())->value() == "BySizes") {
91     aToSize = real(TO_SIZE_ID())->value();
92     aFromSize =  real(FROM_SIZE_ID())->value();
93   } else {
94     aToSize = real(TO_OFFSET_ID())->value();
95     aFromSize =  real(FROM_OFFSET_ID())->value();
96   }
97
98   // Getting bounding planes.
99   std::shared_ptr<GeomAPI_Shape> aToShape;
100   std::shared_ptr<GeomAPI_Shape> aFromShape;
101
102   if(string(CREATION_METHOD())->value() == "ByPlanesAndOffsets") {
103     std::shared_ptr<ModelAPI_AttributeSelection> anObjRef = selection(TO_OBJECT_ID());
104     if(anObjRef.get() != NULL) {
105       aToShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
106       if(aToShape.get() == NULL && anObjRef->context().get() != NULL) {
107         aToShape =  anObjRef->context()->shape();
108       }
109     }
110     anObjRef = selection(FROM_OBJECT_ID());
111     if(anObjRef.get() != NULL) {
112       aFromShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
113       if(aFromShape.get() == NULL && anObjRef->context().get() != NULL) {
114         aFromShape = anObjRef->context()->shape();
115       }
116     }
117   }
118
119   // Searching faces with common edges.
120   ListOfShape aShells;
121   ListOfShape aFreeFaces;
122   std::shared_ptr<GeomAPI_Shape> aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aFacesList);
123   GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, aShells, aFreeFaces);
124   aShells.insert(aShells.end(), aFreeFaces.begin(), aFreeFaces.end());
125
126   // Generating result for each shell and face.
127   int aResultIndex = 0;
128   for(ListOfShape::const_iterator anIter = aShells.cbegin(); anIter != aShells.cend(); anIter++) {
129     std::shared_ptr<GeomAPI_Shape> aBaseShape = *anIter;
130
131     GeomAlgoAPI_Prism aPrismAlgo(aBaseShape, aToShape, aToSize, aFromShape, aFromSize);
132     if(!aPrismAlgo.isDone()) {
133       static const std::string aPrismAlgoError = "Error: Extrusion algorithm failed.";
134       setError(aPrismAlgoError);
135       aResultIndex = 0;
136       break;
137     }
138
139     // Check if shape is valid
140     if(!aPrismAlgo.shape().get() || aPrismAlgo.shape()->isNull()) {
141       static const std::string aShapeError = "Error: Resulting shape is Null.";
142       setError(aShapeError);
143       aResultIndex = 0;
144       break;
145     }
146     if(!aPrismAlgo.isValid()) {
147       std::string aPrismAlgoError = "Error: Resulting shape is not valid.";
148       setError(aPrismAlgoError);
149       aResultIndex = 0;
150       break;
151     }
152
153     ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
154     loadNamingDS(aPrismAlgo, aResultBody, aBaseShape);
155     setResult(aResultBody, aResultIndex);
156     aResultIndex++;
157   }
158
159   removeResults(aResultIndex);
160 }
161
162 //=================================================================================================
163 void FeaturesPlugin_Extrusion::loadNamingDS(GeomAlgoAPI_Prism& thePrismAlgo,
164                                             std::shared_ptr<ModelAPI_ResultBody> theResultBody,
165                                             std::shared_ptr<GeomAPI_Shape> theBasis)
166 {
167   //load result
168   theResultBody->storeGenerated(theBasis, thePrismAlgo.shape());
169
170   std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = thePrismAlgo.mapOfSubShapes();
171
172   //Insert lateral face : Face from Edge
173   const std::string aLatName = "LateralFace";
174   const int aLatTag = 1;
175   theResultBody->loadAndOrientGeneratedShapes(&thePrismAlgo, theBasis, GeomAPI_Shape::EDGE, aLatTag, aLatName, *aSubShapes);
176
177   //Insert to faces
178   int aToFaceIndex = 1;
179   const std::string aToName = "ToFace";
180   int aToTag = 2;
181   const ListOfShape& aToFaces = thePrismAlgo.toFaces();
182   for(ListOfShape::const_iterator anIt = aToFaces.cbegin(); anIt != aToFaces.cend(); anIt++) {
183     std::shared_ptr<GeomAPI_Shape> aToFace = *anIt;
184     if(aSubShapes->isBound(aToFace)) {
185       aToFace = aSubShapes->find(aToFace);
186     }
187     std::ostringstream aStr;
188     aStr << aToName << "_" << aToFaceIndex++;
189     theResultBody->generated(aToFace, aStr.str(), aToTag++);
190   }
191
192   //Insert from faces
193   int aFromFaceIndex = 1;
194   const std::string aFromName = "FromFace";
195   int aFromTag = aToTag > 10000 ? aToTag : 10000;
196   const ListOfShape& aFromFaces = thePrismAlgo.fromFaces();
197   for(ListOfShape::const_iterator anIt = aFromFaces.cbegin(); anIt != aFromFaces.cend(); anIt++) {
198     std::shared_ptr<GeomAPI_Shape> aFromFace = *anIt;
199     if(aSubShapes->isBound(aFromFace)) {
200       aFromFace = aSubShapes->find(aFromFace);
201     }
202     std::ostringstream aStr;
203     aStr << aFromName << "_" << aFromFaceIndex++;
204     theResultBody->generated(aFromFace, aStr.str(), aFromTag++);
205   }
206 }