Salome HOME
Test case for issue #2918.
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_VersionedBoolean.h
1 // Copyright (C) 2014-2019  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #ifndef FeaturesPlugin_VersionedBoolean_H_
21 #define FeaturesPlugin_VersionedBoolean_H_
22
23 #include "FeaturesPlugin.h"
24 #include "FeaturesPlugin_Tools.h"
25
26 #include <GeomAlgoAPI_Tools.h>
27
28 #include <ModelAPI_Feature.h>
29
30 class ModelAPI_Attribute;
31 class ModelAPI_Result;
32 class GeomAlgoAPI_MakeShapeList;
33
34 /// \class FeaturesPlugin_VersionedBoolean
35 /// \ingroup Plugins
36 /// \brief Feature controls a version of Boolean operations.
37 class FeaturesPlugin_VersionedBoolean : public ModelAPI_Feature
38 {
39 public:
40   static const int THE_VERSION_0 = 0;
41   static const int THE_VERSION_1 = 20190506;
42
43   /// Attribute name of the version of Boolean feature
44   inline static const std::string& VERSION_ID()
45   {
46     static const std::string MY_VERSION_ID("version");
47     return MY_VERSION_ID;
48   }
49
50 protected:
51
52   /// Use plugin manager for features creation.
53   FeaturesPlugin_VersionedBoolean() {}
54
55   /// Initialize version field of the Boolean feature.
56   /// The version is initialized for newly created features,
57   /// not read from previously stored document.
58   void initVersion(const int theVersion,
59                    const std::shared_ptr<ModelAPI_Attribute> theObjectsAttr
60                             = std::shared_ptr<ModelAPI_Attribute>(),
61                    const std::shared_ptr<ModelAPI_Attribute> theToolsAttr
62                             = std::shared_ptr<ModelAPI_Attribute>());
63
64   /// Auxiliary class to store hierarchy of Boolean operation objects/tools
65   /// and their parent shapes (compounds or compsolids)
66   class ObjectHierarchy {
67     typedef std::pair<GeomShapePtr, ListOfShape> ShapeAndSubshapes;
68     typedef std::map<GeomShapePtr, GeomShapePtr, GeomAPI_Shape::Comparator> MapShapeToParent;
69     typedef std::map<GeomShapePtr, size_t, GeomAPI_Shape::Comparator> MapShapeToIndex;
70     typedef std::set<GeomShapePtr, GeomAPI_Shape::Comparator> SetOfShape;
71
72     ListOfShape myObjects; ///< list of objects/tools of Boolean operation
73     MapShapeToParent myParent; ///< refer a shape to compound/compsolid containing it
74     /// indices of compounds/compsolids to keep the order of parent shapes
75     /// corresponding to the order of objects
76     MapShapeToIndex  myParentIndices;
77     /// list of shape and its subshapes stored according to the index of parent shape
78     std::vector<ShapeAndSubshapes> mySubshapes;
79
80     SetOfShape myProcessedObjects;
81
82   public:
83     /// Add object of Boolean opration
84     void AddObject(const GeomShapePtr& theObject);
85
86     /// Maps shape and its parent
87     void AddParent(const GeomShapePtr& theShape, const GeomShapePtr& theParent);
88
89     /// Return parent shape for the given, or empty if it is a high-level shape.
90     /// By default, the parent and all its subshapes are marked as processed for further skip.
91     GeomShapePtr Parent(const GeomShapePtr& theShape, bool theMarkProcessed = true);
92
93     /// Marke the shape as already processed
94     void MarkProcessed(const GeomShapePtr& theShape);
95     /// Marke list ofshapes as already processed
96     void MarkProcessed(const ListOfShape& theShapes);
97
98     /// Split compound/compsolid shape for subshapes selected for Boolean operation and the other.
99     void SplitCompound(const GeomShapePtr& theCompShape,
100                        ListOfShape& theUsed,
101                        ListOfShape& theNotUsed) const;
102
103     /// Generates the list of top-level compounds, which contain the objects of Boolean operation.
104     /// The generated list will contain only shapes unused during the Boolean operation.
105     void CompoundsOfUnusedObjects(ListOfShape& theDestination) const;
106
107     /// Return \c true if there is no object in hierarchy
108     bool IsEmpty() const;
109
110     /// Return list of objects
111     const ListOfShape& Objects() const { return myObjects; }
112     /// Separate objects of the given range of types and all other objects
113     void ObjectsByType(ListOfShape& theShapesByType, ListOfShape& theOtherShapes,
114         const GeomAPI_Shape::ShapeType theMinType = GeomAPI_Shape::COMPOUND,
115         const GeomAPI_Shape::ShapeType theMaxType = GeomAPI_Shape::SHAPE) const;
116
117   private:
118     GeomShapePtr collectUnusedSubs(const GeomShapePtr theTopLevelCompound,
119                                    const SetOfShape& theUsed) const;
120
121   public:
122     class Iterator {
123       friend class ObjectHierarchy;
124
125       ObjectHierarchy* myHierarchy;
126       ListOfShape::iterator myObject;
127
128       Iterator() {}
129       Iterator(ObjectHierarchy* theHierarchy, bool isBegin = true);
130
131       void SkipAlreadyProcessed();
132
133     public:
134       bool operator==(const Iterator&) const;
135       bool operator!=(const Iterator&) const;
136
137       Iterator& operator++();
138       Iterator  operator++(int);
139
140       GeomShapePtr operator*() const;
141     };
142
143     Iterator Begin();
144     Iterator End();
145   };
146
147   /// Process SelectionList attribute and fill the objects hierarchy.
148   bool processAttribute(const std::string& theAttributeName,
149                         ObjectHierarchy& theObjects,
150                         ListOfShape& thePlanesList);
151
152   /// Perform Boolean operation of the object with the tools.
153   /// In case of theResultCompound is not empty, the result of Boolean operation
154   /// is added to this compound, and corresponding ResultBody is not generated.
155   /// \return \c false if something went wrong
156   bool processObject(const GeomAlgoAPI_Tools::BOPType theBooleanType,
157                      const GeomShapePtr& theObject,
158                      const ListOfShape& theTools,
159                      const ListOfShape& thePlanes,
160                      int& theResultIndex,
161                      std::vector<FeaturesPlugin_Tools::ResultBaseAlgo>& theResultBaseAlgoList,
162                      ListOfShape& theResultShapesList,
163                      GeomShapePtr theResulCompound = GeomShapePtr());
164
165   /// Perform Boolean operation of the Compsolid with the tools
166   /// In case of theResultCompound is not empty, the result of Boolean operation
167   /// is added to this compound, and corresponding ResultBody is not generated.
168   /// \return \c false if something went wrong
169   bool processCompsolid(const GeomAlgoAPI_Tools::BOPType theBooleanType,
170                         ObjectHierarchy& theCompsolidHierarchy,
171                         const GeomShapePtr& theCompsolid,
172                         const ListOfShape& theTools,
173                         const ListOfShape& thePlanes,
174                         int& theResultIndex,
175                         std::vector<FeaturesPlugin_Tools::ResultBaseAlgo>& theResultBaseAlgoList,
176                         ListOfShape& theResultShapesList,
177                         GeomShapePtr theResulCompound = GeomShapePtr());
178
179   /// Perform Boolean operation of the Compound with the tools
180   /// In case of theResultCompound is not empty, the result of Boolean operation
181   /// is added to this compound, and corresponding ResultBody is not generated.
182   /// \return \c false if something went wrong
183   bool processCompound(const GeomAlgoAPI_Tools::BOPType theBooleanType,
184                        ObjectHierarchy& theCompoundHierarchy,
185                        const GeomShapePtr& theCompound,
186                        const ListOfShape& theTools,
187                        int& theResultIndex,
188                        std::vector<FeaturesPlugin_Tools::ResultBaseAlgo>& theResultBaseAlgoList,
189                        ListOfShape& theResultShapesList,
190                        GeomShapePtr theResulCompound = GeomShapePtr());
191
192   /// Resize planes to fit them to the bounding box of the given lins of objects.
193   static void resizePlanes(const ListOfShape& theObjects,
194                            ListOfShape& thePlanes,
195                            std::shared_ptr<GeomAlgoAPI_MakeShapeList>& theMakeShapeList);
196
197   /// Process unused sub-shapes of compounds.
198   /// Keep the compound hierarchy, but merge top-level compounds
199   /// into a single compound and add the result of the FUSE operation.
200   GeomShapePtr keepUnusedSubsOfCompound(
201       const GeomShapePtr& theResult,
202       const ObjectHierarchy& theObjectsHierarchy,
203       const ObjectHierarchy& theToolsHierarchy,
204       std::shared_ptr<GeomAlgoAPI_MakeShapeList> theMakeShapeList);
205
206   /// Return version of the feature
207   int version();
208
209 private:
210   void parentForShape(const GeomShapePtr& theShape,
211                       const std::shared_ptr<ModelAPI_Result>& theContext,
212                       ObjectHierarchy& theShapesHierarchy);
213 };
214
215 #endif