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#ifdef ENABLE_OPENCASCADE
119bool GeometryTriangulator::hasOCSurface() const { return m_objSurface != nullptr; }
121const TopoDS_Shape &GeometryTriangulator::getOCSurface() {
123 return *m_objSurface;
124}
125#endif
126
128 if (m_csgObj != nullptr || m_meshObj != nullptr) {
129 if (!m_isTriangulated) {
130 triangulate();
131 }
132 }
133}
138
143
146const std::vector<double> &GeometryTriangulator::getTriangleVertices() {
148 return m_points;
149}
152const std::vector<uint32_t> &GeometryTriangulator::getTriangleFaces() {
154 return m_faces;
155}
156
157#ifdef ENABLE_OPENCASCADE
158void GeometryTriangulator::OCAnalyzeObject() {
159 if (m_csgObj != nullptr) // If object exists
160 {
161 // Get the top rule tree in Obj
162 const auto *top = m_csgObj->topRule();
163 if (top == nullptr) {
164 m_objSurface.reset(new TopoDS_Shape());
165 return;
166 } else {
167 // Traverse through Rule
168 TopoDS_Shape Result = const_cast<Rule *>(top)->analyze();
169 try {
170 m_objSurface.reset(new TopoDS_Shape(Result));
171 BRepMesh_IncrementalMesh(Result, 0.001);
172 } catch (StdFail_NotDone &) {
173 g_log.error("Cannot build the geometry. Check the geometry definition");
174 }
175 }
176 }
177
178 setupPoints();
179 setupFaces();
180}
181
182size_t GeometryTriangulator::numPoints() const {
183 size_t countVert = 0;
184 if (m_objSurface != nullptr) {
185 TopExp_Explorer Ex;
186 for (Ex.Init(*m_objSurface, TopAbs_FACE); Ex.More(); Ex.Next()) {
187 TopoDS_Face F = TopoDS::Face(Ex.Current());
188 TopLoc_Location L;
189 Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
190 countVert += static_cast<size_t>(facing->NbNodes());
191 }
192 }
193 return countVert;
194}
195
196size_t GeometryTriangulator::numFaces() const {
197 size_t countFace = 0;
198 if (m_objSurface != nullptr) {
199 TopExp_Explorer Ex;
200 for (Ex.Init(*m_objSurface, TopAbs_FACE); Ex.More(); Ex.Next()) {
201 TopoDS_Face F = TopoDS::Face(Ex.Current());
202 TopLoc_Location L;
203 Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
204 countFace += static_cast<size_t>(facing->NbTriangles());
205 }
206 }
207 return countFace;
208}
209
210void GeometryTriangulator::setupPoints() {
211 m_nPoints = numPoints();
212 if (m_nPoints > 0) {
213 size_t index = 0;
214 m_points.resize(m_nPoints * 3);
215 TopExp_Explorer Ex;
216 for (Ex.Init(*m_objSurface, TopAbs_FACE); Ex.More(); Ex.Next()) {
217 TopoDS_Face F = TopoDS::Face(Ex.Current());
218 TopLoc_Location L;
219 Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
220 for (Standard_Integer i = 1; i <= (facing->NbNodes()); i++) {
221 const auto pnt = getNode(facing, i);
222 m_points[index * 3 + 0] = pnt.X();
223 m_points[index * 3 + 1] = pnt.Y();
224 m_points[index * 3 + 2] = pnt.Z();
225 index++;
226 }
227 }
228 }
229}
230
231void GeometryTriangulator::setupFaces() {
232 m_nFaces = numFaces();
233 if (m_nFaces > 0) {
234 m_faces.resize(m_nFaces * 3);
235 TopExp_Explorer Ex;
236 int maxindex = 0;
237 size_t index = 0;
238 for (Ex.Init(*m_objSurface, TopAbs_FACE); Ex.More(); Ex.Next()) {
239 TopoDS_Face F = TopoDS::Face(Ex.Current());
240 TopLoc_Location L;
241 Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
242 for (Standard_Integer i = 1; i <= (facing->NbTriangles()); i++) {
243 Poly_Triangle trian = getTriangle(facing, i);
244 Standard_Integer index1, index2, index3;
245 trian.Get(index1, index2, index3);
246 m_faces[index * 3 + 0] = static_cast<uint32_t>(maxindex + index1 - 1);
247 m_faces[index * 3 + 1] = static_cast<uint32_t>(maxindex + index2 - 1);
248 m_faces[index * 3 + 2] = static_cast<uint32_t>(maxindex + index3 - 1);
249 index++;
250 }
251 maxindex += facing->NbNodes();
252 }
253 }
254}
255#endif
256
257void GeometryTriangulator::setGeometryCache(size_t nPoints, size_t nFaces, std::vector<double> &&points,
258 std::vector<uint32_t> &&faces) {
259 m_nPoints = nPoints;
260 m_nFaces = nFaces;
261 m_points = std::move(points);
262 m_faces = std::move(faces);
263 m_isTriangulated = true;
264}
265} // namespace Mantid::Geometry::detail
std::map< DeltaEMode::Type, std::string > index
double top
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:108
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.