1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: FeaturesPlugin_CompositeSketch.cpp
4 // Created: 11 September 2015
5 // Author: Dmitry Bobylev
7 #include <FeaturesPlugin_CompositeSketch.h>
9 #include <ModelAPI_AttributeSelectionList.h>
10 #include <ModelAPI_AttributeReference.h>
11 #include <ModelAPI_BodyBuilder.h>
12 #include <ModelAPI_ResultConstruction.h>
13 #include <ModelAPI_Session.h>
14 #include <ModelAPI_Validator.h>
16 #include <GeomAlgoAPI_CompoundBuilder.h>
17 #include <GeomAlgoAPI_Prism.h>
18 #include <GeomAlgoAPI_Revolution.h>
19 #include <GeomAlgoAPI_ShapeTools.h>
20 #include <GeomAPI_ShapeExplorer.h>
24 //=================================================================================================
25 void FeaturesPlugin_CompositeSketch::initCompositeSketchAttribtues(const int theInitFlags)
27 // Initialize sketch launcher.
28 if(theInitFlags & InitSketchLauncher) {
29 data()->addAttribute(SKETCH_ID(), ModelAPI_AttributeReference::typeId());
30 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SKETCH_ID());
33 // Initialize selection list.
34 if(theInitFlags & InitBaseObjectsList) {
35 data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId());
39 //=================================================================================================
40 std::shared_ptr<ModelAPI_Feature> FeaturesPlugin_CompositeSketch::addFeature(std::string theID)
42 FeaturePtr aNew = document()->addFeature(theID, false);
44 data()->reference(SKETCH_ID())->setValue(aNew);
47 // Set as current also after it becomes sub to set correctly enabled for other sketch subs.
48 document()->setCurrentFeature(aNew, false);
52 //=================================================================================================
53 int FeaturesPlugin_CompositeSketch::numberOfSubs(bool forTree) const
55 ObjectPtr aObj = data()->reference(SKETCH_ID())->value();
56 return aObj.get() ? 1 : 0;
59 //=================================================================================================
60 std::shared_ptr<ModelAPI_Feature> FeaturesPlugin_CompositeSketch::subFeature(const int theIndex, bool forTree)
63 return std::dynamic_pointer_cast<ModelAPI_Feature>(data()->reference(SKETCH_ID())->value());
66 return std::shared_ptr<ModelAPI_Feature>();
69 //=================================================================================================
70 int FeaturesPlugin_CompositeSketch::subFeatureId(const int theIndex) const
74 std::dynamic_pointer_cast<ModelAPI_Feature>(data()->reference(SKETCH_ID())->value());
76 return aFeature->data()->featureId();
83 //=================================================================================================
84 bool FeaturesPlugin_CompositeSketch::isSub(ObjectPtr theObject) const
86 // Check is this feature of result
87 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
92 ObjectPtr aSub = data()->reference(SKETCH_ID())->value();
93 return aSub == theObject;
96 //=================================================================================================
97 void FeaturesPlugin_CompositeSketch::removeFeature(std::shared_ptr<ModelAPI_Feature> theFeature)
99 AttributeSelectionListPtr aBaseObjectsSelectionList = selectionList(BASE_OBJECTS_ID());
100 if(aBaseObjectsSelectionList.get() && aBaseObjectsSelectionList->size() > 0) {
101 aBaseObjectsSelectionList->clear();
104 reference(SKETCH_ID())->setValue(ObjectPtr());
107 //=================================================================================================
108 void FeaturesPlugin_CompositeSketch::getBaseShapes(ListOfShape& theBaseShapesList,
109 const bool theIsMakeShells)
111 theBaseShapesList.clear();
113 ListOfShape aBaseFacesList;
114 AttributeSelectionListPtr aBaseObjectsSelectionList = selectionList(BASE_OBJECTS_ID());
115 if(!aBaseObjectsSelectionList.get()) {
116 setError("Error: Could not get base objects selection list.");
119 if(aBaseObjectsSelectionList->size() == 0) {
120 setError("Error: Base objects list is empty.");
123 for(int anIndex = 0; anIndex < aBaseObjectsSelectionList->size(); anIndex++) {
124 AttributeSelectionPtr aBaseObjectSelection = aBaseObjectsSelectionList->value(anIndex);
125 if(!aBaseObjectSelection.get()) {
126 setError("Error: One of the selected base objects is empty.");
129 GeomShapePtr aBaseShape = aBaseObjectSelection->value();
130 if(aBaseShape.get() && !aBaseShape->isNull()) {
131 GeomAPI_Shape::ShapeType aST = aBaseShape->shapeType();
132 if(aST != GeomAPI_Shape::VERTEX && aST != GeomAPI_Shape::EDGE && aST != GeomAPI_Shape::WIRE &&
133 aST != GeomAPI_Shape::FACE && aST != GeomAPI_Shape::SHELL) {
134 setError("Error: Selected shapes has unsupported type.");
137 aST == GeomAPI_Shape::FACE ? aBaseFacesList.push_back(aBaseShape) :
138 theBaseShapesList.push_back(aBaseShape);
140 // This may be the whole sketch result selected, check and get faces.
141 ResultConstructionPtr aConstruction =
142 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aBaseObjectSelection->context());
143 if(!aConstruction.get()) {
144 setError("Error: One of selected sketches does not have results.");
147 int aFacesNum = aConstruction->facesNum();
149 // Probably it can be construction.
150 aBaseShape = aConstruction->shape();
151 if(aBaseShape.get() && !aBaseShape->isNull()) {
152 GeomAPI_Shape::ShapeType aST = aBaseShape->shapeType();
153 if(aST != GeomAPI_Shape::VERTEX && aST != GeomAPI_Shape::EDGE && aST != GeomAPI_Shape::WIRE &&
154 aST != GeomAPI_Shape::FACE && aST != GeomAPI_Shape::SHELL) {
155 setError("Error: Selected shapes has unsupported type.");
158 aST == GeomAPI_Shape::FACE ? aBaseFacesList.push_back(aBaseShape) :
159 theBaseShapesList.push_back(aBaseShape);
162 for(int aFaceIndex = 0; aFaceIndex < aFacesNum; aFaceIndex++) {
163 GeomShapePtr aBaseFace = aConstruction->face(aFaceIndex);
164 if(!aBaseFace.get() || aBaseFace->isNull()) {
165 setError("Error: One of the faces on selected sketch is Null.");
168 aBaseFacesList.push_back(aBaseFace);
174 // Searching faces with common edges.
175 if(theIsMakeShells) {
177 ListOfShape aFreeFaces;
178 GeomShapePtr aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseFacesList);
179 GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, aShells, aFreeFaces);
180 theBaseShapesList.insert(theBaseShapesList.end(), aFreeFaces.begin(), aFreeFaces.end());
181 theBaseShapesList.insert(theBaseShapesList.end(), aShells.begin(), aShells.end());
183 theBaseShapesList.insert(theBaseShapesList.end(), aBaseFacesList.begin(), aBaseFacesList.end());
187 //=================================================================================================
188 bool FeaturesPlugin_CompositeSketch::isMakeShapeValid(const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape)
190 // Check that algo is done.
191 if(!theMakeShape->isDone()) {
192 setError("Error: " + getKind() + " algorithm failed.");
196 // Check if shape is not null.
197 if(!theMakeShape->shape().get() || theMakeShape->shape()->isNull()) {
198 setError("Error: Resulting shape is null.");
202 // Check that resulting shape is valid.
203 if(!theMakeShape->isValid()) {
204 setError("Error: Resulting shape is not valid.");
211 //=================================================================================================
212 void FeaturesPlugin_CompositeSketch::storeResult(const GeomShapePtr theBaseShape,
213 const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
214 const int theResultIndex)
216 // Create result body.
217 ResultBodyPtr aResultBody = document()->createBody(data(), theResultIndex);
219 // Store generated shape.
220 aResultBody->storeGenerated(theBaseShape, theMakeShape->shape());
222 // Store generated edges/faces.
224 storeGenerationHistory(aResultBody, theBaseShape, theMakeShape, aGenTag);
226 setResult(aResultBody, theResultIndex);
229 //=================================================================================================
230 void FeaturesPlugin_CompositeSketch::storeGenerationHistory(ResultBodyPtr theResultBody,
231 const GeomShapePtr theBaseShape,
232 const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
235 GeomAPI_Shape::ShapeType aBaseShapeType = theBaseShape->shapeType();
236 GeomAPI_Shape::ShapeType aShapeTypeToExplode;
237 std::string aGenName = "Generated_";
239 std::shared_ptr<GeomAPI_DataMapOfShapeShape> aMapOfSubShapes = theMakeShape->mapOfSubShapes();
240 switch(aBaseShapeType) {
241 case GeomAPI_Shape::VERTEX: {
242 aShapeTypeToExplode = GeomAPI_Shape::VERTEX;
246 case GeomAPI_Shape::EDGE:
247 case GeomAPI_Shape::WIRE: {
248 std::shared_ptr<GeomAPI_Vertex> aV1, aV2;
249 GeomAlgoAPI_ShapeTools::findBounds(theBaseShape, aV1, aV2);
250 ListOfShape aV1History, aV2History;
251 theMakeShape->generated(aV1, aV1History);
252 theMakeShape->generated(aV2, aV2History);
253 theResultBody->generated(aV1, aV1History.front(), aGenName + "Edge_1", theTag++);
254 theResultBody->generated(aV2, aV2History.front(), aGenName + "Edge_2", theTag++);
256 case GeomAPI_Shape::FACE:
257 case GeomAPI_Shape::SHELL: {
258 aShapeTypeToExplode = GeomAPI_Shape::EDGE;
263 theResultBody->loadAndOrientGeneratedShapes(theMakeShape.get(), theBaseShape, aShapeTypeToExplode,
264 theTag++, aGenName, *aMapOfSubShapes.get());
266 std::shared_ptr<GeomAlgoAPI_MakeSweep> aMakeSweep = std::dynamic_pointer_cast<GeomAlgoAPI_MakeSweep>(theMakeShape);
267 if(aMakeSweep.get()) {
268 // Store from shapes.
269 storeShapes(theResultBody, aBaseShapeType, aMapOfSubShapes, aMakeSweep->fromShapes(), "From_", theTag);
272 storeShapes(theResultBody, aBaseShapeType, aMapOfSubShapes, aMakeSweep->toShapes(), "To_", theTag);
276 //=================================================================================================
277 void FeaturesPlugin_CompositeSketch::storeShapes(ResultBodyPtr theResultBody,
278 const GeomAPI_Shape::ShapeType theBaseShapeType,
279 const std::shared_ptr<GeomAPI_DataMapOfShapeShape> theMapOfSubShapes,
280 const ListOfShape& theShapes,
281 const std::string theName,
284 GeomAPI_Shape::ShapeType aShapeTypeToExplore = GeomAPI_Shape::FACE;
285 std::string aShapeTypeStr = "Face";
286 switch(theBaseShapeType) {
287 case GeomAPI_Shape::VERTEX: {
288 aShapeTypeToExplore = GeomAPI_Shape::VERTEX;
289 aShapeTypeStr = "Vertex";
292 case GeomAPI_Shape::EDGE:
293 case GeomAPI_Shape::WIRE: {
294 aShapeTypeToExplore = GeomAPI_Shape::EDGE;
295 aShapeTypeStr = "Edge";
298 case GeomAPI_Shape::FACE:
299 case GeomAPI_Shape::SHELL: {
300 aShapeTypeToExplore = GeomAPI_Shape::FACE;
301 aShapeTypeStr = "Face";
308 std::string aName = theName + aShapeTypeStr;
309 for(ListOfShape::const_iterator anIt = theShapes.cbegin(); anIt != theShapes.cend(); ++anIt) {
310 GeomShapePtr aShape = *anIt;
311 for(GeomAPI_ShapeExplorer anExp(aShape, aShapeTypeToExplore); anExp.more(); anExp.next()) {
312 GeomShapePtr aSubShape = anExp.current();
313 if(theMapOfSubShapes->isBound(aSubShape)) {
314 aSubShape = theMapOfSubShapes->find(aSubShape);
316 std::ostringstream aStr;
317 aStr << aName << "_" << aShapeIndex++;
318 theResultBody->generated(aSubShape, aStr.str(), theTag++);