1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
3 // File: FeaturesPlugin_Extrusion.cpp
4 // Created: 30 May 2014
5 // Author: Vitaly SMETANNIKOV
7 #include <FeaturesPlugin_Extrusion.h>
9 #include <ModelAPI_BodyBuilder.h>
10 #include <ModelAPI_Session.h>
11 #include <ModelAPI_Validator.h>
12 #include <ModelAPI_Document.h>
13 #include <ModelAPI_Data.h>
14 #include <ModelAPI_ResultConstruction.h>
15 #include <ModelAPI_ResultCompSolid.h>
16 #include <ModelAPI_ResultBody.h>
17 #include <ModelAPI_AttributeDouble.h>
18 #include <ModelAPI_AttributeSelection.h>
19 #include <ModelAPI_AttributeSelectionList.h>
20 #include <ModelAPI_AttributeBoolean.h>
21 #include <ModelAPI_AttributeString.h>
22 #include <ModelAPI_AttributeReference.h>
24 #include <GeomAlgoAPI_CompoundBuilder.h>
25 #include <GeomAlgoAPI_Prism.h>
26 #include <GeomAlgoAPI_ShapeTools.h>
28 //=================================================================================================
29 FeaturesPlugin_Extrusion::FeaturesPlugin_Extrusion()
33 //=================================================================================================
34 void FeaturesPlugin_Extrusion::initAttributes()
36 AttributeSelectionListPtr aSelection =
37 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(data()->addAttribute(
38 LIST_ID(), ModelAPI_AttributeSelectionList::typeId()));
39 // extrusion works with faces always
40 aSelection->setSelectionType("FACE");
42 data()->addAttribute(CREATION_METHOD(), ModelAPI_AttributeString::typeId());
44 data()->addAttribute(TO_SIZE_ID(), ModelAPI_AttributeDouble::typeId());
45 data()->addAttribute(FROM_SIZE_ID(), ModelAPI_AttributeDouble::typeId());
47 data()->addAttribute(TO_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
48 data()->addAttribute(TO_OFFSET_ID(), ModelAPI_AttributeDouble::typeId());
50 data()->addAttribute(FROM_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
51 data()->addAttribute(FROM_OFFSET_ID(), ModelAPI_AttributeDouble::typeId());
53 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), TO_OBJECT_ID());
54 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), FROM_OBJECT_ID());
57 //=================================================================================================
58 void FeaturesPlugin_Extrusion::execute()
61 ListOfShape aFacesList;
62 AttributeSelectionListPtr aFacesSelectionList = selectionList(LIST_ID());
63 for(int anIndex = 0; anIndex < aFacesSelectionList->size(); anIndex++) {
64 std::shared_ptr<ModelAPI_AttributeSelection> aFaceSel = aFacesSelectionList->value(anIndex);
65 ResultPtr aContext = aFaceSel->context();
66 std::shared_ptr<GeomAPI_Shape> aContextShape = aContext->shape();
67 if(!aContextShape.get()) {
68 static const std::string aContextError = "The selection context is bad";
69 setError(aContextError);
73 std::shared_ptr<GeomAPI_Shape> aFaceShape = aFaceSel->value();
74 int aFacesNum = -1; // this mean that "aFace" is used
75 ResultConstructionPtr aConstruction =
76 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
77 if(!aFaceShape.get()) { // this may be the whole sketch result selected, check and get faces
78 if (aConstruction.get()) {
79 aFacesNum = aConstruction->facesNum();
81 static const std::string aFaceError = "Can not find basis for extrusion";
86 for(int aFaceIndex = 0; aFaceIndex < aFacesNum || aFacesNum == -1; aFaceIndex++) {
87 std::shared_ptr<GeomAPI_Shape> aBaseShape;
88 if (aFacesNum == -1) {
89 aFacesList.push_back(aFaceShape);
92 aFaceShape = std::dynamic_pointer_cast<GeomAPI_Shape>(aConstruction->face(aFaceIndex));
93 aFacesList.push_back(aFaceShape);
100 double aFromSize = 0.0;
102 if(string(CREATION_METHOD())->value() == "BySizes") {
103 aToSize = real(TO_SIZE_ID())->value();
104 aFromSize = real(FROM_SIZE_ID())->value();
106 aToSize = real(TO_OFFSET_ID())->value();
107 aFromSize = real(FROM_OFFSET_ID())->value();
110 // Getting bounding planes.
111 std::shared_ptr<GeomAPI_Shape> aToShape;
112 std::shared_ptr<GeomAPI_Shape> aFromShape;
114 if(string(CREATION_METHOD())->value() == "ByPlanesAndOffsets") {
115 std::shared_ptr<ModelAPI_AttributeSelection> anObjRef = selection(TO_OBJECT_ID());
116 if(anObjRef.get() != NULL) {
117 aToShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
118 if(aToShape.get() == NULL && anObjRef->context().get() != NULL) {
119 aToShape = anObjRef->context()->shape();
122 anObjRef = selection(FROM_OBJECT_ID());
123 if(anObjRef.get() != NULL) {
124 aFromShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
125 if(aFromShape.get() == NULL && anObjRef->context().get() != NULL) {
126 aFromShape = anObjRef->context()->shape();
131 // Searching faces with common edges.
133 ListOfShape aFreeFaces;
134 std::shared_ptr<GeomAPI_Shape> aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aFacesList);
135 GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, aShells, aFreeFaces);
136 if(aShells.empty()) {
137 aShells = aFreeFaces;
139 aShells.merge(aFreeFaces);
142 // Generating result for each shell and face.
143 int aResultIndex = 0;
144 for(ListOfShape::const_iterator anIter = aShells.cbegin(); anIter != aShells.cend(); anIter++) {
145 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anIter;
147 GeomAlgoAPI_Prism aPrismAlgo(aBaseShape, aToShape, aToSize, aFromShape, aFromSize);
148 if(!aPrismAlgo.isDone()) {
149 static const std::string aPrismAlgoError = "Extrusion algorithm failed";
150 setError(aPrismAlgoError);
155 // Check if shape is valid
156 if(!aPrismAlgo.shape().get() || aPrismAlgo.shape()->isNull()) {
157 static const std::string aShapeError = "Resulting shape is Null";
158 setError(aShapeError);
162 if(!aPrismAlgo.isValid()) {
163 std::string aPrismAlgoError = "Warning: resulting shape is not valid";
164 setError(aPrismAlgoError);
169 ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
170 loadNamingDS(aPrismAlgo, aResultBody, aBaseShape);
171 setResult(aResultBody, aResultIndex);
175 removeResults(aResultIndex);
178 //=================================================================================================
179 void FeaturesPlugin_Extrusion::loadNamingDS(GeomAlgoAPI_Prism& thePrismAlgo,
180 std::shared_ptr<ModelAPI_ResultBody> theResultBody,
181 std::shared_ptr<GeomAPI_Shape> theBasis)
184 theResultBody->storeGenerated(theBasis, thePrismAlgo.shape());
186 std::shared_ptr<GeomAPI_DataMapOfShapeShape> aSubShapes = thePrismAlgo.mapOfShapes();
188 //Insert lateral face : Face from Edge
189 const std::string aLatName = "LateralFace";
190 const int aLatTag = 1;
191 theResultBody->loadAndOrientGeneratedShapes(thePrismAlgo.makeShape().get(), theBasis, GeomAPI_Shape::EDGE, aLatTag, aLatName, *aSubShapes);
194 const std::string aToName = "ToFace";
195 const int aToTag = 2;
196 const ListOfShape& aToFaces = thePrismAlgo.toFaces();
197 for(ListOfShape::const_iterator anIt = aToFaces.cbegin(); anIt != aToFaces.cend(); anIt++) {
198 std::shared_ptr<GeomAPI_Shape> aToFace = *anIt;
199 if(aSubShapes->isBound(aToFace)) {
200 aToFace = aSubShapes->find(aToFace);
202 theResultBody->generated(aToFace, aToName, aToTag);
206 const std::string aFromName = "FromFace";
207 const int aFromTag = 3;
208 const ListOfShape& aFromFaces = thePrismAlgo.fromFaces();
209 for(ListOfShape::const_iterator anIt = aFromFaces.cbegin(); anIt != aFromFaces.cend(); anIt++) {
210 std::shared_ptr<GeomAPI_Shape> aFromFace = *anIt;
211 if(aSubShapes->isBound(aFromFace)) {
212 aFromFace = aSubShapes->find(aFromFace);
214 theResultBody->generated(aFromFace, aFromName, aFromTag);