gmsh-TingyuanDoc  0.1
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
OCCRegion.cpp
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 #include "GmshConfig.h"
7 #include "GmshMessage.h"
8 #include "GModel.h"
9 #include "GModelIO_OCC.h"
10 #include "OCCEdge.h"
11 #include "OCCFace.h"
12 #include "OCCRegion.h"
13 #include "Context.h"
14 
15 #if defined(HAVE_OCC)
16 
17 #include <BRepBndLib.hxx>
18 #include <BRepClass3d_SolidClassifier.hxx>
19 #include <BRepTools.hxx>
20 #include <BRep_Builder.hxx>
21 #include <Bnd_Box.hxx>
22 #include <TopExp_Explorer.hxx>
23 #include <TopoDS.hxx>
24 #include <TopoDS_Compound.hxx>
25 
26 OCCRegion::OCCRegion(GModel *m, TopoDS_Solid s, int num)
27  : GRegion(m, num), _s(s)
28 {
29  _setup();
30 
31  // if(tag() == 1) writeBREP("v1.brep");
32 }
33 
34 void OCCRegion::_setup()
35 {
36  l_faces.clear();
37  TopExp_Explorer exp2, exp3;
38  for(exp2.Init(_s, TopAbs_SHELL); exp2.More(); exp2.Next()) {
39  const TopoDS_Shape &shell = exp2.Current();
40  Msg::Debug("OCC volume %d - new shell", tag());
41  for(exp3.Init(shell, TopAbs_FACE); exp3.More(); exp3.Next()) {
42  TopoDS_Face face = TopoDS::Face(exp3.Current());
43  GFace *f = nullptr;
44  if(model()->getOCCInternals())
45  f = model()->getOCCInternals()->getFaceForOCCShape(model(), face);
46  if(!f) { Msg::Error("Unknown surface in volume %d", tag()); }
47  else if(face.Orientation() == TopAbs_INTERNAL &&
49  Msg::Debug("Adding embedded surface %d in volume %d", f->tag(), tag());
50  embedded_faces.push_back(f);
51  }
52  else {
53  l_faces.push_back(f);
54  // face.orientation() contains the orientation of the TopoDS_Face
55  // w.r.t. the underlying Geom_Surface, and the value is multiplied by
56  // the orientation of the shell
57  if(face.Orientation() == TopAbs_REVERSED)
58  l_dirs.push_back(-1);
59  else
60  l_dirs.push_back(1);
61  f->addRegion(this);
62  }
63  }
64  }
65 
66  for(exp3.Init(_s, TopAbs_EDGE, TopAbs_FACE); exp3.More(); exp3.Next()) {
67  TopoDS_Edge edge = TopoDS::Edge(exp3.Current());
68  GEdge *e = nullptr;
69  if(model()->getOCCInternals())
70  e = model()->getOCCInternals()->getEdgeForOCCShape(model(), edge);
71  if(!e) { Msg::Error("Unknown curve in volume %d", tag()); }
72  else if(edge.Orientation() == TopAbs_INTERNAL &&
74  Msg::Debug("Adding embedded curve %d in volume %d", e->tag(), tag());
75  embedded_edges.push_back(e);
76  // OCCEdge *occe = (OCCEdge*)e;
77  // occe->setTrimmed(this);
78  }
79  }
80 
81  for(exp3.Init(_s, TopAbs_VERTEX, TopAbs_FACE); exp3.More(); exp3.Next()) {
82  TopoDS_Vertex vertex = TopoDS::Vertex(exp3.Current());
83  GVertex *v = nullptr;
84  if(model()->getOCCInternals())
85  v = model()->getOCCInternals()->getVertexForOCCShape(model(), vertex);
86  if(!v) { Msg::Error("Unknown point in volume %d", tag()); }
87  else if(vertex.Orientation() == TopAbs_INTERNAL &&
89  Msg::Debug("Adding embedded point %d in volume %d", v->tag(), tag());
90  embedded_vertices.push_back(v);
91  }
92  }
93 
94  Msg::Debug("OCC volume %d with %d surfaces", tag(), l_faces.size());
95 }
96 
97 SBoundingBox3d OCCRegion::bounds(bool fast)
98 {
99  if(CTX::instance()->geom.occBoundsUseSTL) {
100  std::vector<GFace *> f = faces();
101  SBoundingBox3d bbox;
102  for(std::size_t i = 0; i < f.size(); i++) {
103  f[i]->buildSTLTriangulation();
104  bbox += f[i]->bounds();
105  }
106  return bbox;
107  }
108 
109  Bnd_Box b;
110  try {
111  BRepBndLib::Add(_s, b);
112  } catch(Standard_Failure &err) {
113  Msg::Error("OpenCASCADE exception %s", err.GetMessageString());
114  return SBoundingBox3d();
115  }
116  double xmin, ymin, zmin, xmax, ymax, zmax;
117  b.Get(xmin, ymin, zmin, xmax, ymax, zmax);
118  SBoundingBox3d bbox(xmin, ymin, zmin, xmax, ymax, zmax);
119  return bbox;
120 }
121 
122 GEntity::GeomType OCCRegion::geomType() const { return Volume; }
123 
124 bool OCCRegion::containsPoint(const SPoint3 &pt) const
125 {
126  BRepClass3d_SolidClassifier solidClassifier(_s);
127  solidClassifier.Perform(gp_Pnt{pt.x(), pt.y(), pt.z()},
129  const TopAbs_State state = solidClassifier.State();
130  return (state == TopAbs_IN || state == TopAbs_ON);
131 }
132 
133 void OCCRegion::writeBREP(const char *filename)
134 {
135  BRep_Builder b;
136  TopoDS_Compound c;
137  b.MakeCompound(c);
138  b.Add(c, _s);
139  BRepTools::Write(c, filename);
140 }
141 
142 #endif
Volume
Definition: Geo.h:140
contextGeometryOptions::tolerance
double tolerance
Definition: Context.h:99
GFace
Definition: GFace.h:33
Msg::Debug
static void Debug(const char *fmt,...)
Definition: GmshMessage.cpp:752
c
static double c(int i, int j, fullMatrix< double > &CA, const std::vector< SPoint3 > &P, const std::vector< SPoint3 > &Q)
Definition: discreteFrechetDistance.cpp:15
Msg::Error
static void Error(const char *fmt,...)
Definition: GmshMessage.cpp:482
OCCFace.h
SPoint3
Definition: SPoint3.h:14
LegendrePolynomials::f
void f(int n, double u, double *val)
Definition: orthogonalBasis.cpp:77
GModelIO_OCC.h
GmshMessage.h
CTX::instance
static CTX * instance()
Definition: Context.cpp:122
SPoint3::x
double x(void) const
Definition: SPoint3.h:125
OCCEdge.h
GVertex
Definition: GVertex.h:23
GModel
Definition: GModel.h:44
SPoint3::y
double y(void) const
Definition: SPoint3.h:127
GEntity::tag
int tag() const
Definition: GEntity.h:280
CTX::geom
contextGeometryOptions geom
Definition: Context.h:311
GRegion
Definition: GRegion.h:28
GEntity::GeomType
GeomType
Definition: GEntity.h:88
Context.h
GEdge
Definition: GEdge.h:26
SPoint3::z
double z(void) const
Definition: SPoint3.h:129
contextGeometryOptions::occAutoEmbed
int occAutoEmbed
Definition: Context.h:100
GModel.h
OCCRegion.h
SBoundingBox3d
Definition: SBoundingBox3d.h:21
faces
static int faces[4][3]
Definition: meshGRegionDelaunayInsertion.cpp:165