OCGeometryGenerator.cpp 5.97 KB
Newer Older
1
#include "MantidGeometry/Rendering/OCGeometryGenerator.h"
2
#include "MantidGeometry/Objects/CSGObject.h"
Nick Draper's avatar
re #843    
Nick Draper committed
3
4
5
6
7
8
#include "MantidGeometry/Surfaces/Quadratic.h"
#include "MantidGeometry/Surfaces/Sphere.h"
#include "MantidGeometry/Surfaces/Cylinder.h"
#include "MantidGeometry/Surfaces/Cone.h"
#include "MantidGeometry/Surfaces/Plane.h"
#include "MantidGeometry/Surfaces/Torus.h"
9
#include "MantidGeometry/Objects/Rules.h"
10
11
#include "MantidKernel/Logger.h"
#include "MantidKernel/Matrix.h"
12
#include "MantidKernel/Quat.h"
13
14
#include "MantidKernel/V3D.h"
#include "MantidKernel/WarningSuppressions.h"
15

16
17
18
#include <climits> // Needed for g++4.4 on Mac with OpenCASCADE 6.3.0
#include <cmath>
#include <vector>
19

Russell Taylor's avatar
Russell Taylor committed
20
21
// Squash a warning coming out of an OpenCascade header
#ifdef __INTEL_COMPILER
22
#pragma warning disable 191
Russell Taylor's avatar
Russell Taylor committed
23
#endif
24
25
26
27
// Opencascade defines _USE_MATH_DEFINES without checking whether it is already
// used.
// Undefine it here before we include the headers to avoid a warning. Older
// versions
28
29
// also define M_SQRT1_2 so do the same if it is already defined
#ifdef _MSC_VER
30
31
32
33
#undef _USE_MATH_DEFINES
#ifdef M_SQRT1_2
#undef M_SQRT1_2
#endif
34
#endif
35

36
GCC_DIAG_OFF(conversion)
37
// clang-format off
38
GCC_DIAG_OFF(cast-qual)
39
// clang-format on
Peterson, Peter's avatar
Peterson, Peter committed
40
#include <gp_Trsf.hxx>
Sri Nagella's avatar
Sri Nagella committed
41
42
43
44
45
46
47
48
#include <gp_Vec.hxx>
#include <gp_Dir.hxx>
#include <gp_Pnt.hxx>
#include <gp_Pln.hxx>
#include <StdFail_NotDone.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Solid.hxx>
Sri Nagella's avatar
Sri Nagella committed
49
50
#include <TopoDS_Face.hxx>
#include <TopExp_Explorer.hxx>
51
#include <BRepMesh_IncrementalMesh.hxx>
Sri Nagella's avatar
Sri Nagella committed
52
53
54
#include <BRepAlgoAPI_Fuse.hxx>
#include <BRepAlgoAPI_Common.hxx>
#include <BRepAlgoAPI_Cut.hxx>
Peterson, Peter's avatar
Peterson, Peter committed
55
#include <BRepPrimAPI_MakeBox.hxx>
Sri Nagella's avatar
Sri Nagella committed
56
#include <BRepBuilderAPI_Transform.hxx>
Sri Nagella's avatar
Sri Nagella committed
57
58
#include <BRep_Tool.hxx>
#include <Poly_Triangulation.hxx>
59
GCC_DIAG_ON(conversion)
60
// clang-format off
61
GCC_DIAG_ON(cast-qual)
62
// clang-format on
63

Russell Taylor's avatar
Russell Taylor committed
64
#ifdef __INTEL_COMPILER
65
#pragma warning enable 191
Russell Taylor's avatar
Russell Taylor committed
66
67
#endif

