00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef SOFA_COMPONENT_TOPOLOGY_SPARSEGRIDTOPOLOGY_H
00026 #define SOFA_COMPONENT_TOPOLOGY_SPARSEGRIDTOPOLOGY_H
00027
00028 #include <string>
00029
00030
00031 #include <sofa/component/topology/MeshTopology.h>
00032 #include <sofa/helper/MarchingCubeUtility.h>
00033 #include <sofa/defaulttype/Vec.h>
00034 #include <sofa/component/topology/RegularGridTopology.h>
00035
00036 #include <sofa/helper/io/Mesh.h>
00037 namespace sofa
00038 {
00039
00040 namespace component
00041 {
00042
00043 namespace topology
00044 {
00045
00046 using namespace sofa::defaulttype;
00047 using sofa::helper::MarchingCubeUtility;
00048
00053 class SparseGridTopology : public MeshTopology
00054 {
00055 public:
00056
00057 typedef fixed_array<Vector3,8> CubeCorners;
00058 typedef enum{OUTSIDE,INSIDE,BOUNDARY} Type;
00059
00060 typedef Vec<3, int> Vec3i;
00061
00062 SparseGridTopology(bool _isVirtual=false);
00063
00064
00065
00066
00067 static const float WEIGHT27[8][27];
00068 static const int cornerIndicesFromFineToCoarse[8][8];
00069
00070 bool load(const char* filename);
00071 virtual void init();
00072 void buildAsFinest();
00073 void buildFromFiner();
00074 void buildVirtualFinerLevels();
00075
00076 typedef std::map<Vector3,int> MapBetweenCornerPositionAndIndice;
00077
00079 typedef std::vector<fixed_array<int,8> > HierarchicalCubeMap;
00080 HierarchicalCubeMap _hierarchicalCubeMap;
00081 typedef helper::vector<int> InverseHierarchicalCubeMap;
00082 InverseHierarchicalCubeMap _inverseHierarchicalCubeMap;
00083
00084 typedef std::map<int,float> AHierarchicalPointMap;
00085
00086 typedef helper::vector< AHierarchicalPointMap > HierarchicalPointMap;
00087 HierarchicalPointMap _hierarchicalPointMap;
00088 typedef helper::vector< AHierarchicalPointMap > InverseHierarchicalPointMap;
00089 InverseHierarchicalPointMap _inverseHierarchicalPointMap;
00090 typedef helper::vector< int > PointMap;
00091 PointMap _pointMap;
00092 PointMap _inversePointMap;
00093
00094
00095 enum{UP,DOWN,RIGHT,LEFT,BEFORE,BEHIND,NUM_CONNECTED_NODES};
00096 typedef helper::vector< helper::fixed_array<int,NUM_CONNECTED_NODES> > NodeAdjacency;
00097 NodeAdjacency _nodeAdjacency;
00098 typedef helper::vector< helper::vector<int> >NodeCubesAdjacency;
00099 NodeCubesAdjacency _nodeCubesAdjacency;
00100 typedef helper::vector< helper::vector<int> >NodeCornersAdjacency;
00101 NodeCornersAdjacency _nodeCornersAdjacency;
00102
00103
00104 helper::vector<SparseGridTopology*> _virtualFinerLevels;
00105
00106
00107 Vec<3, int> getN() const { return n.getValue();}
00108 int getNx() const { return n.getValue()[0]; }
00109 int getNy() const { return n.getValue()[1]; }
00110 int getNz() const { return n.getValue()[2]; }
00111
00112 void setN(Vec3i _n) {n.setValue(_n);}
00113 void setNx(int _n) { n.setValue(Vec3i(_n ,n.getValue()[1],n.getValue()[2])); }
00114 void setNy(int _n) { n.setValue(Vec3i(n.getValue()[0],_n ,n.getValue()[2])); }
00115 void setNz(int _n) { n.setValue(Vec3i(n.getValue()[0],n.getValue()[1],_n) ); }
00116
00117 int getNbVirtualFinerLevels() const { return _nbVirtualFinerLevels.getValue();}
00118 void setNbVirtualFinerLevels(int n) {_nbVirtualFinerLevels.setValue(n);}
00119
00120 void setMin(Vector3 val) {_min.setValue(val);}
00121 void setXmin(SReal val) { _min.setValue(Vector3(val ,_min.getValue()[1],_min.getValue()[2])); }
00122 void setYmin(SReal val) { _min.setValue(Vector3(_min.getValue()[0],val ,_min.getValue()[2])); }
00123 void setZmin(SReal val) { _min.setValue(Vector3(_min.getValue()[0],_min.getValue()[1],val) ); }
00124
00125
00126 void setMax(Vector3 val) {_min.setValue(val);}
00127
00128 void setXmax(SReal val) { _max.setValue(Vector3(val ,_max.getValue()[1],_max.getValue()[2])); }
00129 void setYmax(SReal val) { _max.setValue(Vector3(_max.getValue()[0],val ,_max.getValue()[2])); }
00130 void setZmax(SReal val) { _max.setValue(Vector3(_max.getValue()[0],_max.getValue()[1],val) ); }
00131
00132 Vector3 getMin() {return _min.getValue();}
00133 SReal getXmin() { return _min.getValue()[0]; }
00134 SReal getYmin() { return _min.getValue()[1]; }
00135 SReal getZmin() { return _min.getValue()[2]; }
00136
00137 Vector3 getMax() {return _max.getValue();}
00138 SReal getXmax() { return _max.getValue()[0]; }
00139 SReal getYmax() { return _max.getValue()[1]; }
00140 SReal getZmax() { return _max.getValue()[2]; }
00141
00142 bool hasPos() const{ return true; }
00143
00146 virtual int findCube(const Vector3& pos, SReal& fx, SReal &fy, SReal &fz);
00147
00150 virtual int findNearestCube(const Vector3& pos, SReal& fx, SReal &fy, SReal &fz);
00151
00153 virtual helper::fixed_array<int,6> findneighboorCubes( int indice );
00154
00155
00157 virtual Type getType( int i );
00158
00159 SparseGridTopology* getFinerSparseGrid() const {return _finerSparseGrid;}
00160 void setFinerSparseGrid( SparseGridTopology* fsp ){_finerSparseGrid=fsp;}
00161 SparseGridTopology* getCoarserSparseGrid() const {return _coarserSparseGrid;}
00162 void setCoarserSparseGrid( SparseGridTopology* csp ){_coarserSparseGrid=csp;}
00163
00164 void updateMesh();
00165
00166 RegularGridTopology _regularGrid;
00167 vector< int > _indicesOfRegularCubeInSparseGrid;
00168 vector< int > _indicesOfCubeinRegularGrid;
00169
00170 Vector3 getPointPos( int i ){ return Vector3( seqPoints[i][0],seqPoints[i][1],seqPoints[i][2] ); }
00171
00172 void getMesh( sofa::helper::io::Mesh &m);
00173
00174
00175 void setDimVoxels( int a, int b, int c){ dataResolution.setValue(Vec3i(a,b,c));}
00176 void setSizeVoxel( float a, float b, float c){ voxelSize.setValue(Vector3(a,b,c));}
00177
00178 bool getVoxel(unsigned int x, unsigned int y, unsigned int z)
00179 {
00180 return getVoxel(dataResolution.getValue()[0]*dataResolution.getValue()[1]*z + dataResolution.getValue()[0]*y + x);
00181 }
00182
00183 bool getVoxel(unsigned int index) const
00184 {
00185 const int i = index%8;
00186 unsigned char c = dataVoxels.getValue()[index>>3];
00187 return ((c&((int)(pow(2.0f, i)))) >> i) == 1;
00188 };
00189
00190
00191 protected:
00192 bool isVirtual;
00194 Data< Vec<3, int> > n;
00195 Data< Vector3 > _min;
00196 Data< Vector3 > _max;
00197 Data< int > _nbVirtualFinerLevels;
00198
00199 Data< Vec3i > dataResolution;
00200 Data< Vector3 > voxelSize;
00201 Data< unsigned int > marchingCubeStep;
00202 Data< unsigned int > convolutionSize;
00203
00204 virtual void updateEdges();
00205 virtual void updateQuads();
00206 virtual void updateHexas();
00207
00208 MarchingCubeUtility marchingCubes;
00209 Data< vector< unsigned char > > dataVoxels;
00210 bool _usingMC;
00211
00212 sofa::helper::vector<Type> _types;
00213
00215 void propagateFrom( const int i, const int j, const int k,
00216 RegularGridTopology& regularGrid,
00217 vector<Type>& regularGridTypes,
00218 vector<bool>& alreadyTested ) const;
00219
00220 void computeBoundingBox(const helper::vector<Vector3>& vertices,
00221 SReal& xmin, SReal& xmax,
00222 SReal& ymin, SReal& ymax,
00223 SReal& zmin, SReal& zmax) const;
00224
00225 void voxelizeTriangleMesh(helper::io::Mesh* mesh,
00226 RegularGridTopology& regularGrid,
00227 vector<Type>& regularGridTypes) const;
00228
00229 void buildFromTriangleMesh(const std::string& filename);
00230
00231 void buildFromRegularGridTypes(RegularGridTopology& regularGrid, const vector<Type>& regularGridTypes);
00232
00243 void buildFromVoxelFile(const std::string& filename);
00244 void buildFromRawVoxelFile(const std::string& filename);
00245
00246 template< class T>
00247 void constructCollisionModels(const sofa::helper::vector< sofa::core::componentmodel::topology::BaseMeshTopology * > &list_mesh,
00248 const sofa::helper::vector< sofa::helper::vector< Vec<3,T> >* > &list_X) const;
00249
00250 SparseGridTopology* _finerSparseGrid;
00251 SparseGridTopology* _coarserSparseGrid;
00252
00253 void setVoxel(int index, unsigned char value){
00254 if (value)
00255 {
00256 (*dataVoxels.beginEdit())[index>>3] |= (int) pow(2.0f, (int)(index%8));
00257 }
00258 else
00259 {
00260 const int i = index%8;
00261 const int mask = (int) pow(2.0f, i);
00262 if (((*dataVoxels.beginEdit())[index>>3]&mask)>>i) (*dataVoxels.beginEdit())[index>>3] -= mask;
00263 }
00264 };
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00306
00307
00308 bool _alreadyInit;
00309
00310 public :
00311
00312 #ifdef SOFA_NEW_HEXA
00313 virtual const SeqHexas& getHexas()
00314 {
00315 if( !_alreadyInit ) init();
00316 return sofa::component::topology::MeshTopology::getHexas();
00317 }
00318 #else
00319 virtual const SeqCubes& getHexas()
00320 {
00321 if( !_alreadyInit ) init();
00322 return sofa::component::topology::MeshTopology::getHexas();
00323 }
00324 #endif
00325 virtual int getNbPoints() const
00326 {
00327 if( !_alreadyInit ) const_cast<SparseGridTopology*>(this)->init();
00328 return sofa::component::topology::MeshTopology::getNbPoints();
00329 }
00330
00331 virtual int getNbHexas() { return this->getHexas().size();}
00332
00333 };
00334
00335 }
00336
00337 }
00338
00339 }
00340
00341 #endif