Go to the documentation of this file.00001 #ifndef OPENTISSUE_BVH_BOTTOM_UP_CONSTRUCTOR_BVH_VOLUME2BVH_GRAPH_H
00002 #define OPENTISSUE_BVH_BOTTOM_UP_CONSTRUCTOR_BVH_VOLUME2BVH_GRAPH_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/utility/utility_qhull.h>
00013 #include <OpenTissue/collision/gjk/gjk.h>
00014
00015 #include <cassert>
00016 #include <vector>
00017 #include <map>
00018
00019 namespace OpenTissue
00020 {
00021 namespace bvh
00022 {
00023
00031 template<typename graph_type>
00032 class Volume2BVHGraph
00033 {
00034 public:
00035
00036 typedef typename graph_type::node_ptr_type node_ptr_type;
00037 typedef typename graph_type::edge_ptr_type edge_ptr_type;
00038 typedef typename graph_type::volume_type volume_type;
00039
00040 public:
00041
00049 template<typename volume_iterator>
00050 void delaunay(volume_iterator & begin,volume_iterator & end,graph_type & graph)
00051 {
00052 int N = 0;
00053 std::map<unsigned int,node_ptr_type > node_lookup;
00054 for(volume_iterator volume=begin;volume!=end;++volume)
00055 {
00056 node_ptr_type node = graph.insert( (*volume) );
00057 node_lookup[N] = node;
00058 ++N;
00059 }
00060 assert(N>3);
00061
00062 int dim = 3;
00063 coordT *coords = new coordT[dim*N];
00064 boolT ismalloc = False;
00065 char flags[] = "qhull v QJ";
00066 FILE *outfile = stdout;
00067 FILE *errfile = stderr;
00068 int exitcode;
00069 int j = 0;
00070
00071 for(volume_iterator volume=begin;volume!=end;++volume)
00072 {
00073 coords[j++] = volume->center()(0);
00074 coords[j++] = volume->center()(1);
00075 coords[j++] = volume->center()(2);
00076 }
00077
00078 exitcode= qh_new_qhull (dim, N, coords, ismalloc, flags, outfile, errfile);
00079 if(!exitcode)
00080 {
00081 vertexT *vertex;
00082 facetT *neighbor,**neighborp;
00083 qh visit_id++;
00084 bool ** exist = new bool*[N];
00085 for(int i=0;i<N;++i)
00086 {
00087 exist[i] = new bool[N];
00088 for(int j=0;j<N;++j)
00089 exist[i][j] = false;
00090 }
00091 FORALLvertices
00092 {
00093 vertex->visitid = qh visit_id;
00094 unsigned int idA = qh_pointid (vertex->point);
00095 FOREACHneighbor_(vertex)
00096 {
00097 if(neighbor->visitid != qh visit_id)
00098 {
00099 neighbor->visitid = qh visit_id;
00100 vertexT *vertex, **vertexp;
00101 FOREACHvertex_(neighbor->vertices)
00102 {
00103 if(vertex->visitid != qh visit_id)
00104 {
00105 unsigned int idB = qh_pointid (vertex->point);
00106 if(!exist[idA][idB])
00107 {
00108 exist[idA][idB] = true;
00109 exist[idB][idA] = true;
00110 node_ptr_type nodeA = node_lookup[idA];
00111 node_ptr_type nodeB = node_lookup[idB];
00112 graph.insert(nodeA,nodeB);
00113 }
00114 }
00115 }
00116 }
00117 }
00118 }
00119 for(int i=0;i<N;++i)
00120 {
00121 delete [] exist[i];
00122 }
00123 delete [] exist;
00124 }
00125 qh_freeqhull(!qh_ALL);
00126 int curlong, totlong;
00127 qh_memfreeshort (&curlong, &totlong);
00128 if (curlong || totlong)
00129 fprintf (errfile, "qhull internal warning (main): did not free %d bytes of long memory (%d pieces)\n", totlong, curlong);
00130 delete [] coords;
00131 }
00132
00133
00140 template<typename volume_iterator>
00141 void all_pair(volume_iterator & begin,volume_iterator & end,graph_type & graph)
00142 {
00143 int N = 0;
00144 std::map<unsigned int,node_ptr_type > node_lookup;
00145 for(volume_iterator volume=begin;volume!=end;++volume)
00146 {
00147 node_ptr_type node = graph.insert( (*volume) );
00148 node_lookup[N] = node;
00149 ++N;
00150 }
00151 for(int i=0;i<N;++i)
00152 {
00153 for(int j=(i+1);j<N;++j)
00154 {
00155 node_ptr_type nodeA = node_lookup[i];
00156 node_ptr_type nodeB = node_lookup[j];
00157 graph.insert(nodeA,nodeB);
00158 }
00159 }
00160 }
00161
00167 template<typename volume_iterator>
00168 void colliding(const volume_iterator & begin,const volume_iterator & end, graph_type & graph)
00169 {
00170
00171 int N = 0;
00172 std::map<unsigned int,node_ptr_type > node_lookup;
00173 for(volume_iterator volume=begin;volume!=end;++volume)
00174 {
00175 node_ptr_type node = graph.insert( (*volume) );
00176 node_lookup[N] = node;
00177 ++N;
00178 }
00179
00180 std::vector<volume_type> enlarged(N);
00181 int i = 0;
00182 for(volume_iterator volume=begin;volume!=end;++volume)
00183 {
00184 enlarged[i] = (*volume);
00185 enlarged[i].scale(1.25);
00186 ++i;
00187 }
00188
00189 OpenTissue::gjk::obsolete::detail::GJK< math::Vector3<double> > gjk;
00190
00191 for(int i=0;i<N;++i)
00192 {
00193 for(int j=(i+1);j<N;++j)
00194 {
00195 volume_type * volA = &enlarged[i];
00196 volume_type * volB = &enlarged[j];
00197 math::Vector3<double> v = volA->center() - volB->center();
00198 bool intersecting = gjk.is_intersecting(*volA,*volB,v);
00199 if(intersecting)
00200 {
00201 node_ptr_type nodeA = node_lookup[i];
00202 node_ptr_type nodeB = node_lookup[j];
00203 graph.insert(nodeA,nodeB);
00204 }
00205 }
00206 }
00207 }
00208
00209 };
00210
00211 }
00212
00213 }
00214
00215
00216 #endif