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_ResultBody.h>
13 #include <ModelAPI_ResultConstruction.h>
14 #include <ModelAPI_Session.h>
15 #include <ModelAPI_Validator.h>
17 #include <GeomAlgoAPI_CompoundBuilder.h>
18 #include <GeomAlgoAPI_Prism.h>
19 #include <GeomAlgoAPI_Revolution.h>
20 #include <GeomAlgoAPI_ShapeTools.h>
24 //=================================================================================================
25 void FeaturesPlugin_CompositeSketch::initAttributes()
27 data()->addAttribute(SKETCH_OBJECT_ID(), ModelAPI_AttributeReference::typeId());
28 data()->addAttribute(SKETCH_SELECTION_ID(), ModelAPI_AttributeSelection::typeId());
29 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SKETCH_SELECTION_ID());
31 //initMakeSolidsAttributes();
34 //=================================================================================================
35 std::shared_ptr<ModelAPI_Feature> FeaturesPlugin_CompositeSketch::addFeature(std::string theID)
37 std::shared_ptr<ModelAPI_Feature> aNew = document()->addFeature(theID, false);
39 data()->reference(SKETCH_OBJECT_ID())->setValue(aNew);
41 // set as current also after it becomes sub to set correctly enabled for other sketch subs
42 document()->setCurrentFeature(aNew, false);
46 //=================================================================================================
47 int FeaturesPlugin_CompositeSketch::numberOfSubs(bool forTree) const
49 ObjectPtr aObj = data()->reference(SKETCH_OBJECT_ID())->value();
50 return aObj.get()? 1 : 0;
53 //=================================================================================================
54 std::shared_ptr<ModelAPI_Feature> FeaturesPlugin_CompositeSketch::subFeature(const int theIndex, bool forTree)
57 return std::dynamic_pointer_cast<ModelAPI_Feature>(data()->reference(SKETCH_OBJECT_ID())->value());
58 return std::shared_ptr<ModelAPI_Feature>();
61 //=================================================================================================
62 int FeaturesPlugin_CompositeSketch::subFeatureId(const int theIndex) const
66 std::dynamic_pointer_cast<ModelAPI_Feature>(data()->reference(SKETCH_OBJECT_ID())->value());
68 return aFeature->data()->featureId();
73 //=================================================================================================
74 bool FeaturesPlugin_CompositeSketch::isSub(ObjectPtr theObject) const
76 // check is this feature of result
77 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
81 ObjectPtr aSub = data()->reference(SKETCH_OBJECT_ID())->value();
82 return aSub == theObject;
85 //=================================================================================================
86 void FeaturesPlugin_CompositeSketch::removeFeature(std::shared_ptr<ModelAPI_Feature> theFeature)
88 AttributeSelectionListPtr aFacesSelectionList = selectionList(LIST_ID());
89 if (aFacesSelectionList.get() && aFacesSelectionList->size() > 0)
90 aFacesSelectionList->clear();
92 data()->reference(SKETCH_OBJECT_ID())->setValue(ObjectPtr());
95 //=================================================================================================
96 void FeaturesPlugin_CompositeSketch::erase()
98 if (data().get() && data()->isValid()) { // on abort of sketch of this composite it may be invalid
100 std::dynamic_pointer_cast<ModelAPI_Feature>(data()->reference(SKETCH_OBJECT_ID())->value());
101 if (aSketch.get() && aSketch->data()->isValid()) {
102 document()->removeFeature(aSketch);
105 ModelAPI_CompositeFeature::erase();
109 //=================================================================================================
110 void FeaturesPlugin_CompositeSketch::execute()
112 // Getting faces to create solids.
113 std::shared_ptr<ModelAPI_Feature> aSketchFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(
114 reference(SKETCH_OBJECT_ID())->value());
115 if(!aSketchFeature || aSketchFeature->results().empty()) {
118 ResultPtr aSketchRes = aSketchFeature->results().front();
119 ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aSketchRes);
120 if(!aConstruction.get()) {
124 /// feature extrusion does not have the next attribute
125 if (data()->attribute(SKETCH_SELECTION_ID()).get()) {
126 if (!selection(SKETCH_SELECTION_ID())->isInitialized() || selection(SKETCH_SELECTION_ID())->context() != aSketchRes) {
127 selection(SKETCH_SELECTION_ID())->setValue(aSketchRes, std::shared_ptr<GeomAPI_Shape>());
130 int aSketchFacesNum = aConstruction->facesNum();
131 if(aSketchFacesNum == 0) {
134 ListOfShape aFacesList;
135 for(int aFaceIndex = 0; aFaceIndex < aSketchFacesNum; aFaceIndex++) {
136 std::shared_ptr<GeomAPI_Shape> aFace = std::dynamic_pointer_cast<GeomAPI_Shape>(aConstruction->face(aFaceIndex));
137 aFacesList.push_back(aFace);
140 // Searching faces with common edges.
142 ListOfShape aFreeFaces;
143 std::shared_ptr<GeomAPI_Shape> aFacesCompound = GeomAlgoAPI_CompoundBuilder::compound(aFacesList);
144 GeomAlgoAPI_ShapeTools::combineShapes(aFacesCompound, GeomAPI_Shape::SHELL, aShells, aFreeFaces);
145 aShells.insert(aShells.end(), aFreeFaces.begin(), aFreeFaces.end());
147 // Generating result for each shell and face.
149 int aResultIndex = 0;
150 for(ListOfShape::const_iterator anIter = aShells.cbegin(); anIter != aShells.cend(); anIter++) {
151 std::shared_ptr<GeomAlgoAPI_MakeShape> aMakeShape;
153 std::shared_ptr<GeomAPI_Shape> aBaseFace = *anIter;
154 makeSolid(aBaseFace, aMakeShape);
155 if(!aMakeShape.get()) {
160 ResultBodyPtr aResultBody = document()->createBody(data(), aResultIndex);
161 loadNamingDS(aResultBody, aBaseFace, aMakeShape);
162 setResult(aResultBody, aResultIndex);
167 std::ostringstream aStringStream;
168 aStringStream << "Error: Could not create solid(s) from " << aErrorsNum << " face(s).";
169 setError(aStringStream.str());
172 // Remove the rest results if there were produced in the previous pass.
173 removeResults(aResultIndex);
176 //=================================================================================================
177 void FeaturesPlugin_CompositeSketch::loadNamingDS(std::shared_ptr<ModelAPI_ResultBody> theResultBody,
178 const std::shared_ptr<GeomAPI_Shape>& theBaseShape,
179 const std::shared_ptr<GeomAlgoAPI_MakeShape>& theMakeShape)
182 theResultBody->storeGenerated(theBaseShape, theMakeShape->shape());
184 //Insert lateral face : Face from Edge
185 const std::string aLatName = "LateralFace";
186 const int aLatTag = 1;
187 std::shared_ptr<GeomAPI_DataMapOfShapeShape> aDataMap = theMakeShape->mapOfSubShapes();
188 theResultBody->loadAndOrientGeneratedShapes(theMakeShape.get(), theBaseShape, GeomAPI_Shape::EDGE, aLatTag, aLatName, *aDataMap.get());
190 std::shared_ptr<GeomAlgoAPI_MakeSweep> aSweepAlgo = std::dynamic_pointer_cast<GeomAlgoAPI_MakeSweep>(theMakeShape);
191 if(aSweepAlgo.get()) {
193 int aToFaceIndex = 1;
194 const std::string aToName = "ToFace";
196 const ListOfShape& aToFaces = aSweepAlgo->toShapes();
197 for(ListOfShape::const_iterator anIt = aToFaces.cbegin(); anIt != aToFaces.cend(); anIt++) {
198 std::shared_ptr<GeomAPI_Shape> aToFace = *anIt;
199 if(aDataMap->isBound(aToFace)) {
200 aToFace = aDataMap->find(aToFace);
202 std::ostringstream aStr;
203 aStr << aToName << "_" << aToFaceIndex++;
204 theResultBody->generated(aToFace, aStr.str(), aToTag++);
208 int aFromFaceIndex = 1;
209 const std::string aFromName = "FromFace";
210 int aFromTag = aToTag > 10000 ? aToTag : 10000;
211 const ListOfShape& aFromFaces = aSweepAlgo->fromShapes();
212 for(ListOfShape::const_iterator anIt = aFromFaces.cbegin(); anIt != aFromFaces.cend(); anIt++) {
213 std::shared_ptr<GeomAPI_Shape> aFromFace = *anIt;
214 if(aDataMap->isBound(aFromFace)) {
215 aFromFace = aDataMap->find(aFromFace);
217 std::ostringstream aStr;
218 aStr << aFromName << "_" << aFromFaceIndex++;
219 theResultBody->generated(aFromFace, aStr.str(), aFromTag++);
223 //=================================================================================================
224 void FeaturesPlugin_CompositeSketch::setSketchObjectToList()
226 std::shared_ptr<ModelAPI_Feature> aSketchFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(
227 reference(SKETCH_OBJECT_ID())->value());
229 if(aSketchFeature.get() && !aSketchFeature->results().empty()) {
230 ResultPtr aSketchRes = aSketchFeature->results().front();
231 ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aSketchRes);
232 if(aConstruction.get()) {
233 AttributeSelectionListPtr aFacesSelectionList = selectionList(LIST_ID());
234 if (aFacesSelectionList.get() && aFacesSelectionList->size() == 0)
235 aFacesSelectionList->append(aSketchRes, std::shared_ptr<GeomAPI_Shape>());