Biomechanical Joint Model
 Author: Anderson Maciel

mesh.cpp

Go to the documentation of this file.
00001 /*@#---------------------------------------------------------------------------
00002  PROJECT            : PHD THESIS
00003  MODULE             : PHYSICALLY-BASED DEFORMATION
00004 
00005  FILE               : mesh.C
00006  CREATION DATE      : Thu Dec  2 12:22:33 MET 1999
00007  CREATION AUTHOR(S) : aubel 
00008  ------------------------------------------------------------------------------
00009  KEYWORD(S)         : marching cubes, voxelisation, volume
00010  DEFINED TYPE(S)    : Mesh class for marching cubes
00011  RELATED TYPE(S)    : 
00012 
00013  FUNCTIONALITY      : 
00014  ------------------------------------------------------------------------------
00015  LANGAGE            : Ansi C++
00016  SYSTEM             : UNIX V 6.x / SGI
00017  GRAPHIC LIBRARY    : SGI  
00018  ------------------------------------------------------------------------------
00019  PROJECT DIRECTOR   : D. THALMANN
00020  LAB                : EPFL- LIG
00021  --------------------------------------------------------------------------#@*/
00022 #include <vector>
00023 #include <list>
00024 #include <algorithm>
00025 
00026 #include "mesh.h"
00027 #include <RayCasting/bbox.h>
00028 #include <LinAlg/vec.h>
00029 
00030 //namespace MarchingCubes {
00031 
00032 Mesh::Mesh(const VECArray &vertlist, const VECArray &normlist, 
00033            const vector<int> &trilist, const vector<int> &normIndex) : 
00034    Primitive(),
00035    vertices(vertlist), normals(normlist), faces(trilist), normalIndex(normIndex),
00036    bbox_h(getBoundingBox()) 
00037 { 
00038    bbox_h.createHierarchy(vertices, faces, (int)sqrt(static_cast<float>(vertices.size())) );   
00039 }
00040 
00041 bool 
00042 Mesh::intersectedBy(Ray &ray) const
00043 {      
00044 
00045     int i;
00046     REAL u,v;
00047     return intersectedBy(ray, u, v, i);
00048 }
00049 
00050 bool
00051 Mesh::intersectedBy(Ray &ray, REAL &u, REAL &v, int &tri_idx) const
00052 {
00053    vector<int> triangles;
00054    bbox_h.getPotentialTriangles(ray, triangles);
00055 
00056    REAL t, u_, v_;
00057    ray.t = infinity; // used in the loop
00058    tri_idx = -1;     // used for final test
00059       
00060    for (vector<int>::const_iterator tri_it=triangles.begin(); tri_it!=triangles.end(); tri_it++)
00061    {
00062       int i = *tri_it;      
00063       if ( intersect_triangle(ray.O, ray.D, vertices[faces[i]],vertices[faces[i+1]],
00064                               vertices[faces[i+2]], t, u_, v_) == true )
00065       {
00066          // if intersection in segment & closer to origin than intersections previously found
00067          if ( t>=0.0 && t<ray.t)
00068          {
00069             ray.t = t;
00070             u = u_; v = v_;
00071             tri_idx = i;
00072          }
00073       }
00074    }
00075 
00076    if (tri_idx != -1)
00077    {
00078       ray.P = ray.O + ray.t * ray.D;      
00079       return (ray.segment==true)? (ray.t <= 1) : true;
00080    }
00081    return false;
00082 }
00083 
00084 REAL
00085 Mesh::getDistance(const VEC &X) const
00086 {
00087    Ray ray(X, VEC(3, "0 0 1"));
00088    vector<REAL> intersections;
00089 
00090    // list all intersections with ray starting from X and pointing (arbitrarily) in +Z
00091    vector<int> triangles;
00092    bbox_h.getPotentialTriangles(ray, triangles);
00093 
00094    for (vector<int>::const_iterator tri_it=triangles.begin(); tri_it!=triangles.end(); tri_it++)
00095    {
00096       int i = *tri_it;
00097       REAL u,v;
00098 
00099       if ( intersect_triangle(ray.O, ray.D, vertices[faces[i]],vertices[faces[i+1]],
00100                               vertices[faces[i+2]], ray.t, u, v) == true )
00101       {
00102          if ( fabs(ray.t) < epsilon ) return 0;
00103          else if (ray.t>0) intersections.push_back(ray.t);
00104       }
00105    }
00106 
00107    // if no intersection, point is outside of mesh
00108    // we don't need to compute how far it is from the mesh
00109    // as findIntersection does not rely on this value
00110    if (intersections.empty()) return -1;
00111    
00112    vector<REAL>::const_iterator it = min_element(intersections.begin(), intersections.end());
00113    REAL dist = *it;
00114    return (intersections.size()%2 == 0)? -dist : dist;
00115 }
00116 
00117   
00118 BBox
00119 Mesh::getBoundingBox()
00120 {
00121    bbox.makeEmpty();
00122 
00123    // loop thru all vertices
00124    for (int i=0; i<vertices.size(); i++) bbox.extendBy(vertices[i]);
00125 
00126    return bbox;
00127 }
00128 
00129 // the values valp1 and valp2 are useless here, as an analytic solution
00130 // can be computed
00131 void
00132 Mesh::findIntersection(const VEC &P1, const VEC &P2, REAL valp1, REAL valp2,
00133                        VEC &P, VEC &N) const
00134 {
00135    REAL u,v;
00136    int tri_idx;
00137  
00138    Ray ray(P1, P2-P1);
00139    ray.segment = true;
00140 
00141    if (!intersectedBy(ray, u, v, tri_idx))
00142    {
00143       cout << "Fatal error: no intersection in Mesh::findIntersection\n";
00144       return;
00145    }
00146    
00147    P = ray.P;
00148    N = (1-u-v) * normals[normalIndex[tri_idx]] 
00149        + u * normals[normalIndex[tri_idx+1]] 
00150        + v * normals[normalIndex[tri_idx+2]];
00151    N.normalize();
00152 }
00153 
00154 //}
00155 
00156 
00157 
00158 
00159  

Generated on Thu Dec 1 10:13:38 2005 for COME - Biomechanical Joint Model by  doxygen 1.4.5