6 #ifndef OCC_ATTRIBUTES_H
7 #define OCC_ATTRIBUTES_H
11 #include "GmshConfig.h"
19 #include <Bnd_Box.hxx>
20 #include <BRepBndLib.hxx>
21 #include <TopoDS_Shape.hxx>
22 #include <BRepTools.hxx>
31 TopoDS_Shape _sourceShape;
33 std::vector<double> _color;
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)
41 OCCAttributes(
int dim, TopoDS_Shape shape,
double size)
42 : _dim(dim), _shape(shape), _meshSize(size), _extrude(0), _sourceDim(-1)
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)
51 OCCAttributes(
int dim, TopoDS_Shape shape,
const std::string &label)
52 : _dim(dim), _shape(shape), _meshSize(
MAX_LC), _extrude(0), _sourceDim(-1),
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)
60 _color.resize(boundary ? 5 : 4);
65 if(boundary) _color[4] = boundary;
68 int getDim() {
return _dim; }
69 TopoDS_Shape getShape() {
return _shape; }
70 double getMeshSize() {
return _meshSize; }
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; }
82 class OCCAttributesRTree {
85 std::vector<OCCAttributes *> _all;
89 std::vector<OCCAttributes *> *out =
90 static_cast<std::vector<OCCAttributes *> *
>(ctx);
94 void _find(
int dim,
const TopoDS_Shape &shape,
95 std::vector<OCCAttributes *> &attr,
bool requireMeshSize,
96 bool requireExtrudeParams,
bool requireLabel,
bool requireColor,
100 if(dim < 0 || dim > 3)
return;
103 BRepBndLib::Add(shape,
box, Standard_False);
106 "Searching for (null or degenerate) shape with void bounding box");
109 }
catch(Standard_Failure &err) {
110 Msg::Error(
"OpenCASCADE exception %s", err.GetMessageString());
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;
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());
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())) {
134 attr.push_back(tmp[i]);
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;
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]);
156 Msg::Debug(
"OCCRtree %d matches after bounding box filtering",
161 OCCAttributesRTree(
double tolerance = 1.e-8)
163 for(
int dim = 0; dim < 4; dim++)
167 ~OCCAttributesRTree()
170 for(
int dim = 0; dim < 4; dim++)
delete _rtree[dim];
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];
178 void print(
const std::string &fileName =
"")
181 if(fileName.size()) {
182 fp =
Fopen(fileName.c_str(),
"w");
184 Msg::Error(
"Could not open file '%s'", fileName.c_str());
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());
197 if(fileName.size()) fclose(fp);
199 void insert(OCCAttributes *v)
202 if(v->getDim() < 0 || v->getDim() > 3)
return;
205 BRepBndLib::Add(v->getShape(),
box, Standard_False);
208 "Inserting (null or degenerate) shape with void bounding box");
212 }
catch(Standard_Failure &err) {
213 Msg::Error(
"OpenCASCADE exception %s", err.GetMessageString());
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);
225 void remove(OCCAttributes *v)
227 if(v->getDim() < 0 || v->getDim() > 3)
return;
230 BRepBndLib::Add(v->getShape(),
box, Standard_False);
233 "Removing (null or degenerate) shape with void bounding box");
237 }
catch(Standard_Failure &err) {
238 Msg::Error(
"OpenCASCADE exception %s", err.GetMessageString());
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;
250 for(std::size_t i = 0; i < tmp.size(); i++)
251 _rtree[v->getDim()]->Remove(bmin, bmax, tmp[i]);
253 double getMeshSize(
int dim, TopoDS_Shape shape)
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();
262 ExtrudeParams *getExtrudeParams(
int dim, TopoDS_Shape shape,
int &sourceDim,
263 TopoDS_Shape &sourceShape)
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();
276 void getLabels(
int dim, TopoDS_Shape shape, std::vector<std::string> &labels)
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());
285 bool getColor(
int dim, TopoDS_Shape shape,
unsigned int &color,
286 unsigned int &boundary)
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;
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;
305 boundary = (col.size() == 5) ? col[4] : 0;
311 void getSimilarShapes(
int dim, TopoDS_Shape shape,
312 std::vector<TopoDS_Shape> &other)
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);