SparseGridTopology.h

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
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 //                  virtual void reinit() {updateMesh();};
00065                     
00066 //                  static const float WEIGHT[8][8];
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 //                  typedef helper::vector< std::pair<int,float> >  AHierarchicalPointMap;
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                     /*  /// to compute valid cubes (intersection between mesh segments and cubes)
00268                     typedef struct segmentForIntersection{
00269                         Vector3 center;
00270                         Vector3 dir;
00271                         SReal norm;
00272                         segmentForIntersection(const Vector3& s0, const Vector3& s1)
00273                         {
00274                             center = (s0+s1)*.5;
00275                             dir = center-s0;
00276                             norm = dir.norm();
00277                             dir /= norm;
00278                         };
00279                     } SegmentForIntersection;
00280                     struct ltSegmentForIntersection // for set of SegmentForIntersection
00281                     {
00282                         bool operator()(const SegmentForIntersection& s0, const SegmentForIntersection& s1) const
00283                         {
00284                             return s0.center < s1.center || s0.norm < s1.norm;
00285                         }
00286                     };
00287                     typedef struct cubeForIntersection{
00288                         Vector3 center;
00289                         fixed_array<Vector3,3> dir;
00290                         Vector3 norm;
00291                         cubeForIntersection( const CubeCorners&  corners )
00292                         {
00293                             center = (corners[7] + corners[0]) * .5;
00294                             
00295                             norm[0] = (center[0] - corners[0][0]);
00296                             dir[0] = Vector3(1,0,0);
00297                             
00298                             norm[1] = (center[1] - corners[0][1]);
00299                             dir[1] = Vector3(0,1,0);
00300                             
00301                             norm[2] = (center[2] - corners[0][2]);
00302                             dir[2] = Vector3(0,0,1);
00303                         }
00304                     } CubeForIntersection;
00306                     bool intersectionSegmentBox( const SegmentForIntersection& seg, const CubeForIntersection& cube  ); */
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         } // namespace topology
00336 
00337     } // namespace component
00338 
00339 } // namespace sofa
00340 
00341 #endif

Generated on Sun Nov 23 03:45:50 2008 for Sofa by  doxygen 1.5.7.1