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.C
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 #include "Geometry/GeoManager.H"
30 
31 #include <unordered_set>
32 
33 #include <BRepAlgoAPI_BooleanOperation.hxx>
34 #include <BRepBuilderAPI_Sewing.hxx>
35 #include <BRep_Builder.hxx>
36 #include <TopExp_Explorer.hxx>
37 #include <TopTools_ListOfShape.hxx>
38 #include <TopoDS_Compound.hxx>
39 #include <TopoDS_Shape.hxx>
40 
41 #include "Geometry/ShapeData.H"
42 
43 namespace NEM {
44 namespace GEO {
45 
47  : map_(),
48  dim_(std::min(3, std::max(1, dim))) {}
49 
50 int GeoManager::getDim() const { return dim_; }
51 
52 void GeoManager::setDim(int dim) { dim_ = dim; }
53 
54 template <typename Op, typename T, typename F>
55 std::vector<TopoDS_Shape> modifyTempl(
56  Op &&op, T &&shapes, const std::vector<TopAbs_ShapeEnum> &typesToTraverse,
57  F &&modifyFunc) {
58  std::vector<TopoDS_Shape> shapesToRemove;
59  for (auto &shape : shapes) {
60  if (typesToTraverse.empty()) {
61  modifyFunc(shape, shapesToRemove);
62  } else {
63  for (auto &shapeType : typesToTraverse) {
64  for (TopExp_Explorer explorer{shape, shapeType}; explorer.More();
65  explorer.Next()) {
66  modifyFunc(explorer.Current(), shapesToRemove);
67  }
68  }
69  }
70  }
71  return shapesToRemove;
72 }
73 
74 std::vector<TopoDS_Shape> GeoManager::modify(
75  BRepBuilderAPI_MakeShape &op, const std::vector<TopoDS_Shape> &shapes,
76  const std::vector<TopAbs_ShapeEnum> &typesToTraverse) {
77  return modifyTempl(op, shapes, typesToTraverse,
78  [this, &op](const TopoDS_Shape &shape,
79  std::vector<TopoDS_Shape> &shapesToRemove) {
80  this->modifyImpl(op, shape, shapesToRemove);
81  });
82 }
83 
84 std::vector<TopoDS_Shape> GeoManager::modify(
85  BRepBuilderAPI_MakeShape &op, const TopTools_ListOfShape &shapes,
86  const std::vector<TopAbs_ShapeEnum> &typesToTraverse) {
87  return modifyTempl(op, shapes, typesToTraverse,
88  [this, &op](const TopoDS_Shape &shape,
89  std::vector<TopoDS_Shape> &shapesToRemove) {
90  this->modifyImpl(op, shape, shapesToRemove);
91  });
92 }
93 
94 std::array<std::vector<TopoDS_Shape>, 2> GeoManager::modify(
95  BRepAlgoAPI_BooleanOperation &op,
96  const std::vector<TopAbs_ShapeEnum> &typesToTraverse) {
97  return {this->modify(op, op.Arguments(), typesToTraverse),
98  this->modify(op, op.Tools(), typesToTraverse)};
99 }
100 
101 std::vector<TopoDS_Shape> GeoManager::modify(
102  BRepBuilderAPI_Sewing &op, const std::vector<TopoDS_Shape> &shapes,
103  const std::vector<TopAbs_ShapeEnum> &typesToTraverse) {
104  return modifyTempl(
105  op, shapes, typesToTraverse,
106  [this, &op](const TopoDS_Shape &shape,
107  std::vector<TopoDS_Shape> &shapesToRemove) {
108  auto findIter = map_.find(shape);
109  if (findIter != map_.end()) {
110  auto shapeType = shape.ShapeType();
111  auto modified =
112  (shapeType == TopAbs_FACE || shapeType == TopAbs_SHELL)
113  ? op.Modified(shape)
114  : op.ModifiedSubShape(shape);
115  if (!modified.IsSame(shape)) {
116  TopTools_ListOfShape modShapes;
117  modShapes.Append(modified);
118  if (findIter->second) {
119  findIter->second->updateModified(shape, modShapes, *this);
120  }
121  shapesToRemove.emplace_back(shape);
122  }
123  }
124  });
125 }
126 
127 void GeoManager::deleteShapes(const TopoDS_Shape &shape) {
128  if (!isChild(shape)) {
129  auto findIter = map_.find(shape);
130  if (findIter != map_.end()) {
131  if (findIter->second) {
132  findIter->second->updateDeleted(shape, *this);
133  }
134  map_.erase(findIter);
135  }
136  }
137 }
138 
139 void GeoManager::deleteShapes(const std::vector<TopoDS_Shape> &shapes) {
140  for (auto &shape : shapes) {
141  this->deleteShapes(shape);
142  }
143 }
144 
145 TopoDS_Compound GeoManager::buildCompound() const {
146  BRep_Builder builder;
147  TopoDS_Compound compound;
148  // If no top-dimension shapes, then return a null compound
149  bool addedShapes = false;
150  for (auto &shape : map_) {
151  if (!isChild(shape.first)) {
152  if (!addedShapes) {
153  builder.MakeCompound(compound);
154  addedShapes = true;
155  }
156  builder.Add(compound, shape.first);
157  }
158  }
159  return compound;
160 }
161 
162 std::shared_ptr<ShapeData> *GeoManager::get(const TopoDS_Shape &shape) {
163  auto findIter = map_.find(shape);
164  if (findIter != map_.end()) {
165  return &findIter->second;
166  } else {
167  return nullptr;
168  }
169 }
170 
171 const std::shared_ptr<ShapeData> *GeoManager::get(
172  const TopoDS_Shape &shape) const {
173  auto findIter = map_.find(shape);
174  if (findIter != map_.end()) {
175  return &findIter->second;
176  } else {
177  return nullptr;
178  }
179 }
180 
181 std::pair<GeoManager::MapType::iterator, bool> GeoManager::insert(
182  const TopoDS_Shape &shape, std::shared_ptr<ShapeData> shapeData) {
183  return map_.emplace(shape, std::move(shapeData));
184 }
185 
187 
188 const GeoManager::MapType &GeoManager::getMap() const { return map_; }
189 
190 bool GeoManager::isChild(const TopoDS_Shape &shape) const {
191  int shapeDim;
192  switch (shape.ShapeType()) {
193  case TopAbs_COMPSOLID:
194  case TopAbs_SOLID: shapeDim = 3; break;
195  case TopAbs_SHELL:
196  case TopAbs_FACE: shapeDim = 2; break;
197  case TopAbs_WIRE:
198  case TopAbs_EDGE: shapeDim = 1; break;
199  case TopAbs_VERTEX: shapeDim = 0; break;
200  case TopAbs_COMPOUND:
201  case TopAbs_SHAPE:
202  default: return false;
203  }
204  return shapeDim < dim_;
205 }
206 
207 void GeoManager::modifyImpl(BRepBuilderAPI_MakeShape &op,
208  const TopoDS_Shape &shape,
209  std::vector<TopoDS_Shape> &shapesToRemove) {
210  if (op.IsDeleted(shape)) {
211  shapesToRemove.emplace_back(shape);
212  } else {
213  auto findIter = map_.find(shape);
214  if (findIter != map_.end()) {
215  auto &generated = op.Generated(shape);
216  if (!generated.IsEmpty()) {
217  if (findIter->second) {
218  findIter->second->updateGenerated(shape, generated, *this);
219  }
220  }
221  auto &modified = op.Modified(shape);
222  if (!modified.IsEmpty()) {
223  if (findIter->second) {
224  findIter->second->updateModified(shape, modified, *this);
225  }
226  shapesToRemove.emplace_back(shape);
227  }
228  }
229  }
230 }
231 
232 } // namespace NUCMESH
233 } // namespace NEM
std::pair< MapType::iterator, bool > insert(const TopoDS_Shape &shape, std::shared_ptr< ShapeData > shapeData)
Definition: GeoManager.C:181
std::unordered_map< TopoDS_Shape, std::shared_ptr< ShapeData >, ShapeMapHasher_Hash, ShapeMapHasher_KeyEqual > MapType
Definition: GeoManager.H:85
std::shared_ptr< ShapeData > * get(const TopoDS_Shape &shape)
Get the data from the map.
Definition: GeoManager.C:162
void deleteShapes(const TopoDS_Shape &shape)
Remove a shape from the map.
Definition: GeoManager.C:127
int getDim() const
Get dimension of geometry.
Definition: GeoManager.C:50
STL namespace.
std::vector< TopoDS_Shape > modifyTempl(Op &&op, T &&shapes, const std::vector< TopAbs_ShapeEnum > &typesToTraverse, F &&modifyFunc)
Definition: GeoManager.C:55
static constexpr auto shapeType
Definition: NucMeshJson.H:81
bool isChild(const TopoDS_Shape &shape) const
Definition: GeoManager.C:190
void modifyImpl(BRepBuilderAPI_MakeShape &op, const TopoDS_Shape &shape, std::vector< TopoDS_Shape > &shapesToRemove)
Definition: GeoManager.C:207
TopoDS_Compound buildCompound() const
Create a compound from shapes present in the map that have same dimension as the instance.
Definition: GeoManager.C:145
MapType & getMap()
Definition: GeoManager.C:186
GeoManager(int dim)
Create an empty geometry manager.
Definition: GeoManager.C:46
std::vector< TopoDS_Shape > modify(BRepBuilderAPI_MakeShape &op, const std::vector< TopoDS_Shape > &shapes, const std::vector< TopAbs_ShapeEnum > &typesToTraverse={ TopAbs_VERTEX, TopAbs_EDGE, TopAbs_FACE, TopAbs_SOLID})
Modify this geoMetadata after a BRepBuilderAPI_MakeShape operation.
Definition: GeoManager.C:74
void setDim(int dim)
Set the dimension.
Definition: GeoManager.C:52