EGSnrc C++ class library  Report PIRS-898 (2021)
Iwan Kawrakow, Ernesto Mainegra-Hing, Frederic Tessier, Reid Townson and Blake Walters
egs_triangle_mesh.h
Go to the documentation of this file.
1 /*
2 ###############################################################################
3 #
4 # EGSnrc egs++ triangle mesh geometry library headers.
5 # Copyright (C) 2022 Max Orok
6 #
7 # This file is part of EGSnrc.
8 #
9 # EGSnrc is free software: you can redistribute it and/or modify it under
10 # the terms of the GNU Affero General Public License as published by the
11 # Free Software Foundation, either version 3 of the License, or (at your
12 # option) any later version.
13 #
14 # EGSnrc is distributed in the hope that it will be useful, but WITHOUT ANY
15 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16 # FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
17 # more details.
18 #
19 # You should have received a copy of the GNU Affero General Public License
20 # along with EGSnrc. If not, see <http://www.gnu.org/licenses/>.
21 #
22 ###############################################################################
23 #
24 # Author: Max Orok, 2022
25 #
26 # Contributors: Alexandre Demelo
27 #
28 ###############################################################################
29 */
30 
31 
36 #ifndef EGS_TRIANGLE_MESH
37 #define EGS_TRIANGLE_MESH
38 
39 #include "egs_base_geometry.h"
40 #include "egs_vector.h"
41 
42 #include <array>
43 #include <memory>
44 #include <string>
45 #include <vector>
46 #include <fstream>
47 
48 #ifdef WIN32
49 
50  #ifdef BUILD_EGS_TRIANGLE_MESH_DLL
51  #define EGS_TRIANGLE_MESH_EXPORT __declspec(dllexport)
52  #else
53  #define EGS_TRIANGLE_MESH_EXPORT __declspec(dllimport)
54  #endif
55  #define EGS_TRIANGLE_MESH_LOCAL
56 
57 #else
58 
59  #ifdef HAVE_VISIBILITY
60  #define EGS_TRIANGLE_MESH_EXPORT __attribute__ ((visibility ("default")))
61  #define EGS_TRIANGLE_MESH_LOCAL __attribute__ ((visibility ("hidden")))
62  #else
63  #define EGS_TRIANGLE_MESH_EXPORT
64  #define EGS_TRIANGLE_MESH_LOCAL
65  #endif
66 
67 #endif
68 
70 class EGS_TRIANGLE_MESH_EXPORT EGS_TriangleMeshSpec {
71 public:
72 
73  // A triangle with a unit normal facing outward from the surface.
74  struct Triangle {
75  Triangle() = default;
77  a(a), b(b), c(c), n(n) {}
78  // nodes
79  EGS_Vector a;
80  EGS_Vector b;
81  EGS_Vector c;
82  // normal
83  EGS_Vector n;
84  };
85 
86  EGS_TriangleMeshSpec() = default;
87  EGS_TriangleMeshSpec(std::vector<Triangle> elements) :
88  elements(std::move(elements)) {}
89 
90  // EGS_TriangleMeshSpec is move-only
92  EGS_TriangleMeshSpec &operator=(const EGS_TriangleMeshSpec &) = delete;
94  EGS_TriangleMeshSpec &operator=(EGS_TriangleMeshSpec &&) = default;
95  ~EGS_TriangleMeshSpec() = default;
96 
98  void scale(EGS_Float factor) {
99  for (auto &e: elements) {
100  e.a *= factor;
101  e.b *= factor;
102  e.c *= factor;
103  }
104  }
105 
106  std::size_t num_elements() const {
107  return elements.size();
108  }
109 
110  // Public members
111 
113  std::vector<EGS_TriangleMeshSpec::Triangle> elements;
114 };
115 
116 // exclude from doxygen
118 class EGS_TriangleMeshBbox;
119 class EGS_TriangleMeshNode;
120 class EGS_TriangleMesh_Octree;
122 
192 class EGS_TRIANGLE_MESH_EXPORT EGS_TriangleMesh : public EGS_BaseGeometry {
193 public:
194  explicit EGS_TriangleMesh(EGS_TriangleMeshSpec spec, bool oct_set, bool use_stored_normals);
195 
196  // EGS_TriangleMesh is move-only
197  EGS_TriangleMesh(const EGS_TriangleMesh &) = delete;
198  EGS_TriangleMesh &operator=(const EGS_TriangleMesh &) = delete;
200  EGS_TriangleMesh &operator=(EGS_TriangleMesh &&);
201  ~EGS_TriangleMesh();
202 
205  int num_triangles() const {
206  return n_tris;
207  }
208 
210  const std::array<EGS_Float, 3> &triangle_xs(int tri) const {
211  return xs.at(tri);
212  }
213 
215  const std::array<EGS_Float, 3> &triangle_ys(int tri) const {
216  return ys.at(tri);
217  }
218 
220  const std::array<EGS_Float, 3> &triangle_zs(int tri) const {
221  return zs.at(tri);
222  }
223 
225  const EGS_Vector &triangle_normal(int tri) const {
226  return ns.at(tri);
227  }
228 
229  // EGS_BaseGeometry interface
230 
231  const std::string &getType() const override {
232  return EGS_TriangleMesh::type;
233  }
234 
235  void setOctBool(bool octset) {
236  octree_acc_on=octset;
237  }
238  bool getOctBool() {
239  return octree_acc_on;
240  }
241  void inctricheck_OHF() {
242  tri_check_OHF++;
243  }
244  void inctricheck_OHN() {
245  tri_check_OHN++;
246  }
247  void inctricheck_OIW() {
248  tri_check_OIW++;
249  }
250  void inctricheck_NHF() {
251  tri_check_NHF++;
252  }
253  void inctricheck_NHN() {
254  tri_check_NHN++;
255  }
256  void inctricheck_NIW() {
257  tri_check_NIW++;
258  }
259 
260  bool isInside(const EGS_Vector &x) override;
261  int inside(const EGS_Vector &x) override;
262  int isWhere(const EGS_Vector &x) override;
263  int howfar(int ireg, const EGS_Vector &x, const EGS_Vector &u,
264  EGS_Float &t, int *newmed=0, EGS_Vector *normal=0) override;
265  EGS_Float hownear(int ireg, const EGS_Vector &x) override;
266  void initializeOctree();
267 
268  static const std::string type;
269 
270 private:
271  int n_tris = -1;
272  int n_hist=0;
273 
274  // Vectors with len = n_tris
275  std::vector<std::array<EGS_Float, 3>> xs;
276  std::vector<std::array<EGS_Float, 3>> ys;
277  std::vector<std::array<EGS_Float, 3>> zs;
278  std::vector<EGS_Vector> ns;
279 
280  // Axis-aligned mesh bounding box used to accelerate geometry routines
281  std::unique_ptr<EGS_TriangleMeshBbox> bbox;
282  std::unique_ptr<EGS_TriangleMesh_Octree> surface_tree_;
283  bool octree_acc_on;
284  int tri_check_OHF=0,tri_check_OHN=0,tri_check_OIW=0,tri_check_NHF=0,tri_check_NHN=0,tri_check_NIW=0;
285 };
286 
287 #endif // EGS_TRIANGLE_MESH
Base geometry class. Every geometry class must be derived from EGS_BaseGeometry.
A container for raw unstructured triangle surface mesh data.
void scale(EGS_Float factor)
Multiply all node coordinates by a constant factor.
std::vector< EGS_TriangleMeshSpec::Triangle > elements
Unique elements.
A triangular surface mesh geometry.
int num_triangles() const
const std::array< EGS_Float, 3 > & triangle_xs(int tri) const
Returns the three triangle node x-coordinates.
const EGS_Vector & triangle_normal(int tri) const
Returns the outward-facing triangle unit normal.
const std::array< EGS_Float, 3 > & triangle_zs(int tri) const
Returns the three triangle node z-coordinates.
const std::array< EGS_Float, 3 > & triangle_ys(int tri) const
Returns the three triangle node y-coordinates.
A class representing 3D vectors.
Definition: egs_vector.h:57
EGS_BaseGeometry class header file.
EGS_Vector methods for the manipulation of 3D vectors in cartesian co-ordinates.