Titan  v1.0
A high-performance CUDA-based physics simulation sandbox for robotics, physics, and reinforcement learning.
stlparser.h
Go to the documentation of this file.
1 //
2 // Created by Jacob Austin on 5/26/18.
3 //
4 
5 #ifndef STL_PARSER_H
6 #define STL_PARSER_H
7 
8 #include <string>
9 #include <vector>
10 #include <iostream>
11 #include <fstream>
12 #include <cassert>
13 #include <cmath>
14 
15 namespace titan {
16 
17 namespace stl {
18  class Vec3D {
19  public:
20  Vec3D(); // default
21  Vec3D(const Vec3D & v); // copy constructor
22  Vec3D(double x, double y, double z); // initialization from x, y, and z values
23  Vec3D & operator = (const Vec3D & v);
24  Vec3D & operator += (const Vec3D & v);
25  Vec3D operator - () const;
26  double & operator [] (int n);
27  const double & operator [] (int n) const;
28 
29  friend Vec3D operator + (const Vec3D & x, const Vec3D & y);
30  friend Vec3D operator - (const Vec3D & x, const Vec3D & y);
31 
32  friend Vec3D operator * (const Vec3D & v, const double x); // double and Vec
33  friend Vec3D operator * (const double x, const Vec3D & v);
34  friend Vec3D operator * (const Vec3D & v1, const Vec3D & v2); // two Vecs (elementwise)
35 
36  friend Vec3D operator / (const Vec3D & v, const double x); // double and vec
37  friend Vec3D operator / (const Vec3D & v1, const Vec3D & v2); // two Vecs (elementwise)
38 
39  friend std::ostream & operator << (std::ostream &, const Vec3D &); // print
40 
41  double norm() const; // gives vector norm
42  double sum() const; // gives vector norm
43 
44  private:
45  double data[3] = { 0 }; // initialize data to 0
46  };
47 
48  double dot(const Vec3D & a, const Vec3D & b);
49  Vec3D cross(const Vec3D & v1, const Vec3D & v2);
50 
52  data[0] = 0;
53  data[1] = 0;
54  data[2] = 0;
55  }
56 
57  Vec3D::Vec3D(double x, double y, double z) {
58  data[0] = x;
59  data[1] = y;
60  data[2] = z;
61  }
62 
63  Vec3D::Vec3D(const Vec3D & v) {
64  data[0] = v.data[0];
65  data[1] = v.data[1];
66  data[2] = v.data[2];
67  }
68 
69  Vec3D & Vec3D::operator=(const Vec3D & v) {
70  if (this == &v) {
71  return *this;
72  }
73 
74  data[0] = v.data[0];
75  data[1] = v.data[1];
76  data[2] = v.data[2];
77 
78  return *this;
79  }
80 
81  Vec3D & Vec3D::operator+=(const Vec3D & v) {
82  data[0] += v.data[0];
83  data[1] += v.data[1];
84  data[2] += v.data[2];
85  return *this;
86  }
87 
89  return Vec3D(-data[0], -data[1], -data[2]);
90  }
91 
92 
93  Vec3D operator+(const Vec3D & v1, const Vec3D & v2) {
94  return Vec3D(v1.data[0] + v2.data[0], v1.data[1] + v2.data[1], v1.data[2] + v2.data[2]);
95  }
96 
97  Vec3D operator-(const Vec3D & v1, const Vec3D & v2) {
98  return Vec3D(v1.data[0] - v2.data[0], v1.data[1] - v2.data[1], v1.data[2] - v2.data[2]);
99  }
100 
101  Vec3D operator*(const double x, const Vec3D & v) {
102  return Vec3D(v.data[0] * x, v.data[1] * x, v.data[2] * x);
103  }
104 
105  Vec3D operator*(const Vec3D & v, const double x) {
106  return x * v;
107  }
108 
109  Vec3D operator*(const Vec3D & v1, const Vec3D & v2) {
110  return Vec3D(v1.data[0] * v2.data[0], v1.data[1] * v2.data[1], v1.data[2] * v2.data[2]);
111  }
112 
113  Vec3D operator/(const Vec3D & v, const double x) {
114  return Vec3D(v.data[0] / x, v.data[1] / x, v.data[2] / x);
115  }
116 
117  Vec3D operator/(const Vec3D & v1, const Vec3D & v2) {
118  return Vec3D(v1.data[0] / v2.data[0], v1.data[1] / v2.data[1], v1.data[2] / v2.data[2]);
119  }
120 
121  std::ostream & operator << (std::ostream & strm, const Vec3D & v) {
122  return strm << "(" << v[0] << ", " << v[1] << ", " << v[2] << ")";
123  }
124 
125  double & Vec3D::operator [] (int n) {
126  if (n < 0 || n >= 3) {
127  std::cerr << std::endl << "Out of bounds" << std::endl;
128  exit(EXIT_FAILURE);
129  } else {
130  return data[n];
131  }
132  }
133 
134  const double & Vec3D::operator [] (int n) const {
135  if (n < 0 || n >= 3) {
136  std::cerr << std::endl << "Out of bounds" << std::endl;
137  exit(EXIT_FAILURE);
138  } else {
139  return data[n];
140  }
141  }
142 
143  double Vec3D::norm() const {
144  return sqrt(pow(data[0], 2) + pow(data[1], 2) + pow(data[2], 2));
145  }
146 
147  double Vec3D::sum() const {
148  return data[0] + data[1] + data[2];
149  }
150 
151  double dot(const Vec3D & a, const Vec3D & b) {
152  return (a * b).sum();
153  }
154 
155  Vec3D cross(const Vec3D & v1, const Vec3D & v2) {
156  return Vec3D(v1[1] * v2[2] - v1[2] * v2[1], v2[0] * v1[2] - v1[0] * v2[2], v1[0] * v2[1] - v1[1] * v2[0]);
157  }
158 
159  struct Triangle {
160  Triangle(const Vec3D &n, const Vec3D &vertex1, const Vec3D &vertex2, const Vec3D &vertex3) : normal(n), v1(vertex1),
161  v2(vertex2),
162  v3(vertex3) {};
163 
164  friend std::ostream & operator<<(std::ostream &, Triangle & t);
165 
170  };
171 
172  struct BBox {
173  BBox(const Vec3D & center, double x, double y, double z) {
174  this -> center = center;
175  this -> xdim = x;
176  this -> ydim = y;
177  this -> zdim = z;
178  }
179 
181  double xdim, ydim, zdim;
182  };
183 
184  struct stlFile {
185  std::string header;
187  std::vector<Triangle> triangles;
188 
190  bool inside(const Vec3D & point, int num_rays = 10);
191  };
192 
194  double min[3] = {DBL_MIN};
195  double max[3] = {DBL_MIN};
196 
197  for (Triangle t : triangles) {
198  for (int i = 0; i < 3; i++) {
199  min[i] = fmin(t.v1[i], min[i]);
200  max[i] = fmax(t.v1[i], max[i]);
201 
202  min[i] = fmin(t.v2[i], min[i]);
203  max[i] = fmax(t.v2[i], max[i]);
204 
205  min[i] = fmin(t.v3[i], min[i]);
206  max[i] = fmax(t.v3[i], max[i]);
207  }
208  }
209 
210  return BBox(Vec3D((max[0] - min[0]) / 2 + min[0], (max[1] - min[1]) / 2 + min[1], (max[2] - min[2]) / 2 + min[2]), max[0] - min[0], max[1] - min[1], max[2] - min[2]);
211  }
212 
213  bool intersect(const Vec3D & point, const Vec3D & ray, const Triangle & t, double EPSILON) {
214  Vec3D edge1 = t.v2 - t.v1;
215  Vec3D edge2 = t.v3 - t.v1;
216  Vec3D h = cross(ray, edge2);
217  double a = dot(edge1, h);
218 
219 // std::cout << "a is: " << a << std::endl;
220 
221  if (a > -EPSILON && a < EPSILON)
222  return false;
223 
224  double f = 1 / a;
225  Vec3D s = point - t.v1;
226  double u = f * dot(s, h);
227 
228  if (u < 0 || u > 1.0)
229  return false;
230 
231 // std::cout << "u is: " << u << std::endl;
232 
233  Vec3D q = cross(s, edge1);
234  double v = f * dot(ray, q);
235 
236  if (v < 0 || u + v > 1.0)
237  return false;
238 
239 // std::cout << "v is: " << v << std::endl;
240 
241  if (f * dot(edge2, q) > EPSILON)
242  return true;
243  else
244  return false;
245  }
246 
247  double randDouble(double min, double max) {
248  return min + (double) rand() / RAND_MAX * (max - min);
249  }
250 
251  bool stlFile::inside(const Vec3D & point, int num_rays) {
252  int count = 0;
253  int ray_count = 0;
254 
255  const double EPSILON = 0.000001;
256 
257  for (int i = 0; i < num_rays; i++) {
258  Vec3D ray = Vec3D(randDouble(-1000, 1000), randDouble(-1000, 1000), randDouble(-1000, 1000));
259  ray = ray / ray.norm();
260 
261  for (Triangle t : triangles) {
262  if (intersect(point, ray, t, EPSILON)) {
263  count++;
264  }
265  }
266 
267  if (count % 2 == 1) {
268  ray_count++;
269  }
270 
271  count = 0;
272  }
273 
274 // std::cout << "ray_count is: " << ray_count << std::endl;
275 
276  double fraction = (double) ray_count / (double) num_rays;
277 
278 // std::cout << "frac is: " << fraction << std::endl;
279 
280  if (fraction > 0.5) {
281  return true;
282  } else {
283  return false;
284  }
285  }
286 
287  Vec3D parseVec(std::ifstream & file) {
288  char triangle[12];
289  file.read(triangle, 12);
290  return Vec3D(*(float *) (triangle), *(float *) (triangle + 4), *(float *) (triangle + 8));
291  }
292 
293  std::ostream & operator<<(std::ostream &strm, Triangle & t) {
294  strm << "Normal : " << t.normal << std::endl;
295  strm << "Vertex 1 : " << t.v1 << std::endl;
296  strm << "Vertex 2 : " << t.v2 << std::endl;
297  strm << "Vertex 3 : " << t.v3 << std::endl;
298  return strm;
299  }
300 
301  stlFile parseSTL(std::string path) {
302  std::ifstream file(path.c_str(), std::ios::in | std::ios::binary);
303 
304  if (!file) {
305  std::cerr << "ERROR: COULD NOT READ FILE." << std::endl;
306  assert(0);
307  } else {
308  std::cout << "File found. Parsing STL file." << std::endl;
309  }
310 
311  char header[80];
312  char num_triangles[4];
313  file.read(header, 80);
314  file.read(num_triangles, 4);
315 
316  stlFile data;
317  data.header = std::string(header);
318  data.num_triangles = * (unsigned int *) num_triangles;
319 
320  for (int i = 0; i < data.num_triangles; i++) {
321  Vec3D normal = parseVec(file);
322  Vec3D v1 = parseVec(file);
323  Vec3D v2 = parseVec(file);
324  Vec3D v3 = parseVec(file);
325  data.triangles.push_back(Triangle(normal, v1, v2, v3));
326 
327  char properties[2];
328  file.read(properties, 2);
329  }
330 
331  std::cout << "Found " << data.num_triangles << " triangles. Parsing complete!" << std::endl;
332 
333  assert((file.peek(), file.eof()));
334 
335  return data;
336  }
337 }
338 
339 } // namespace titan
340 
341 #endif //STL_PARSER_H
titan::stl::randDouble
double randDouble(double min, double max)
Definition: stlparser.h:247
titan::stl::Vec3D::operator+
friend Vec3D operator+(const Vec3D &x, const Vec3D &y)
Definition: stlparser.h:93
titan::stl::BBox::BBox
BBox(const Vec3D &center, double x, double y, double z)
Definition: stlparser.h:173
titan
Definition: mass.h:11
titan::stl::Triangle::operator<<
friend std::ostream & operator<<(std::ostream &, Triangle &t)
Definition: stlparser.h:293
titan::stl::Vec3D::operator=
Vec3D & operator=(const Vec3D &v)
Definition: stlparser.h:69
titan::stl::Triangle
Definition: stlparser.h:159
titan::stl::Vec3D::operator/
friend Vec3D operator/(const Vec3D &v, const double x)
Definition: stlparser.h:113
titan::stl::stlFile::getBoundingBox
BBox getBoundingBox()
Definition: stlparser.h:193
titan::stl::Vec3D::operator[]
double & operator[](int n)
Definition: stlparser.h:125
titan::stl::Vec3D::operator+=
Vec3D & operator+=(const Vec3D &v)
Definition: stlparser.h:81
titan::stl::operator<<
std::ostream & operator<<(std::ostream &strm, const Vec3D &v)
Definition: stlparser.h:121
titan::stl::Triangle::v3
Vec3D v3
Definition: stlparser.h:169
titan::stl::Triangle::v2
Vec3D v2
Definition: stlparser.h:168
titan::stl::Triangle::normal
Vec3D normal
Definition: stlparser.h:166
titan::stl::Triangle::v1
Vec3D v1
Definition: stlparser.h:167
titan::stl::Triangle::Triangle
Triangle(const Vec3D &n, const Vec3D &vertex1, const Vec3D &vertex2, const Vec3D &vertex3)
Definition: stlparser.h:160
titan::stl::stlFile::header
std::string header
Definition: stlparser.h:185
titan::stl::operator*
Vec3D operator*(const double x, const Vec3D &v)
Definition: stlparser.h:101
titan::stl::stlFile
Definition: stlparser.h:184
titan::stl::stlFile::triangles
std::vector< Triangle > triangles
Definition: stlparser.h:187
titan::stl::Vec3D::operator-
Vec3D operator-() const
Definition: stlparser.h:88
titan::stl::BBox::xdim
double xdim
Definition: stlparser.h:181
titan::stl::Vec3D::norm
double norm() const
Definition: stlparser.h:143
titan::stl::cross
Vec3D cross(const Vec3D &v1, const Vec3D &v2)
Definition: stlparser.h:155
titan::stl::BBox
Definition: stlparser.h:172
titan::stl::Vec3D::operator*
friend Vec3D operator*(const Vec3D &v, const double x)
Definition: stlparser.h:105
titan::stl::dot
double dot(const Vec3D &a, const Vec3D &b)
Definition: stlparser.h:151
titan::stl::BBox::ydim
double ydim
Definition: stlparser.h:181
titan::stl::operator+
Vec3D operator+(const Vec3D &v1, const Vec3D &v2)
Definition: stlparser.h:93
titan::stl::parseVec
Vec3D parseVec(std::ifstream &file)
Definition: stlparser.h:287
titan::stl::Vec3D::sum
double sum() const
Definition: stlparser.h:147
titan::stl::Vec3D
Definition: stlparser.h:18
titan::stl::Vec3D::Vec3D
Vec3D()
Definition: stlparser.h:51
titan::stl::parseSTL
stlFile parseSTL(std::string path)
Definition: stlparser.h:301
titan::stl::operator-
Vec3D operator-(const Vec3D &v1, const Vec3D &v2)
Definition: stlparser.h:97
titan::stl::BBox::center
Vec3D center
Definition: stlparser.h:180
titan::stl::Vec3D::operator<<
friend std::ostream & operator<<(std::ostream &, const Vec3D &)
Definition: stlparser.h:121
titan::stl::stlFile::num_triangles
int num_triangles
Definition: stlparser.h:186
titan::stl::BBox::zdim
double zdim
Definition: stlparser.h:181
titan::stl::intersect
bool intersect(const Vec3D &point, const Vec3D &ray, const Triangle &t, double EPSILON)
Definition: stlparser.h:213
titan::stl::operator/
Vec3D operator/(const Vec3D &v, const double x)
Definition: stlparser.h:113
titan::stl::stlFile::inside
bool inside(const Vec3D &point, int num_rays=10)
Definition: stlparser.h:251