Mantid
Loading...
Searching...
No Matches
GeometryTriangulator.cpp
Go to the documentation of this file.
1// Mantid Repository : https://github.com/mantidproject/mantid
2//
3// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
4// NScD Oak Ridge National Laboratory, European Spallation Source,
5// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
6// SPDX - License - Identifier: GPL - 3.0 +
12#include "MantidKernel/Logger.h"
14#include <climits>
15
16#ifdef ENABLE_OPENCASCADE
17// Squash a warning coming out of an OpenCascade header
18#ifdef __INTEL_COMPILER
19#pragma warning disable 191
20#endif
21// Opencascade defines _USE_MATH_DEFINES without checking whether it is already
22// used.
23// Undefine it here before we include the headers to avoid a warning. Older
24// versions
25// also define M_SQRT1_2 so do the same if it is already defined
26#ifdef _MSC_VER
27#undef _USE_MATH_DEFINES
28#ifdef M_SQRT1_2
29#undef M_SQRT1_2
30#endif
31#endif
32
33GNU_DIAG_OFF("conversion")
34GNU_DIAG_OFF("cast-qual")
35
36#include <BRepBuilderAPI_Transform.hxx>
37#include <BRepMesh_IncrementalMesh.hxx>
38#include <BRep_Tool.hxx>
39#include <Poly_Triangulation.hxx>
40#include <Standard_Version.hxx>
41#include <StdFail_NotDone.hxx>
42#include <TopExp_Explorer.hxx>
43#include <TopoDS.hxx>
44#include <TopoDS_Face.hxx>
45#include <TopoDS_Shape.hxx>
46#include <gp_Pln.hxx>
47#include <gp_Pnt.hxx>
48#include <gp_Trsf.hxx>
49GNU_DIAG_ON("conversion")
50GNU_DIAG_ON("cast-qual")
51
52#ifdef __INTEL_COMPILER
53#pragma warning enable 191
54#endif
55
56namespace {
57auto getNode(const Handle(Poly_Triangulation) facing, Standard_Integer i) {
58#if OCC_VERSION_MAJOR >= 7 && OCC_VERSION_MINOR >= 6
59 return facing->Node(i);
60#else
61 // Compat shim to support OCCT 7.5 and below
62 TColgp_Array1OfPnt tab(1, (facing->NbNodes()));
63 tab = facing->Nodes();
64 return tab.Value(i);
65#endif
66}
67
68auto getTriangle(const Handle(Poly_Triangulation) facing, Standard_Integer i) {
69#if OCC_VERSION_MAJOR >= 7 && OCC_VERSION_MINOR >= 6
70 return facing->Triangle(i);
71#else
72 // Compat shim to support OCCT 7.5 and below
73 Poly_Array1OfTriangle tri(1, facing->NbTriangles());
74 tri = facing->Triangles();
75 return tri.Value(i);
76#endif
77}
78} // namespace
79#endif // ENABLE_OPENCASCADE
80
82namespace {
84Kernel::Logger g_log("GeometryTriangulator");
85} // namespace
86
88 : m_isTriangulated(false), m_nFaces(0), m_nPoints(0), m_csgObj(obj)
89#ifdef ENABLE_OPENCASCADE
90 ,
91 m_objSurface(nullptr)
92#endif
93{
94}
95
96GeometryTriangulator::GeometryTriangulator(std::unique_ptr<RenderingMesh> obj)
97 : m_isTriangulated(false), m_meshObj(std::move(obj)) {}
98
100
102#ifdef ENABLE_OPENCASCADE
103 if (m_objSurface == nullptr)
104 OCAnalyzeObject();
105#endif
106 if (m_meshObj) {
107 generateMesh();
108 m_nPoints = m_meshObj->numberOfVertices();
109 m_nFaces = m_meshObj->numberOfTriangles();
110 m_points = m_meshObj->getVertices();
111 m_faces = m_meshObj->getTriangles();
112 }
113 m_isTriangulated = true;
114}
115
116void GeometryTriangulator::generateMesh() { /* Placeholder function to replace MeshGeometryGenerator::Generate()*/
117}
118
119#ifdef ENABLE_OPENCASCADE
120bool GeometryTriangulator::hasOCSurface() const { return m_objSurface != nullptr; }
122const TopoDS_Shape &GeometryTriangulator::getOCSurface() {
124 return *m_objSurface;
125}
126#endif
127
129 if (m_csgObj != nullptr || m_meshObj != nullptr) {
130 if (!m_isTriangulated) {
131 triangulate();
132 }
133 }
134}
137 return m_nFaces;
138}
139
142 return m_nPoints;
143}
144
147const std::vector<double> &GeometryTriangulator::getTriangleVertices() {
149 return m_points;
150}
153const std::vector<uint32_t> &GeometryTriangulator::getTriangleFaces() {
155 return m_faces;
156}
157
158#ifdef ENABLE_OPENCASCADE
159void GeometryTriangulator::OCAnalyzeObject() {
160 if (m_csgObj != nullptr) // If object exists
161 {
162 // Get the top rule tree in Obj
163 const auto *top = m_csgObj->topRule();
164 if (top == nullptr) {
165 m_objSurface.reset(new TopoDS_Shape());
166 return;
167 } else {
168 // Traverse through Rule
169 TopoDS_Shape Result = const_cast<Rule *>(top)->analyze();
170 try {
171 m_objSurface.reset(new TopoDS_Shape(Result));
172 BRepMesh_IncrementalMesh(Result, 0.001);
173 } catch (StdFail_NotDone &) {
174 g_log.error("Cannot build the geometry. Check the geometry definition");
175 }
176 }
177 }
178
179 setupPoints();
180 setupFaces();
181}
182
183size_t GeometryTriangulator::numPoints() const {
184 size_t countVert = 0;
185 if (m_objSurface != nullptr) {
186 TopExp_Explorer Ex;
187 for (Ex.Init(*m_objSurface, TopAbs_FACE); Ex.More(); Ex.Next()) {
188 TopoDS_Face F = TopoDS::Face(Ex.Current());
189 TopLoc_Location L;
190 Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
191 countVert += static_cast<size_t>(facing->NbNodes());
192 }
193 }
194 return countVert;
195}
196
197size_t GeometryTriangulator::numFaces() const {
198 size_t countFace = 0;
199 if (m_objSurface != nullptr) {
200 TopExp_Explorer Ex;
201 for (Ex.Init(*m_objSurface, TopAbs_FACE); Ex.More(); Ex.Next()) {
202 TopoDS_Face F = TopoDS::Face(Ex.Current());
203 TopLoc_Location L;
204 Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
205 countFace += static_cast<size_t>(facing->NbTriangles());
206 }
207 }
208 return countFace;
209}
210
211void GeometryTriangulator::setupPoints() {
212 m_nPoints = numPoints();
213 if (m_nPoints > 0) {
214 size_t index = 0;
215 m_points.resize(m_nPoints * 3);
216 TopExp_Explorer Ex;
217 for (Ex.Init(*m_objSurface, TopAbs_FACE); Ex.More(); Ex.Next()) {
218 TopoDS_Face F = TopoDS::Face(Ex.Current());
219 TopLoc_Location L;
220 Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
221 for (Standard_Integer i = 1; i <= (facing->NbNodes()); i++) {
222 const auto pnt = getNode(facing, i);
223 m_points[index * 3 + 0] = pnt.X();
224 m_points[index * 3 + 1] = pnt.Y();
225 m_points[index * 3 + 2] = pnt.Z();
226 index++;
227 }
228 }
229 }
230}
231
232void GeometryTriangulator::setupFaces() {
233 m_nFaces = numFaces();
234 if (m_nFaces > 0) {
235 m_faces.resize(m_nFaces * 3);
236 TopExp_Explorer Ex;
237 int maxindex = 0;
238 size_t index = 0;
239 for (Ex.Init(*m_objSurface, TopAbs_FACE); Ex.More(); Ex.Next()) {
240 TopoDS_Face F = TopoDS::Face(Ex.Current());
241 TopLoc_Location L;
242 Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
243 for (Standard_Integer i = 1; i <= (facing->NbTriangles()); i++) {
244 Poly_Triangle trian = getTriangle(facing, i);
245 Standard_Integer index1, index2, index3;
246 trian.Get(index1, index2, index3);
247 m_faces[index * 3 + 0] = static_cast<uint32_t>(maxindex + index1 - 1);
248 m_faces[index * 3 + 1] = static_cast<uint32_t>(maxindex + index2 - 1);
249 m_faces[index * 3 + 2] = static_cast<uint32_t>(maxindex + index3 - 1);
250 index++;
251 }
252 maxindex += facing->NbNodes();
253 }
254 }
255}
256#endif
257
258void GeometryTriangulator::setGeometryCache(size_t nPoints, size_t nFaces, std::vector<double> &&points,
259 std::vector<uint32_t> &&faces) {
260 m_nPoints = nPoints;
261 m_nFaces = nFaces;
262 m_points = std::move(points);
263 m_faces = std::move(faces);
264 m_isTriangulated = true;
265}
266} // namespace Mantid::Geometry::detail
std::map< DeltaEMode::Type, std::string > index
Definition: DeltaEMode.cpp:19
double top
Definition: LineProfile.cpp:78
double obj
the value of the quadratic function
#define GNU_DIAG_ON(x)
#define GNU_DIAG_OFF(x)
This is a collection of macros for turning compiler warnings off in a controlled manner.
Constructive Solid Geometry object.
Definition: CSGObject.h:51
const Rule * topRule() const
Return the top rule.
Definition: CSGObject.h:76
Object generation rule tree.
Definition: Rules.h:33
size_t numTriangleVertices()
Return the number of triangle vertices.
void setGeometryCache(size_t nPoints, size_t nFaces, std::vector< double > &&points, std::vector< uint32_t > &&faces)
size_t numTriangleFaces()
Return the number of triangle faces.
std::vector< double > m_points
double array or points
const std::vector< double > & getTriangleVertices()
get a pointer to the 3x(NumberOfPoints) coordinates (x1,y1,z1,x2..) of mesh
std::vector< uint32_t > m_faces
Integer array of faces.
const std::vector< uint32_t > & getTriangleFaces()
get a pointer to the 3x(NumberOFaces) integers describing points forming faces (p1,...
void error(const std::string &msg)
Logs at error level.
Definition: Logger.cpp:77
boost::python::handle< T > Handle
Definition: Object.h:34
ShapeInfo : Stores shape types and information relevant to drawing the shape.
Definition: RandomPoint.h:20
Mantid::Kernel::Logger g_log("Goniometer")
STL namespace.