Salome HOME
Issue #1503: Fixed naming for Build/Sub-Shapes feature
[modules/shaper.git] / src / BuildPlugin / BuildPlugin_SubShapes.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        BuildPlugin_SubShapes.cpp
4 // Created:     14 April 2016
5 // Author:      Dmitry Bobylev
6
7 #include "BuildPlugin_SubShapes.h"
8
9 #include <ModelAPI_AttributeSelectionList.h>
10 #include <ModelAPI_ResultBody.h>
11 #include <ModelAPI_ResultConstruction.h>
12 #include <ModelAPI_Session.h>
13 #include <ModelAPI_Validator.h>
14
15 #include <GeomAPI_Edge.h>
16 #include <GeomAPI_ShapeIterator.h>
17 #include <GeomAPI_Wire.h>
18
19 #include <GeomAlgoAPI_ShapeBuilder.h>
20
21 //==================================================================================================
22 BuildPlugin_SubShapes::BuildPlugin_SubShapes()
23 {
24 }
25
26 //==================================================================================================
27 void BuildPlugin_SubShapes::initAttributes()
28 {
29   data()->addAttribute(BASE_SHAPE_ID(), ModelAPI_AttributeSelection::typeId());
30
31   data()->addAttribute(SUBSHAPES_ID(), ModelAPI_AttributeSelectionList::typeId());
32   ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), SUBSHAPES_ID());
33 }
34
35 void BuildPlugin_SubShapes::attributeChanged(const std::string& theID)
36 {
37   ModelAPI_Feature::attributeChanged(theID);
38
39   if(theID == BASE_SHAPE_ID()) {
40     AttributeSelectionPtr aShapeAttrSelection = selection(BASE_SHAPE_ID());
41     AttributeSelectionListPtr aSubShapesAttrList = selectionList(SUBSHAPES_ID());
42     if(!aShapeAttrSelection.get() || !aSubShapesAttrList.get()) {
43       return;
44     }
45     ResultPtr aContext = aShapeAttrSelection->context();
46
47     aSubShapesAttrList->clear();
48
49     GeomShapePtr aBaseShape = aShapeAttrSelection->value();
50     if(!aBaseShape.get()) {
51       return;
52     }
53     GeomAPI_Shape::ShapeType aBaseShapeType = aBaseShape->shapeType();
54     for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) {
55       GeomShapePtr aSubShape = anIt.current();
56       if(aBaseShapeType == GeomAPI_Shape::WIRE) {
57         for(GeomAPI_ShapeIterator aSubIt(aSubShape); aSubIt.more(); aSubIt.next()) {
58           GeomShapePtr aSubOfSubShape = aSubIt.current();
59           if(aSubOfSubShape->orientation() == GeomAPI_Shape::INTERNAL) {
60             aSubShapesAttrList->append(aContext, aSubOfSubShape);
61           }
62         }
63       } else if(aBaseShapeType == GeomAPI_Shape::FACE) {
64         if(aSubShape->shapeType() != GeomAPI_Shape::WIRE) {
65           aSubShapesAttrList->append(aContext, aSubShape);
66         } else if(aSubShape->orientation() == GeomAPI_Shape::INTERNAL) {
67           if(aSubShape->shapeType() == GeomAPI_Shape::WIRE) {
68             for(GeomAPI_ShapeIterator aWireIt(aSubShape); aWireIt.more(); aWireIt.next()) {
69               aSubShapesAttrList->append(aContext, aWireIt.current());
70             }
71           }
72         }
73       }
74     }
75   }
76 }
77
78 //==================================================================================================
79 void BuildPlugin_SubShapes::execute()
80 {
81   // Get base shape and sub-shapes list.
82   AttributeSelectionPtr aShapeAttrSelection = selection(BASE_SHAPE_ID());
83   AttributeSelectionListPtr aSubShapesAttrList = selectionList(SUBSHAPES_ID());
84   if(!aShapeAttrSelection.get() || !aSubShapesAttrList.get()) {
85     return;
86   }
87
88   // Get base shape without internal shapes.
89   GeomShapePtr aBaseShape = aShapeAttrSelection->value();
90   if(!aBaseShape.get()) {
91     return;
92   }
93   GeomAlgoAPI_ShapeBuilder aBuilder;
94   aBuilder.removeInternal(aBaseShape);
95   GeomShapePtr aResultShape = aBuilder.shape();
96
97   // Get list of shapes.
98   ListOfShape aShapesToAdd;
99   for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
100     AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
101     aShapesToAdd.push_back(anAttrSelectionInList->value());
102   }
103
104   // Copy sub-shapes from list to new shape.
105   if(!aShapesToAdd.empty()) {
106     aBuilder.add(aResultShape, aShapesToAdd);
107     aResultShape = aBuilder.shape();
108   }
109
110   // Store result.
111   const int aModVertexTag = 1;
112   const int aModEdgeTag = 2;
113   ResultBodyPtr aResultBody = document()->createBody(data());
114   aResultBody->storeModified(aBaseShape, aResultShape);
115   aResultBody->loadAndOrientModifiedShapes(&aBuilder, aBaseShape, GeomAPI_Shape::EDGE, aModEdgeTag,
116                                           "Modified_Edge", *aBuilder.mapOfSubShapes().get());
117   for(ListOfShape::const_iterator anIt = aShapesToAdd.cbegin(); anIt != aShapesToAdd.cend(); ++anIt) {
118     GeomAPI_Shape::ShapeType aShType = (*anIt)->shapeType();
119     aResultBody->loadAndOrientModifiedShapes(&aBuilder, *anIt, aShType,
120                                              aShType == GeomAPI_Shape::VERTEX ? aModVertexTag : aModEdgeTag,
121                                              aShType == GeomAPI_Shape::VERTEX ? "Modified_Vertex" : "Modified_Edge",
122                                              *aBuilder.mapOfSubShapes().get());
123   }
124   setResult(aResultBody);
125 }