1 // Copyright (C) 2014-2022 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include <FeaturesPlugin_CompositeSketch.h>
21 #include <FeaturesPlugin_Tools.h>
23 #include <ModelAPI_AttributeSelectionList.h>
24 #include <ModelAPI_AttributeReference.h>
25 #include <ModelAPI_BodyBuilder.h>
26 #include <ModelAPI_ResultConstruction.h>
27 #include <ModelAPI_Session.h>
28 #include <ModelAPI_Validator.h>
30 #include <GeomAlgoAPI_Revolution.h>
32 #include <GeomAPI_ShapeExplorer.h>
35 static const std::string COMPOSITESKETCH_VERSION_1("v9.6");
37 static void storeSubShape(const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
38 ResultBodyPtr theResultBody,
39 const GeomShapePtr theShape,
40 const GeomAPI_Shape::ShapeType theType,
41 const std::string& theName);
43 //=================================================================================================
44 void FeaturesPlugin_CompositeSketch::initCompositeSketchAttribtues(const int theInitFlags)
46 // Initialize sketch launcher.
47 if(theInitFlags & InitSketchLauncher) {
48 data()->addAttribute(SKETCH_ID(), ModelAPI_AttributeReference::typeId());
49 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SKETCH_ID());
52 // Initialize selection list.
53 if(theInitFlags & InitBaseObjectsList) {
54 AttributeSelectionListPtr anObjectsAttr =
55 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(
56 data()->addAttribute(BASE_OBJECTS_ID(), ModelAPI_AttributeSelectionList::typeId()));
57 myCurrentSelectionType = selectionList(BASE_OBJECTS_ID())->selectionType();
58 anObjectsAttr->setWholeResultAllowed(true);
59 if (!anObjectsAttr->isInitialized()) {
60 // new feature, specify the version
61 data()->setVersion(COMPOSITESKETCH_VERSION_1);
66 //=================================================================================================
67 std::shared_ptr<ModelAPI_Feature> FeaturesPlugin_CompositeSketch::addFeature(std::string theID)
69 FeaturePtr aNew = document()->addFeature(theID, false);
71 data()->reference(SKETCH_ID())->setValue(aNew);
74 // Set as current also after it becomes sub to set correctly enabled for other sketch subs.
75 document()->setCurrentFeature(aNew, false);
79 //=================================================================================================
80 int FeaturesPlugin_CompositeSketch::numberOfSubs(bool /*forTree*/) const
82 ObjectPtr aObj = data()->reference(SKETCH_ID())->value();
83 return aObj.get() ? 1 : 0;
86 //=================================================================================================
87 std::shared_ptr<ModelAPI_Feature> FeaturesPlugin_CompositeSketch::subFeature(const int theIndex,
90 FeaturePtr aSubFeature;
93 std::dynamic_pointer_cast<ModelAPI_Feature>(data()->reference(SKETCH_ID())->value());
98 //=================================================================================================
99 int FeaturesPlugin_CompositeSketch::subFeatureId(const int theIndex) const
102 FeaturePtr aFeature =
103 std::dynamic_pointer_cast<ModelAPI_Feature>(data()->reference(SKETCH_ID())->value());
105 return aFeature->data()->featureId();
112 //=================================================================================================
113 bool FeaturesPlugin_CompositeSketch::isSub(ObjectPtr theObject) const
115 bool isSubFeature = false;
116 // Check is this feature of result
117 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
118 if (aFeature.get()) {
119 ObjectPtr aSub = data()->reference(SKETCH_ID())->value();
120 isSubFeature = aSub == theObject;
125 //=================================================================================================
126 void FeaturesPlugin_CompositeSketch::removeFeature(std::shared_ptr<ModelAPI_Feature> theFeature)
128 AttributeSelectionListPtr aBaseObjectsSelectionList = selectionList(BASE_OBJECTS_ID());
129 if(aBaseObjectsSelectionList.get() && aBaseObjectsSelectionList->size() > 0) {
130 aBaseObjectsSelectionList->clear();
133 reference(SKETCH_ID())->setValue(ObjectPtr());
136 //=================================================================================================
137 void FeaturesPlugin_CompositeSketch::getBaseShapes(ListOfShape& theBaseShapesList,
138 const bool theIsMakeShells)
140 AttributeSelectionListPtr aBaseObjectsSelectionList = selectionList(BASE_OBJECTS_ID());
142 bool isOk = FeaturesPlugin_Tools::getShape(
143 aBaseObjectsSelectionList, theIsMakeShells, theBaseShapesList, anError);
148 //=================================================================================================
149 void FeaturesPlugin_CompositeSketch::storeResult(const GeomShapePtr theBaseShape,
150 const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
153 // Create result body.
154 ResultBodyPtr aResultBody = document()->createBody(data(), theIndex);
156 // Store generated shape.
157 aResultBody->storeGenerated(theBaseShape, theMakeShape->shape());
159 // Store generated edges/faces.
160 storeGenerationHistory(aResultBody, theBaseShape, theMakeShape);
162 setResult(aResultBody, theIndex);
165 //=================================================================================================
166 void FeaturesPlugin_CompositeSketch::storeGenerationHistory(ResultBodyPtr theResultBody,
167 const GeomShapePtr theBaseShape,
168 const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape)
170 GeomAPI_Shape::ShapeType aBaseShapeType = theBaseShape->shapeType();
171 GeomAPI_Shape::ShapeType aShapeTypeToExplode = GeomAPI_Shape::SHAPE;
173 switch(aBaseShapeType) {
174 case GeomAPI_Shape::EDGE: {
175 aShapeTypeToExplode = GeomAPI_Shape::VERTEX;
178 case GeomAPI_Shape::WIRE: {
179 aShapeTypeToExplode = GeomAPI_Shape::COMPOUND;
182 case GeomAPI_Shape::FACE:
183 case GeomAPI_Shape::SHELL: {
184 aShapeTypeToExplode = GeomAPI_Shape::EDGE;
187 case GeomAPI_Shape::COMPOUND: {
188 aShapeTypeToExplode = GeomAPI_Shape::COMPOUND;
190 default: // [to avoid compilation warnings]
194 if(aShapeTypeToExplode == GeomAPI_Shape::VERTEX ||
195 aShapeTypeToExplode == GeomAPI_Shape::COMPOUND) {
196 theResultBody->loadGeneratedShapes(theMakeShape, theBaseShape, GeomAPI_Shape::VERTEX);
198 if(aShapeTypeToExplode == GeomAPI_Shape::EDGE ||
199 aShapeTypeToExplode == GeomAPI_Shape::COMPOUND) {
200 theResultBody->loadGeneratedShapes(theMakeShape, theBaseShape, GeomAPI_Shape::EDGE);
202 std::list<std::shared_ptr<GeomAlgoAPI_MakeSweep> > aSweeps; // all sweeps collected
203 std::shared_ptr<GeomAlgoAPI_MakeSweep> aMakeSweep =
204 std::dynamic_pointer_cast<GeomAlgoAPI_MakeSweep>(theMakeShape);
205 if(aMakeSweep.get()) {
206 aSweeps.push_back(aMakeSweep);
208 std::shared_ptr<GeomAlgoAPI_MakeShapeList> aMakeList =
209 std::dynamic_pointer_cast<GeomAlgoAPI_MakeShapeList>(theMakeShape);
210 if (aMakeList.get()) {
211 ListOfMakeShape::const_iterator anIter = aMakeList->list().cbegin();
212 for(; anIter != aMakeList->list().cend(); anIter++) {
213 std::shared_ptr<GeomAlgoAPI_MakeSweep> aSweep =
214 std::dynamic_pointer_cast<GeomAlgoAPI_MakeSweep>(*anIter);
216 aSweeps.push_back(aSweep);
220 std::list<std::shared_ptr<GeomAlgoAPI_MakeSweep> >::iterator aSweep = aSweeps.begin();
221 for(; aSweep != aSweeps.end(); aSweep++) {
222 // Store from shapes.
223 storeShapes(theMakeShape, theResultBody, aBaseShapeType, (*aSweep)->fromShapes(), "From_");
226 storeShapes(theMakeShape, theResultBody, aBaseShapeType, (*aSweep)->toShapes(), "To_");
230 //=================================================================================================
231 void FeaturesPlugin_CompositeSketch::storeShapes(
232 const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
233 ResultBodyPtr theResultBody,
234 const GeomAPI_Shape::ShapeType theBaseShapeType,
235 const ListOfShape& theShapes,
236 const std::string theName)
238 GeomAPI_Shape::ShapeType aShapeTypeToExplore = GeomAPI_Shape::FACE;
239 std::string aShapeTypeStr = "Face";
240 switch(theBaseShapeType) {
241 case GeomAPI_Shape::VERTEX: {
242 aShapeTypeToExplore = GeomAPI_Shape::VERTEX;
243 aShapeTypeStr = "Vertex";
246 case GeomAPI_Shape::EDGE:
247 case GeomAPI_Shape::WIRE: {
248 aShapeTypeToExplore = GeomAPI_Shape::EDGE;
249 aShapeTypeStr = "Edge";
252 case GeomAPI_Shape::FACE:
253 case GeomAPI_Shape::SHELL: {
254 aShapeTypeToExplore = GeomAPI_Shape::FACE;
255 aShapeTypeStr = "Face";
258 case GeomAPI_Shape::COMPOUND: {
259 aShapeTypeToExplore = GeomAPI_Shape::COMPOUND;
262 default: // [to avoid compilation warnings]
267 for(ListOfShape::const_iterator anIt = theShapes.cbegin(); anIt != theShapes.cend(); ++anIt) {
268 GeomShapePtr aShape = *anIt;
270 if(aShapeTypeToExplore == GeomAPI_Shape::COMPOUND) {
271 std::string aName = theName + (aShape->shapeType() == GeomAPI_Shape::EDGE ? "Edge" : "Face");
272 storeSubShape(theMakeShape, theResultBody, aShape, aShape->shapeType(), aName);
274 std::string aName = theName + aShapeTypeStr;
275 storeSubShape(theMakeShape, theResultBody, aShape, aShapeTypeToExplore, aName);
276 if (theBaseShapeType == GeomAPI_Shape::WIRE) { // issue 2289: special names also for vertices
277 aName = theName + "Vertex";
278 storeSubShape(theMakeShape, theResultBody, aShape, GeomAPI_Shape::VERTEX, aName);
285 const std::shared_ptr<GeomAlgoAPI_MakeShape> theMakeShape,
286 ResultBodyPtr theResultBody,
287 const GeomShapePtr theShape,
288 const GeomAPI_Shape::ShapeType theType,
289 const std::string& theName)
291 for(GeomAPI_ShapeExplorer anExp(theShape, theType); anExp.more(); anExp.next()) {
292 GeomShapePtr aSubShape = anExp.current();
293 if (!theResultBody->generated(aSubShape, theName)) {
294 int aNbSubs = theResultBody->numberOfSubs();
296 // check the modified shape is in the result body, don't store it if not
297 ListOfShape aNewShapes;
298 theMakeShape->modified(aSubShape, aNewShapes);
299 for (int i = 0; i < aNbSubs; ++i) {
300 ResultBodyPtr aSubRes = theResultBody->subResult(i);
301 GeomShapePtr aShape = aSubRes->shape();
302 ListOfShape::iterator aNewIt = aNewShapes.begin();
303 for (; aNewIt != aNewShapes.end(); ++aNewIt)
304 if (aShape->isSubShape(*aNewIt, false))
306 if (aNewIt != aNewShapes.end()) {
307 // store from/to shapes as primitives and then store modification of them by the boolean
308 aSubRes->generated(aSubShape, theName, false);
309 aSubRes->loadModifiedShapes(theMakeShape, aSubShape, theType);
314 // store from/to shapes as primitives and then store modification of them by the boolean
315 theResultBody->generated(aSubShape, theName, false);
316 theResultBody->loadModifiedShapes(theMakeShape, aSubShape, theType);