NEMoSys  0.63.0
A modular, extensible resource with robust automated mesh generation, mesh quality analysis, adaptive mesh refinement, and data transfer between arbitrary meshes.
GeoManager.H
Go to the documentation of this file.
1 /*******************************************************************************
2 * Promesh *
3 * Copyright (C) 2022, IllinoisRocstar LLC. All rights reserved. *
4 * *
5 * Promesh is the property of IllinoisRocstar LLC. *
6 * *
7 * IllinoisRocstar LLC *
8 * Champaign, IL *
9 * www.illinoisrocstar.com *
10 * promesh@illinoisrocstar.com *
11 *******************************************************************************/
12 /*******************************************************************************
13 * This file is part of Promesh *
14 * *
15 * This version of Promesh is free software: you can redistribute it and/or *
16 * modify it under the terms of the GNU Lesser General Public License as *
17 * published by the Free Software Foundation, either version 3 of the License, *
18 * or (at your option) any later version. *
19 * *
20 * Promesh is distributed in the hope that it will be useful, but WITHOUT ANY *
21 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS *
22 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more *
23 * details. *
24 * *
25 * You should have received a copy of the GNU Lesser General Public License *
26 * along with this program. If not, see <https://www.gnu.org/licenses/>. *
27 * *
28 *******************************************************************************/
29 #ifndef NEMOSYS_GEOMANAGER_H_
30 #define NEMOSYS_GEOMANAGER_H_
31 
32 #include "nemosys_export.h"
33 
34 #include <array>
35 #include <memory>
36 #include <type_traits>
37 #include <unordered_map>
38 #include <utility>
39 #include <vector>
40 
41 #include <TopAbs_ShapeEnum.hxx>
42 #include <TopTools_ShapeMapHasher.hxx>
43 
44 #include "Geometry/ShapeData.H"
45 
46 class TopoDS_Compound;
47 class TopoDS_Shape;
48 class BRepBuilderAPI_MakeShape;
49 class BRepAlgoAPI_BooleanOperation;
50 class BRepBuilderAPI_Sewing;
51 
52 namespace NEM {
53 namespace GEO {
54 
55 /**
56  * @brief Class to manage @c TopoDS_Shapes along with metadata
57  * @details Handles results of @c BRepBuilderAPI_MakeShape (in particular,
58  * boolean operations) by delegating to the arguments' metadata. Also see @c
59  * NEM::GEO::ShapeData
60  */
61 class NEMOSYS_EXPORT GeoManager {
62  public:
63  /**
64  * Hasher based on TopTools_ShapeMapHasher, which relies on
65  * TopoDS_Shape::IsSame, which is not TopoDS_Shape::operator==
66  */
68  std::size_t operator()(const TopoDS_Shape &shape) const {
69  return TopTools_ShapeMapHasher::HashCode(shape, IntegerLast());
70  }
71  };
72 
73  /**
74  * Equality operator based on TopTools_ShapeMapHasher, which relies on
75  * TopoDS_Shape::IsSame, which is not TopoDS_Shape::operator==
76  */
78  bool operator()(const TopoDS_Shape &shape1,
79  const TopoDS_Shape &shape2) const {
80  return TopTools_ShapeMapHasher::IsEqual(shape1, shape2);
81  }
82  };
83  using MapType =
84  std::unordered_map<TopoDS_Shape, std::shared_ptr<ShapeData>,
86 
87  /**
88  * Create an empty geometry manager
89  * @param dim Shapes of this dimension (clipped to be between 1 and 3,
90  * inclusive) are treated as first-class citizens, with lower-dimensional
91  * shapes assumed to be subshapes.
92  */
93  explicit GeoManager(int dim);
94 
95  /**
96  * Get dimension of geometry
97  * @return dimension
98  */
99  int getDim() const;
100  /**
101  * Set the dimension
102  * @param dim dimension (between 1 and 3)
103  */
104  void setDim(int dim);
105 
106  /**
107  * Modify this geoMetadata after a @c BRepBuilderAPI_MakeShape operation
108  * @param op Modification of geometry
109  * @param shapes Geometry objects assumed to be inputs of @p op. The
110  * corresponding values in the map dictate the behavior of the resulting
111  * metadata.
112  * @param typesToTraverse Traverse the subshapes of @p shapes with these
113  * types. An empty list means only @p shapes will be examined.
114  * @return Shapes that are no longer present in the output of @p op
115  */
116  std::vector<TopoDS_Shape> modify(
117  BRepBuilderAPI_MakeShape &op, const std::vector<TopoDS_Shape> &shapes,
118  const std::vector<TopAbs_ShapeEnum> &typesToTraverse = {
119  TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE, TopAbs_SOLID});
120 
121  /**
122  * @copydoc GeoManager::modify(BRepBuilderAPI_MakeShape &, const
123  * std::vector<TopoDS_Shape> &, const std::vector<TopAbs_ShapeEnum> &)
124  */
125  std::vector<TopoDS_Shape> modify(
126  BRepBuilderAPI_MakeShape &op, const TopTools_ListOfShape &shapes,
127  const std::vector<TopAbs_ShapeEnum> &typesToTraverse = {
128  TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE, TopAbs_SOLID});
129 
130  /**
131  * @copydoc GeoManager::modify(BRepBuilderAPI_MakeShape &, const
132  * std::vector<TopoDS_Shape> &, const std::vector<TopAbs_ShapeEnum> &)
133  * shapes are inferred from @op
134  */
135  std::array<std::vector<TopoDS_Shape>, 2> modify(
136  BRepAlgoAPI_BooleanOperation &op,
137  const std::vector<TopAbs_ShapeEnum> &typesToTraverse = {
138  TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE, TopAbs_SOLID});
139 
140  /**
141  * @copydoc GeoManager::modify(BRepBuilderAPI_MakeShape &, const
142  * std::vector<TopoDS_Shape> &, const std::vector<TopAbs_ShapeEnum> &)
143  */
144  std::vector<TopoDS_Shape> modify(
145  BRepBuilderAPI_Sewing &op, const std::vector<TopoDS_Shape> &shapes,
146  const std::vector<TopAbs_ShapeEnum> &typesToTraverse = {
147  TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE, TopAbs_SOLID});
148 
149  /**
150  * @brief Remove a shape from the map
151  * @details Note there is no effect if shape's dimension is less than the
152  * instance dimension (to avoid removing shapes that are still referenced by
153  * other shapes).
154  * @param shape Shape to remove, if present
155  */
156  void deleteShapes(const TopoDS_Shape &shape);
157 
158  /**
159  * @brief Delete a set of shapes
160  * @copydetails GeoManager::deleteShapes(const TopoDS_Shape &)
161  * @param shapes Shapes to remove, if present
162  */
163  void deleteShapes(const std::vector<TopoDS_Shape> &shapes);
164 
165  /**
166  * Create a compound from shapes present in the map that have same dimension
167  * as the instance.
168  * @return compound of shapes
169  */
170  TopoDS_Compound buildCompound() const;
171 
172  /**
173  * @copydoc GeoManager::get(const TopoDS_Shape &) const
174  */
175  std::shared_ptr<ShapeData> *get(const TopoDS_Shape &shape);
176 
177  /**
178  * Get the data from the map
179  * @param shape Shape to query
180  * @return Pointer to data in the map, or nullptr if shape not in map. If a
181  * pointer to a nullptr, then shape is in map, but data in map is null.
182  */
183  const std::shared_ptr<ShapeData> *get(const TopoDS_Shape &shape) const;
184 
185  std::pair<MapType::iterator, bool> insert(
186  const TopoDS_Shape &shape, std::shared_ptr<ShapeData> shapeData);
187 
188  /**
189  * Helper to insert a shape and data into the map
190  * @tparam T @c ShapeData type
191  * @param shape Shape to insert
192  * @param shapeData Data to associate to with @shape
193  * @return iterator to inserted or already existing element, and whether or
194  * not there was an insertion
195  */
196  template <typename T>
197  std::pair<MapType::iterator, bool> insertForward(const TopoDS_Shape &shape,
198  T &&shapeData) {
199  auto emplaceIter = getMap().emplace(shape, std::shared_ptr<ShapeData>{});
200  if (emplaceIter.second) {
201  emplaceIter.first->second.reset(
202  new typename std::decay<T>::type(std::forward<T>(shapeData)));
203  }
204  return emplaceIter;
205  }
206 
207  /**
208  * Helper to insert a shape and construct data
209  * @tparam T @c ShapeData type
210  * @tparam Args Types of @p T constructor
211  * @param shape Shape to insert
212  * @param args Arguments of @p T constructor for data to associate with @p
213  * shape
214  * @return iterator to inserted or already existing element, and whether or
215  * not there was an insertion
216  */
217  template <typename T, typename... Args>
218  std::pair<MapType::iterator, bool> insertConstruct(const TopoDS_Shape &shape,
219  Args &&...args) {
220  auto emplaceIter = getMap().emplace(shape, std::shared_ptr<ShapeData>{});
221  if (emplaceIter.second) {
222  emplaceIter.first->second.reset(new T(std::forward<Args>(args)...));
223  }
224  return emplaceIter;
225  }
226 
227  /*
228  * @copydoc GeoManager::getMap() const
229  */
230  MapType &getMap();
231 
232  /**
233  * Get the shapes and data
234  * @return Map from shapes to data
235  */
236  const MapType &getMap() const;
237 
238  protected:
240  int dim_;
241 
242  bool isChild(const TopoDS_Shape &shape) const;
243 
244  void modifyImpl(BRepBuilderAPI_MakeShape &op, const TopoDS_Shape &shape,
245  std::vector<TopoDS_Shape> &shapesToRemove);
246 };
247 
248 } // namespace GEO
249 } // namespace NEM
250 
251 #endif // NEMOSYS_GEOMANAGER_H_
std::unordered_map< TopoDS_Shape, std::shared_ptr< ShapeData >, ShapeMapHasher_Hash, ShapeMapHasher_KeyEqual > MapType
Definition: GeoManager.H:85
Class to manage TopoDS_Shapes along with metadata.
Definition: GeoManager.H:61
bool operator()(const TopoDS_Shape &shape1, const TopoDS_Shape &shape2) const
Definition: GeoManager.H:78
Hasher based on TopTools_ShapeMapHasher, which relies on TopoDS_Shape::IsSame, which is not TopoDS_Sh...
Definition: GeoManager.H:67
std::size_t operator()(const TopoDS_Shape &shape) const
Definition: GeoManager.H:68
Equality operator based on TopTools_ShapeMapHasher, which relies on TopoDS_Shape::IsSame, which is not TopoDS_Shape::operator==.
Definition: GeoManager.H:77
std::pair< MapType::iterator, bool > insertConstruct(const TopoDS_Shape &shape, Args &&...args)
Helper to insert a shape and construct data.
Definition: GeoManager.H:218
std::pair< MapType::iterator, bool > insertForward(const TopoDS_Shape &shape, T &&shapeData)
Helper to insert a shape and data into the map.
Definition: GeoManager.H:197