Salome HOME
2f8704e023c1cb75e023ee3bc4df472ccbac3a29
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_ExtrusionCut.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        FeaturesPlugin_ExtrusionCut.cpp
4 // Created:     12 May 2015
5 // Author:      Dmitry Bobylev
6
7 #include <FeaturesPlugin_ExtrusionCut.h>
8
9 #include <ModelAPI_AttributeDouble.h>
10 #include <ModelAPI_AttributeSelectionList.h>
11 #include <ModelAPI_AttributeReference.h>
12 #include <ModelAPI_Validator.h>
13 #include <ModelAPI_Session.h>
14 #include <ModelAPI_Data.h>
15 #include <ModelAPI_AttributeRefList.h>
16 #include <ModelAPI_ResultBody.h>
17 #include <ModelAPI_ResultConstruction.h>
18
19 #include <GeomAlgoAPI_Boolean.h>
20 #include <GeomAlgoAPI_Prism.h>
21 #include <GeomAlgoAPI_ShapeProps.h>
22
23 //=================================================================================================
24 FeaturesPlugin_ExtrusionCut::FeaturesPlugin_ExtrusionCut()
25 {
26 }
27
28 //=================================================================================================
29 void FeaturesPlugin_ExtrusionCut::initAttributes()
30 {
31
32   data()->addAttribute(SKETCH_OBJECT_ID(), ModelAPI_AttributeReference::typeId());
33
34   data()->addAttribute(FROM_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
35   data()->addAttribute(FROM_SIZE_ID(), ModelAPI_AttributeDouble::typeId());
36
37   data()->addAttribute(TO_OBJECT_ID(), ModelAPI_AttributeSelection::typeId());
38   data()->addAttribute(TO_SIZE_ID(), ModelAPI_AttributeDouble::typeId());
39
40   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), FROM_OBJECT_ID());
41   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), TO_OBJECT_ID());
42
43   data()->addAttribute(CUTLIST_ID(), ModelAPI_AttributeSelectionList::typeId());
44
45   // extrusion works with faces always
46   AttributeSelectionListPtr aSelection = data()->selectionList(CUTLIST_ID());
47   aSelection->setSelectionType("SOLID");
48 }
49
50
51 std::shared_ptr<ModelAPI_Feature> FeaturesPlugin_ExtrusionCut::addFeature(std::string theID)
52 {
53   std::shared_ptr<ModelAPI_Feature> aNew = document()->addFeature(theID, false);
54   if (aNew) {
55     data()->reference(SKETCH_OBJECT_ID())->setValue(aNew);
56   }
57    // set as current also after it becomes sub to set correctly enabled for other sketch subs
58   document()->setCurrentFeature(aNew, false);
59   return aNew;
60 }
61
62   
63 int FeaturesPlugin_ExtrusionCut::numberOfSubs() const
64 {
65   ObjectPtr aObj = data()->reference(SKETCH_OBJECT_ID())->value();
66   return aObj.get()? 1 : 0;
67 }
68
69 std::shared_ptr<ModelAPI_Feature> FeaturesPlugin_ExtrusionCut::subFeature(const int theIndex) const
70 {
71   if (theIndex == 0)
72     return std::dynamic_pointer_cast<ModelAPI_Feature>(data()->reference(SKETCH_OBJECT_ID())->value());
73   return std::shared_ptr<ModelAPI_Feature>();
74 }
75
76 int FeaturesPlugin_ExtrusionCut::subFeatureId(const int theIndex) const
77 {
78   std::shared_ptr<ModelAPI_Feature> aFeature = subFeature(theIndex);
79   if (aFeature.get())
80     return aFeature->data()->featureId();
81   return -1;
82 }
83
84 bool FeaturesPlugin_ExtrusionCut::isSub(ObjectPtr theObject) const
85 {
86   // check is this feature of result
87   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
88   if (!aFeature)
89     return false;
90  
91   ObjectPtr aSub = data()->reference(SKETCH_OBJECT_ID())->value();
92   return aSub == theObject;
93 }
94
95 void FeaturesPlugin_ExtrusionCut::removeFeature(std::shared_ptr<ModelAPI_Feature> theFeature)
96 {
97 }
98
99 //=================================================================================================
100 void FeaturesPlugin_ExtrusionCut::execute()
101 {
102   // Getting extrusion bounding planes.
103   std::shared_ptr<GeomAPI_Shape> aFromShape;
104   std::shared_ptr<GeomAPI_Shape> aToShape;
105   std::shared_ptr<ModelAPI_AttributeSelection> anObjRef = selection(FROM_OBJECT_ID());
106   if (anObjRef) {
107     aFromShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
108   }
109   anObjRef = selection(TO_OBJECT_ID());
110   if (anObjRef) {
111     aToShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anObjRef->value());
112   }
113
114   // Getting extrusion sizes.
115   double aFromSize = real(FROM_SIZE_ID())->value();
116   double aToSize = real(TO_SIZE_ID())->value();
117
118   // Getting faces to extrude.
119   std::shared_ptr<ModelAPI_Feature> aSketchFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(
120                                                      reference(SKETCH_OBJECT_ID())->value());
121   if(!aSketchFeature) {
122     return;
123   }
124   ResultPtr aSketchRes = aSketchFeature->results().front();
125   ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aSketchRes);
126   if(!aConstruction.get()) {
127     return;
128   }
129   int aSketchFacesNum = aConstruction->facesNum();
130
131   // Extrude faces.
132   ListOfShape anExtrusionList;
133   for(int aFaceIndex = 0; aFaceIndex < aSketchFacesNum; aFaceIndex++) {
134     std::shared_ptr<GeomAPI_Shape> aBaseShape = std::dynamic_pointer_cast<GeomAPI_Shape>(aConstruction->face(aFaceIndex));
135     GeomAlgoAPI_Prism aPrismAlgo(aBaseShape, aFromShape, aFromSize, aToShape, aToSize);
136
137     // Checking that the algorithm worked properly.
138     if(!aPrismAlgo.isDone() || aPrismAlgo.shape()->isNull() || !aPrismAlgo.isValid()) {
139       return;
140     }
141     anExtrusionList.push_back(aPrismAlgo.shape());
142   }
143
144   // Getting objects to cut from.
145   ListOfShape aCutList;
146   AttributeSelectionListPtr anObjectsSelList = selectionList(CUTLIST_ID());
147   if (anObjectsSelList->size() == 0) {
148     return;
149   }
150   for(int anObjectsIndex = 0; anObjectsIndex < anObjectsSelList->size(); anObjectsIndex++) {
151     std::shared_ptr<ModelAPI_AttributeSelection> anObjectAttr = anObjectsSelList->value(anObjectsIndex);
152     std::shared_ptr<GeomAPI_Shape> anObject = anObjectAttr->value();
153     if(!anObject.get()) {
154       return;
155     }
156     aCutList.push_back(anObject);
157   }
158
159   // Cut from each objec result of extrusion.
160   int aResultIndex = 0;
161   for(ListOfShape::iterator aCutListIt = aCutList.begin(); aCutListIt != aCutList.end(); aCutListIt++) {
162     std::shared_ptr<GeomAPI_Shape> anObject = *aCutListIt;
163     ListOfShape aListWithObject;
164     aListWithObject.push_back(anObject);
165     GeomAlgoAPI_Boolean aBoolAlgo(aListWithObject, anExtrusionList, GeomAlgoAPI_Boolean::BOOL_CUT);
166
167     // Checking that the algorithm worked properly.
168     if(!aBoolAlgo.isDone() || aBoolAlgo.shape()->isNull() || !aBoolAlgo.isValid()) {
169       return;
170     }
171
172     if(GeomAlgoAPI_ShapeProps::volume(aBoolAlgo.shape()) > 1.e-7) {
173       std::shared_ptr<ModelAPI_ResultBody> aResultBody = document()->createBody(data(), aResultIndex);
174       LoadNamingDS(aResultBody, anObject, anExtrusionList, aBoolAlgo);
175       setResult(aResultBody, aResultIndex);
176       aResultIndex++;
177     }
178   }
179 }
180
181 //=================================================================================================
182 void FeaturesPlugin_ExtrusionCut::LoadNamingDS(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
183                                                const std::shared_ptr<GeomAPI_Shape>& theBaseShape,
184                                                const ListOfShape& theTools,
185                                                const GeomAlgoAPI_Boolean& theAlgo)
186 {
187   //load result
188   if(theBaseShape->isEqual(theAlgo.shape())) {
189     theResultBody->store(theAlgo.shape());
190   } else {
191     theResultBody->storeModified(theBaseShape, theAlgo.shape());
192
193     GeomAPI_DataMapOfShapeShape* aSubShapes = new GeomAPI_DataMapOfShapeShape();
194
195     const int aModTag = 1;
196     const int aDeleteTag = 2;
197     const std::string aModName = "Modified";
198     theResultBody->loadAndOrientModifiedShapes(theAlgo.makeShape().get(), theBaseShape, GeomAPI_Shape::FACE,
199                                                aModTag, aModName, *theAlgo.mapOfShapes().get());
200     theResultBody->loadDeletedShapes(theAlgo.makeShape().get(), theBaseShape, GeomAPI_Shape::FACE, aDeleteTag);
201
202     for(ListOfShape::const_iterator anIter = theTools.begin(); anIter != theTools.end(); anIter++) {
203       theResultBody->loadAndOrientModifiedShapes(theAlgo.makeShape().get(), *anIter, GeomAPI_Shape::FACE,
204                                                  aModTag, aModName, *theAlgo.mapOfShapes().get());
205       theResultBody->loadDeletedShapes(theAlgo.makeShape().get(), *anIter, GeomAPI_Shape::FACE, aDeleteTag);
206     }
207   }
208 }