gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
OCCAttributes.h
Go to the documentation of this file.
1 // Gmsh - Copyright (C) 1997-2022 C. Geuzaine, J.-F. Remacle
2 //
3 // See the LICENSE.txt file in the Gmsh root directory for license information.
4 // Please report all issues on https://gitlab.onelab.info/gmsh/gmsh/issues.
5 
6 #ifndef OCC_ATTRIBUTES_H
7 #define OCC_ATTRIBUTES_H
8 
9 #include <vector>
10 #include <string>
11 #include "GmshConfig.h"
12 #include "GmshMessage.h"
13 #include "OS.h"
14 #include "Context.h"
15 #include "rtree.h"
16 
17 #if defined(HAVE_OCC)
18 
19 #include <Bnd_Box.hxx>
20 #include <BRepBndLib.hxx>
21 #include <TopoDS_Shape.hxx>
22 #include <BRepTools.hxx>
23 
24 class OCCAttributes {
25 private:
26  int _dim;
27  TopoDS_Shape _shape;
28  double _meshSize;
29  ExtrudeParams *_extrude;
30  int _sourceDim;
31  TopoDS_Shape _sourceShape;
32  std::string _label;
33  std::vector<double> _color;
34 
35 public:
36  OCCAttributes() : _dim(-1), _meshSize(MAX_LC), _extrude(0), _sourceDim(-1) {}
37  OCCAttributes(int dim, TopoDS_Shape shape)
38  : _dim(dim), _shape(shape), _meshSize(MAX_LC), _extrude(0), _sourceDim(-1)
39  {
40  }
41  OCCAttributes(int dim, TopoDS_Shape shape, double size)
42  : _dim(dim), _shape(shape), _meshSize(size), _extrude(0), _sourceDim(-1)
43  {
44  }
45  OCCAttributes(int dim, TopoDS_Shape shape, ExtrudeParams *e, int sourceDim,
46  TopoDS_Shape sourceShape)
47  : _dim(dim), _shape(shape), _meshSize(MAX_LC), _extrude(e),
48  _sourceDim(sourceDim), _sourceShape(sourceShape)
49  {
50  }
51  OCCAttributes(int dim, TopoDS_Shape shape, const std::string &label)
52  : _dim(dim), _shape(shape), _meshSize(MAX_LC), _extrude(0), _sourceDim(-1),
53  _label(label)
54  {
55  }
56  OCCAttributes(int dim, TopoDS_Shape shape, double r, double g, double b,
57  double a = 1., int boundary = 0)
58  : _dim(dim), _shape(shape), _meshSize(MAX_LC), _extrude(0), _sourceDim(-1)
59  {
60  _color.resize(boundary ? 5 : 4);
61  _color[0] = r;
62  _color[1] = g;
63  _color[2] = b;
64  _color[3] = a;
65  if(boundary) _color[4] = boundary;
66  }
67  ~OCCAttributes() {}
68  int getDim() { return _dim; }
69  TopoDS_Shape getShape() { return _shape; }
70  double getMeshSize() { return _meshSize; }
71  ExtrudeParams *getExtrudeParams() { return _extrude; }
72  int getSourceDim() { return _sourceDim; }
73  TopoDS_Shape getSourceShape() { return _sourceShape; }
74  const std::string &getLabel() { return _label; }
75  const std::vector<double> &getColor() { return _color; }
76 };
77 
78 // attributes are stored according to the center of their associated shape
79 // bounding box; this allows to efficiently search for potential matches, even
80 // if the actual underlying shape has been modified (typically through boolean
81 // fragments)
82 class OCCAttributesRTree {
83 private:
85  std::vector<OCCAttributes *> _all;
86  double _tol;
87  static bool rtree_callback(OCCAttributes *v, void *ctx)
88  {
89  std::vector<OCCAttributes *> *out =
90  static_cast<std::vector<OCCAttributes *> *>(ctx);
91  out->push_back(v);
92  return true;
93  }
94  void _find(int dim, const TopoDS_Shape &shape,
95  std::vector<OCCAttributes *> &attr, bool requireMeshSize,
96  bool requireExtrudeParams, bool requireLabel, bool requireColor,
97  bool excludeSame)
98  {
99  attr.clear();
100  if(dim < 0 || dim > 3) return;
101  Bnd_Box box;
102  try {
103  BRepBndLib::Add(shape, box, Standard_False);
104  if(box.IsVoid()) {
105  Msg::Debug(
106  "Searching for (null or degenerate) shape with void bounding box");
107  return;
108  }
109  } catch(Standard_Failure &err) {
110  Msg::Error("OpenCASCADE exception %s", err.GetMessageString());
111  return;
112  }
113  double xmin, ymin, zmin, xmax, ymax, zmax;
114  box.Get(xmin, ymin, zmin, xmax, ymax, zmax);
115  double x = 0.5 * (xmin + xmax);
116  double y = 0.5 * (ymin + ymax);
117  double z = 0.5 * (zmin + zmax);
118  double bmin[3] = {x - _tol, y - _tol, z - _tol};
119  double bmax[3] = {x + _tol, y + _tol, z + _tol};
120  std::vector<OCCAttributes *> tmp;
121  _rtree[dim]->Search(bmin, bmax, rtree_callback, &tmp);
122  Msg::Debug("OCCRTree found %d matches at (%g,%g,%g) in tree of size %d",
123  (int)tmp.size(), x, y, z, (int)_all.size());
124  if(tmp.empty()) { // no match
125  return;
126  }
127  if(!excludeSame) {
128  for(std::size_t i = 0; i < tmp.size(); i++) {
129  if(requireMeshSize && tmp[i]->getMeshSize() == MAX_LC) continue;
130  if(requireExtrudeParams && !tmp[i]->getExtrudeParams()) continue;
131  if(requireLabel && tmp[i]->getLabel().empty()) continue;
132  if(requireColor && tmp[i]->getColor().empty()) continue;
133  if(shape.IsSame(tmp[i]->getShape())) { // exact match: same shape
134  attr.push_back(tmp[i]);
135  Msg::Debug("OCCRTree exact match");
136  return;
137  }
138  }
139  }
140  // potential matches based on bounding box
141  for(std::size_t i = 0; i < tmp.size(); i++) {
142  if(requireMeshSize && tmp[i]->getMeshSize() == MAX_LC) continue;
143  if(requireExtrudeParams && !tmp[i]->getExtrudeParams()) continue;
144  if(requireLabel && tmp[i]->getLabel().empty()) continue;
145  if(requireColor && tmp[i]->getColor().empty()) continue;
146  Bnd_Box box2;
147  BRepBndLib::Add(tmp[i]->getShape(), box2, Standard_False);
148  double xmin2, ymin2, zmin2, xmax2, ymax2, zmax2;
149  box2.Get(xmin2, ymin2, zmin2, xmax2, ymax2, zmax2);
150  if(std::abs(xmin - xmin2) < _tol && std::abs(xmax - xmax2) < _tol &&
151  std::abs(ymin - ymin2) < _tol && std::abs(ymax - ymax2) < _tol &&
152  std::abs(zmin - zmin2) < _tol && std::abs(zmax - zmax2) < _tol) {
153  attr.push_back(tmp[i]);
154  }
155  }
156  Msg::Debug("OCCRtree %d matches after bounding box filtering",
157  (int)attr.size());
158  }
159 
160 public:
161  OCCAttributesRTree(double tolerance = 1.e-8)
162  {
163  for(int dim = 0; dim < 4; dim++)
164  _rtree[dim] = new RTree<OCCAttributes *, double, 3, double>();
165  _tol = tolerance;
166  }
167  ~OCCAttributesRTree()
168  {
169  clear();
170  for(int dim = 0; dim < 4; dim++) delete _rtree[dim];
171  }
172  void clear()
173  {
174  for(int dim = 0; dim < 4; dim++) _rtree[dim]->RemoveAll();
175  for(std::size_t i = 0; i < _all.size(); i++) delete _all[i];
176  _all.clear();
177  }
178  void print(const std::string &fileName = "")
179  {
180  FILE *fp = stdout;
181  if(fileName.size()) {
182  fp = Fopen(fileName.c_str(), "w");
183  if(!fp) {
184  Msg::Error("Could not open file '%s'", fileName.c_str());
185  return;
186  }
187  }
188  fprintf(fp, "View(\"rtree mesh sizes\"){\n");
189  for(std::size_t i = 0; i < _all.size(); i++) {
190  if(_all[i]->getDim() != 0) continue;
191  if(_all[i]->getMeshSize() == MAX_LC) continue;
192  gp_Pnt pnt = BRep_Tool::Pnt(TopoDS::Vertex(_all[i]->getShape()));
193  fprintf(fp, "SP(%g,%g,%g){%g};\n", pnt.X(), pnt.Y(), pnt.Z(),
194  _all[i]->getMeshSize());
195  }
196  fprintf(fp, "};\n");
197  if(fileName.size()) fclose(fp);
198  }
199  void insert(OCCAttributes *v)
200  {
201  _all.push_back(v);
202  if(v->getDim() < 0 || v->getDim() > 3) return;
203  Bnd_Box box;
204  try {
205  BRepBndLib::Add(v->getShape(), box, Standard_False);
206  if(box.IsVoid()) {
207  Msg::Debug(
208  "Inserting (null or degenerate) shape with void bounding box");
209  // BRepTools::Dump(v->getShape(), std::cout);
210  return;
211  }
212  } catch(Standard_Failure &err) {
213  Msg::Error("OpenCASCADE exception %s", err.GetMessageString());
214  return;
215  }
216  double xmin, ymin, zmin, xmax, ymax, zmax;
217  box.Get(xmin, ymin, zmin, xmax, ymax, zmax);
218  double x = 0.5 * (xmin + xmax);
219  double y = 0.5 * (ymin + ymax);
220  double z = 0.5 * (zmin + zmax);
221  double bmin[3] = {x - _tol, y - _tol, z - _tol};
222  double bmax[3] = {x + _tol, y + _tol, z + _tol};
223  _rtree[v->getDim()]->Insert(bmin, bmax, v);
224  }
225  void remove(OCCAttributes *v)
226  {
227  if(v->getDim() < 0 || v->getDim() > 3) return;
228  Bnd_Box box;
229  try {
230  BRepBndLib::Add(v->getShape(), box, Standard_False);
231  if(box.IsVoid()) {
232  Msg::Debug(
233  "Removing (null or degenerate) shape with void bounding box");
234  // BRepTools::Dump(v->getShape(), std::cout);
235  return;
236  }
237  } catch(Standard_Failure &err) {
238  Msg::Error("OpenCASCADE exception %s", err.GetMessageString());
239  return;
240  }
241  double xmin, ymin, zmin, xmax, ymax, zmax;
242  box.Get(xmin, ymin, zmin, xmax, ymax, zmax);
243  double x = 0.5 * (xmin + xmax);
244  double y = 0.5 * (ymin + ymax);
245  double z = 0.5 * (zmin + zmax);
246  double bmin[3] = {x - _tol, y - _tol, z - _tol};
247  double bmax[3] = {x + _tol, y + _tol, z + _tol};
248  std::vector<OCCAttributes *> tmp;
249  _rtree[v->getDim()]->Search(bmin, bmax, rtree_callback, &tmp);
250  for(std::size_t i = 0; i < tmp.size(); i++)
251  _rtree[v->getDim()]->Remove(bmin, bmax, tmp[i]);
252  }
253  double getMeshSize(int dim, TopoDS_Shape shape)
254  {
255  std::vector<OCCAttributes *> attr;
256  _find(dim, shape, attr, true, false, false, false, false);
257  for(std::size_t i = 0; i < attr.size(); i++) {
258  if(attr[i]->getMeshSize() < MAX_LC) return attr[i]->getMeshSize();
259  }
260  return MAX_LC;
261  }
262  ExtrudeParams *getExtrudeParams(int dim, TopoDS_Shape shape, int &sourceDim,
263  TopoDS_Shape &sourceShape)
264  {
265  std::vector<OCCAttributes *> attr;
266  _find(dim, shape, attr, false, true, false, false, false);
267  for(std::size_t i = 0; i < attr.size(); i++) {
268  if(attr[i]->getExtrudeParams()) {
269  sourceDim = attr[i]->getSourceDim();
270  sourceShape = attr[i]->getSourceShape();
271  return attr[i]->getExtrudeParams();
272  }
273  }
274  return 0;
275  }
276  void getLabels(int dim, TopoDS_Shape shape, std::vector<std::string> &labels)
277  {
278  labels.clear();
279  std::vector<OCCAttributes *> attr;
280  _find(dim, shape, attr, false, false, true, false, false);
281  for(std::size_t i = 0; i < attr.size(); i++) {
282  if(!attr[i]->getLabel().empty()) labels.push_back(attr[i]->getLabel());
283  }
284  }
285  bool getColor(int dim, TopoDS_Shape shape, unsigned int &color,
286  unsigned int &boundary)
287  {
288  std::vector<OCCAttributes *> attr;
289  _find(dim, shape, attr, false, false, false, true, false);
290  for(std::size_t i = 0; i < attr.size(); i++) {
291  const std::vector<double> &col = attr[i]->getColor();
292  if(col.size() >= 3) {
293  int r = static_cast<int>(col[0] * 255. + 0.5);
294  r = (r < 0) ? 0 : (r > 255) ? 255 : r;
295  int g = static_cast<int>(col[1] * 255. + 0.5);
296  g = (g < 0) ? 0 : (g > 255) ? 255 : g;
297  int b = static_cast<int>(col[2] * 255. + 0.5);
298  b = (b < 0) ? 0 : (b > 255) ? 255 : b;
299  int a = 255;
300  if(col.size() >= 4) {
301  int a = static_cast<int>(col[3] * 255. + 0.5);
302  a = (a < 0) ? 0 : (a > 255) ? 255 : a;
303  }
304  color = CTX::instance()->packColor(r, g, b, a);
305  boundary = (col.size() == 5) ? col[4] : 0;
306  return true;
307  }
308  }
309  return false;
310  }
311  void getSimilarShapes(int dim, TopoDS_Shape shape,
312  std::vector<TopoDS_Shape> &other)
313  {
314  std::vector<OCCAttributes *> attr;
315  _find(dim, shape, attr, false, false, false, false, true);
316  for(std::size_t i = 0; i < attr.size(); i++) {
317  TopoDS_Shape s = attr[i]->getShape();
318  if(!s.IsNull()) other.push_back(s);
319  }
320  }
321 };
322 
323 #endif
324 #endif
CTX::packColor
unsigned int packColor(int R, int G, int B, int A)
Definition: Context.cpp:128
OS.h
Msg::Debug
static void Debug(const char *fmt,...)
Definition: GmshMessage.cpp:752
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
box
Definition: gl2gif.cpp:311
GmshMessage.h
MAX_LC
#define MAX_LC
Definition: GEntity.h:19
rtree.h
Fopen
FILE * Fopen(const char *f, const char *mode)
Definition: OS.cpp:273
CTX::instance
static CTX * instance()
Definition: Context.cpp:122
RTree
Definition: rtree.h:100
tolerance
#define tolerance
Definition: curvature.cpp:11
RTree::Insert
void Insert(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS], const DATATYPE &a_dataId)
Context.h
RTree::Search
int Search(const ELEMTYPE a_min[NUMDIMS], const ELEMTYPE a_max[NUMDIMS], bool a_resultCallback(DATATYPE a_data, void *a_context), void *a_context)
z
const double z
Definition: GaussQuadratureQuad.cpp:56
rtree_callback
bool rtree_callback(MElement *e1, void *pe2)
Definition: filterElements.cpp:152
ExtrudeParams
Definition: ExtrudeParams.h:26