Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Rocon/include/BndSurface.h
Go to the documentation of this file.
1 #ifndef BNDSURFACE_INCLUDED
2 #define BNDSURFACE_INCLUDED
3 
4 #include <iostream>
5 #include <vector>
6 #include <algorithm>
7 #include <ext/hash_map>
8 #include <cstdlib>
9 #include <cmath>
10 #include <map>
11 #include <queue>
12 #include "triangle.h"
13 #include "NVec.h"
14 #include "KNN_Grid.h"
15 
16 //****************************************************************************************************
17 // A C++ class for a bounding surface described as a triangulated mesh
18 //---------------------------------
19 //
20 // An application should:
21 // a) create a new MeshBndSurf object
22 // b) call initialize()
23 // c) call intersect() as many times as needed
24 // d) delete the MeshBndSurf object
25 //
26 // External interface:
27 //
28 //------------------------------------------------------------------------------------------------------
29 // void initialize(double * nodes, int * triangles, unsigned int nv, unsigned int nt, int divisions = 50)
30 //
31 // Purpose: Creates a data structure for accelerates intersection tests against a bounding surface
32 // A MeshBndSurf object requires the bounding surface be expressed as a triangulated surface mesh
33 // in 3D space. It uses a simple cartesian grid to accelerate tests. It has no special persistance
34 // so if it is a local variable it will be destroyed when it goes out of scope. Most uses
35 // will probably allocate a MeshBndSurf using new to avoid this.
36 //
37 // NOTE: the data in the "nodes" and "triangles" arrays will be copied. These arrays should be deleted
38 // after initialize() returns to conserve storage space
39 //
40 //
41 // Input:
42 // double * nodes: the coordinates of 3D nodes of the bounding mesh in an array of size 3*nv
43 // node i has it's x coordinate at nodes[3*i], y coordinate at nodes[3*i+1]
44 // z coordinate at nodes[3*i+2]
45 //
46 // unsigned int nv: number of nodes in the input mesh
47 //
48 // int * triangles: the triangles of the bounding mesh in an array of size 3*nt
49 // triangle i has the indices of it's nodes stored at triangles[3*i],
50 // triangles[3*i+1], and triangles[3*i+2]
51 //
52 // unsigned int nt: number of triangles in the input mesh
53 //
54 // int divisions: the number of grid divisions along the longest axis
55 // MUST BE BETWEEN 1 and 1023
56 // If perfomance is slow due too a densely tesselated mesh, increase divisions
57 //
58 //------------------------------------------------------------------------------------------------------
59 // bool intersection(double * p, double * d, double * x)
60 //
61 // Purpose: determines if displacing a point p by offset d will cross the bounding surface
62 // if so, the point of intersection is the output
63 //
64 // Input:
65 // double * p: a point in 3D space exressed as an array of 3 doubles
66 // x coordinate is in p[0], y in p[1] and z in p[2]
67 //
68 // double * d: a displacment of p in 3D space expressed as an array of doubles
69 //
70 // Ouput: double * x: the calling code provides storage for a 3D point passed as this parameter
71 // if the function finds an intersection, x will hold the 3D coordinates of the point of
72 // intersection between the bounding mesh and the line segment (p,p+d)
73 //
74 // Returns: true if line segment (p,p+d) intersects the bounding mesh. Otherwise false
75 //------------------------------------------------------------------------------------------------------
76 //
77 //
78 
79 #define GRID_NO 100
80 #define MAX_GRID_DIV 1023
81 
82 using namespace std;
83 using namespace nvc;
84 
86 {
87 
88  private:
90  Point3D bbmin, bbmax;
93  unsigned int numv;
94  unsigned int numt;
95 
96  void compute_bbox(Point3D &bbmin, Point3D &bbmax)
97  {
98  if (numv == 0)
99  {
100  bbmin = bbmax = 0.0;
101  }
102  else
103  {
104  bbmin = bbmax = node_array[0];
105  }
106 
107  for(unsigned int i=1; i<numv; i++)
108  {
109  Vertex3D & v = node_array[i];
110 
111  if(v[0] < bbmin[0]) bbmin[0]=v[0];
112  if(v[1] < bbmin[1]) bbmin[1]=v[1];
113  if(v[2] < bbmin[2]) bbmin[2]=v[2];
114 
115  if(v[0] > bbmax[0]) bbmax[0]=v[0];
116  if(v[1] > bbmax[1]) bbmax[1]=v[1];
117  if(v[2] > bbmax[2]) bbmax[2]=v[2];
118  }
119  }
120 
121  public:
122 
123  MeshBndSurf():gSpace(NULL),node_array(NULL),tri_array(NULL),numv(0),numt(0){}
124 
125  MeshBndSurf(Vec3D * n, Tri * t,unsigned int nv,
126  unsigned int nt):node_array(n),tri_array(t),numv(nv),numt(nt)
127  {
128  compute_bbox(bbmin, bbmax);
129  gSpace = new KNN_Grid< Tri > (bbmin, bbmax, 8);
130  for(unsigned int i=0; i<nt; ++i){
131  Point3D p(n[t[i][0]][0], n[t[i][0]][1], n[t[i][0]][2]);
132  Point3D q(n[t[i][1]][0], n[t[i][1]][1], n[t[i][1]][2]);
133  Point3D r(n[t[i][2]][0], n[t[i][2]][1], n[t[i][2]][2]);
134  gSpace->insertRange(t[i], p,q,r);
135  }
136  }
137 
139  delete gSpace;
140  delete [] node_array;
141  delete [] tri_array;
142  }
143 
144 bool intersection(const Vec3D & p, const Vec3D & d, Vec3D & x)
145  {
146  double orig[3];
147  double dir[3];
148  double v1[3];
149  double v2[3];
150  double v3[3];
151  double t;
152 
153  Point3D a,b;
154  a = p;
155  b = p+d;
156  vector<Tri> * hitTri = gSpace->get_cell_range(a,b);
157 
158  t = 0;
159 
160  for(int j=0;j<3;j++)
161  {
162  orig[j] = p[j];
163  dir[j] = d[j];
164  }
165 
166  for(vector<Tri>::iterator it = hitTri->begin(); it !=hitTri->end(); it++)
167  {
168  Tri & cur = *it;
169  for(int j=0;j<3;j++)
170  {
171  v1[j]=(node_array[cur[0]])[j];
172  v2[j]=(node_array[cur[1]])[j];
173  v3[j]=(node_array[cur[2]])[j];
174  }
175  if (rayIntersectsTriangle(orig, dir,v1,v2,v3,x))
176  {
177  //Debugging info
178  std::cerr << "XXXX Ray " << p << " to " << d
179  << " Tri " << std::endl;
180  std::cerr << node_array[cur[0]] << std::endl;
181  std::cerr << node_array[cur[1]] << std::endl;
182  std::cerr << node_array[cur[2]] << std::endl << std::endl;
183  return true;
184  }
185  else
186  {
187  std::cerr << "0000 Ray "<< p << " to" << d
188  << " Tri " << std::endl;
189  std::cerr << node_array[cur[0]] << std::endl;
190  std::cerr << node_array[cur[1]] << std::endl;
191  std::cerr << node_array[cur[2]] << std::endl << std::endl;
192  }
193  }
194  return false;
195  }
196 
197  void initialize(double * nodes, int * triangles, unsigned int nv, unsigned int nt, int divisions = 50)
198  {
199  numv=nv;
200  numt=nt;
201  //make sure grid divisions are sane
202  if (divisions > MAX_GRID_DIV)
203  {
204  cerr << "Grid divsisions on longest dimension must be less than or equal to "
205  << MAX_GRID_DIV << endl;
206  divisions = MAX_GRID_DIV;
207  }
208 
209  //Copy nodal coordinates
210  if (node_array != NULL)
211  delete [] node_array;
212 
213  node_array = new Vec3D[numv];
214  for(unsigned int i=0;i<numv;i++)
215  {
216  for(int j=0;j<3;j++)
217  {
218  (node_array[i])[j]=nodes[i*3+j];
219  }
220  }
221 
222  //Copy triangle connectivity
223  if (tri_array != NULL)
224  delete [] tri_array;
225 
226  tri_array = new Tri[numt];
227  for(unsigned int i=0;i<numt;i++)
228  {
229  for(int j=0;j<3;j++)
230  {
231  (tri_array[i])[j]=triangles[i*3+j];
232  }
233  }
234 
235  compute_bbox(bbmin, bbmax);
236  if (gSpace != NULL)
237  delete gSpace;
238 
239  gSpace = new KNN_Grid< Tri > (bbmin, bbmax, divisions);
240  for(unsigned int i=0; i<nt; ++i)
241  {
242  Point3D p(node_array[tri_array[i][0]][0], node_array[tri_array[i][0]][1], node_array[tri_array[i][0]][2]);
243  Point3D q(node_array[tri_array[i][1]][0], node_array[tri_array[i][1]][1], node_array[tri_array[i][1]][2]);
244  Point3D r(node_array[tri_array[i][2]][0], node_array[tri_array[i][2]][1], node_array[tri_array[i][2]][2]);
245  gSpace->insertRange(tri_array[i], p,q,r);
246  }
247  }
248 
249  bool intersection(double * p, double * d, double * x)
250  {
251  double orig[3];
252  double dir[3];
253  double v1[3];
254  double v2[3];
255  double v3[3];
256  double t;
257  Vec3D xint;
258  Point3D a,b;
259  for(int j=0;j<3;j++)
260  {
261  a[j] = p[j];
262  b[j] = p[j]+d[j];
263  }
264  vector<Tri> * hitTri = gSpace->get_cell_range(a,b);
265  if(hitTri->size() == 0){
266  // std::cout << "Rocon> WARNING: No constraint boundary found for p("
267  // << a[0] << "," << a[1] << "," << a[2] << "), d(" << d[0]
268  // << "," << d[1] << "," << d[2] << std::endl;
269  }
270  // else
271  // std::cout << "Rocon> Checking " << hitTri->size() << " triangles for intersection for < "
272  // << a[0] << "," << a[1] << "," << a[2] << " >" << std::endl;
273  t = 0;
274 
275  for(int j=0;j<3;j++)
276  {
277  orig[j] = p[j];
278  dir[j] = d[j];
279  }
280 
281  for(vector<Tri>::iterator it = hitTri->begin(); it !=hitTri->end(); it++)
282  {
283  Tri & cur = *it;
284  for(int j=0;j<3;j++)
285  {
286  v1[j]=(node_array[cur[0]])[j];
287  v2[j]=(node_array[cur[1]])[j];
288  v3[j]=(node_array[cur[2]])[j];
289  }
290  if (rayIntersectsTriangle(orig, dir,v1,v2,v3,xint))
291  {
292  for(int i=0;i<3;i++)
293  x[i]=xint[i];
294  hitTri->resize(0);
295  delete hitTri;
296  return true;
297  }
298  // else
299  // {
300  // std::cout << "Rocon> " " Tri< " << node_array[cur[0]]
301  // << ","<< node_array[cur[1]] << ","
302  // << node_array[cur[2]] << " >" << std::endl;
303  // }
304  }
305  if(hitTri){
306  hitTri->resize(0);
307  delete hitTri;
308  }
309  return false;
310  }
311 
312 
313 };
314 
315 
316 #endif
const NT & d
MeshBndSurf(Vec3D *n, Tri *t, unsigned int nv, unsigned int nt)
*********************************************************************Illinois Open Source License ****University of Illinois NCSA **Open Source License University of Illinois All rights reserved ****Developed free of to any person **obtaining a copy of this software and associated documentation to deal with the Software without including without limitation the rights to and or **sell copies of the and to permit persons to whom the **Software is furnished to do subject to the following this list of conditions and the following disclaimers ****Redistributions in binary form must reproduce the above **copyright this list of conditions and the following **disclaimers in the documentation and or other materials **provided with the distribution ****Neither the names of the Center for Simulation of Advanced the University of nor the names of its **contributors may be used to endorse or promote products derived **from this Software without specific prior written permission ****THE SOFTWARE IS PROVIDED AS WITHOUT WARRANTY OF ANY **EXPRESS OR INCLUDING BUT NOT LIMITED TO THE WARRANTIES **OF FITNESS FOR A PARTICULAR PURPOSE AND **NONINFRINGEMENT IN NO EVENT SHALL THE CONTRIBUTORS OR **COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES OR OTHER WHETHER IN AN ACTION OF TORT OR **ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE **USE OR OTHER DEALINGS WITH THE SOFTWARE v
Definition: roccomf90.h:20
void compute_bbox(Point3D &bbmin, Point3D &bbmax)
void initialize(double *nodes, int *triangles, unsigned int nv, unsigned int nt, int divisions=50)
blockLoc i
Definition: read.cpp:79
void int int REAL * x
Definition: read.cpp:74
const NT & n
bool rayIntersectsTriangle(double *p, double *d, double *v0, double *v1, double *v2, Vec3D &I)
#define MAX_GRID_DIV
bool intersection(const Vec3D &p, const Vec3D &d, Vec3D &x)
bool intersection(double *p, double *d, double *x)
j indices j
Definition: Indexing.h:6
NT q
KNN_Grid< Tri > * gSpace