68
namespace Mantid {
Sri Nagella's avatar
Sri Nagella committed
69

70
71
72
73
74
namespace Geometry {
namespace {
/// static logger
Kernel::Logger g_log("OCGeometryGenerator");
}
75

76
77
78
79
/**
* Constructor
* @param obj :: input object
*/
80
OCGeometryGenerator::OCGeometryGenerator(const CSGObject *obj) : Obj(obj) {
81
  ObjSurface = nullptr;
82
}
Sri Nagella's avatar
Sri Nagella committed
83

84
85
86
87
/**
* Generate geometry, it uses OpenCascade to generate surface triangles.
*/
void OCGeometryGenerator::Generate() {
88
  if (ObjSurface == nullptr) {
89
90
91
    AnalyzeObject();
  }
}
Sri Nagella's avatar
Sri Nagella committed
92

93
94
95
96
/**
* Destroy the surface generated for the object
*/
OCGeometryGenerator::~OCGeometryGenerator() {
97
  if (ObjSurface != nullptr) {
98
99
100
    delete ObjSurface;
  }
}
Sri Nagella's avatar
Sri Nagella committed
101

102
103
104
105
/**
* Analyzes the rule tree in object and creates a Topology Shape
*/
void OCGeometryGenerator::AnalyzeObject() {
106
  if (Obj != nullptr) // If object exists
107
108
109
  {
    // Get the top rule tree in Obj
    const Rule *top = Obj->topRule();
110
    if (top == nullptr) {
111
112
      ObjSurface = new TopoDS_Shape();
      return;
113
    }
114
    // Traverse through Rule
115
    TopoDS_Shape Result = const_cast<Rule *>(top)->analyze();
116
117
    try {
      ObjSurface = new TopoDS_Shape(Result);
118
      BRepMesh_IncrementalMesh(Result, 0.001);
119
120
    } catch (StdFail_NotDone &) {
      g_log.error("Cannot build the geometry. Check the geometry definition");
121
    }
122
123
  }
}
124

125
/**
126
* Returns the shape generated.
127
*/
128
TopoDS_Shape *OCGeometryGenerator::getObjectSurface() { return ObjSurface; }
Sri Nagella's avatar
Sri Nagella committed
129

130
131
int OCGeometryGenerator::getNumberOfTriangles() {
  int countFace = 0;
132
  if (ObjSurface != nullptr) {
133
134
135
136
137
138
    TopExp_Explorer Ex;
    for (Ex.Init(*ObjSurface, TopAbs_FACE); Ex.More(); Ex.Next()) {
      TopoDS_Face F = TopoDS::Face(Ex.Current());
      TopLoc_Location L;
      Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
      countFace += facing->NbTriangles();
139
    }
140
141
142
  }
  return countFace;
}
Sri Nagella's avatar
Sri Nagella committed
143

144
145
int OCGeometryGenerator::getNumberOfPoints() {
  int countVert = 0;
146
  if (ObjSurface != nullptr) {
147
148
149
150
151
152
    TopExp_Explorer Ex;
    for (Ex.Init(*ObjSurface, TopAbs_FACE); Ex.More(); Ex.Next()) {
      TopoDS_Face F = TopoDS::Face(Ex.Current());
      TopLoc_Location L;
      Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
      countVert += facing->NbNodes();
153
    }
154
155
156
  }
  return countVert;
}
Sri Nagella's avatar
Sri Nagella committed
157

158
double *OCGeometryGenerator::getTriangleVertices() {
159
  double *points = nullptr;
160
161
  int nPts = this->getNumberOfPoints();
  if (nPts > 0) {
162
    points = new double[static_cast<std::size_t>(nPts) * 3];
163
164
165
166
167
168
169
170
171
172
173
174
175
176
    int index = 0;
    TopExp_Explorer Ex;
    for (Ex.Init(*ObjSurface, TopAbs_FACE); Ex.More(); Ex.Next()) {
      TopoDS_Face F = TopoDS::Face(Ex.Current());
      TopLoc_Location L;
      Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
      TColgp_Array1OfPnt tab(1, (facing->NbNodes()));
      tab = facing->Nodes();
      for (Standard_Integer i = 1; i <= (facing->NbNodes()); i++) {
        gp_Pnt pnt = tab.Value(i);
        points[index * 3 + 0] = pnt.X();
        points[index * 3 + 1] = pnt.Y();
        points[index * 3 + 2] = pnt.Z();
        index++;
177
178
      }
    }
179
180
181
  }
  return points;
}
Sri Nagella's avatar
Sri Nagella committed
182

183
int *OCGeometryGenerator::getTriangleFaces() {
184
  int *faces = nullptr;
185
186
  int nFaces = this->getNumberOfTriangles(); // was Points
  if (nFaces > 0) {
187
    faces = new int[static_cast<std::size_t>(nFaces) * 3];
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
    TopExp_Explorer Ex;
    int maxindex = 0;
    int index = 0;
    for (Ex.Init(*ObjSurface, TopAbs_FACE); Ex.More(); Ex.Next()) {
      TopoDS_Face F = TopoDS::Face(Ex.Current());
      TopLoc_Location L;
      Handle(Poly_Triangulation) facing = BRep_Tool::Triangulation(F, L);
      TColgp_Array1OfPnt tab(1, (facing->NbNodes()));
      tab = facing->Nodes();
      Poly_Array1OfTriangle tri(1, facing->NbTriangles());
      tri = facing->Triangles();
      for (Standard_Integer i = 1; i <= (facing->NbTriangles()); i++) {
        Poly_Triangle trian = tri.Value(i);
        Standard_Integer index1, index2, index3;
        trian.Get(index1, index2, index3);
        faces[index * 3 + 0] = maxindex + index1 - 1;
        faces[index * 3 + 1] = maxindex + index2 - 1;
        faces[index * 3 + 2] = maxindex + index3 - 1;
        index++;
207
      }
208
      maxindex += facing->NbNodes();
209
    }
210
211
212
213
  }
  return faces;
}
} // NAMESPACE Geometry
Sri Nagella's avatar
Sri Nagella committed
214

215
} // NAMESPACE Mantid