| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #ifndef GEOMETRY_INCLUDED |
| | #define GEOMETRY_INCLUDED |
| |
|
| | #include <math.h> |
| | #include <vector> |
| | #include <stdlib.h> |
| | #include <stdio.h> |
| | #include "Hash.h" |
| |
|
| | template<class Real> |
| | Real Random(void); |
| |
|
| | template< class Real > |
| | struct Point3D |
| | { |
| | Real coords[3]; |
| | Point3D( void ) { coords[0] = coords[1] = coords[2] = Real(0); } |
| | Point3D( Real v ) { coords[0] = coords[1] = coords[2] = v; } |
| | template< class _Real > Point3D( _Real v0 , _Real v1 , _Real v2 ){ coords[0] = Real(v0) , coords[1] = Real(v1) , coords[2] = Real(v2); } |
| | template< class _Real > Point3D( const Point3D< _Real >& p ){ coords[0] = Real( p[0] ) , coords[1] = Real( p[1] ) , coords[2] = Real( p[2] ); } |
| | inline Real& operator[] ( int i ) { return coords[i]; } |
| | inline const Real& operator[] ( int i ) const { return coords[i]; } |
| | inline Point3D operator - ( void ) const { Point3D q ; q.coords[0] = -coords[0] , q.coords[1] = -coords[1] , q.coords[2] = -coords[2] ; return q; } |
| |
|
| | template< class _Real > inline Point3D& operator += ( Point3D< _Real > p ){ coords[0] += Real(p.coords[0]) , coords[1] += Real(p.coords[1]) , coords[2] += Real(p.coords[2]) ; return *this; } |
| | template< class _Real > inline Point3D operator + ( Point3D< _Real > p ) const { Point3D q ; q.coords[0] = coords[0] + Real(p.coords[0]) , q.coords[1] = coords[1] + Real(p.coords[1]) , q.coords[2] = coords[2] + Real(p.coords[2]) ; return q; } |
| | template< class _Real > inline Point3D& operator *= ( _Real r ) { coords[0] *= Real(r) , coords[1] *= Real(r) , coords[2] *= Real(r) ; return *this; } |
| | template< class _Real > inline Point3D operator * ( _Real r ) const { Point3D q ; q.coords[0] = coords[0] * Real(r) , q.coords[1] = coords[1] * Real(r) , q.coords[2] = coords[2] * Real(r) ; return q; } |
| |
|
| | template< class _Real > inline Point3D& operator -= ( Point3D< _Real > p ){ return ( (*this)+=(-p) ); } |
| | template< class _Real > inline Point3D operator - ( Point3D< _Real > p ) const { return (*this)+(-p); } |
| | template< class _Real > inline Point3D& operator /= ( _Real r ){ return ( (*this)*=Real(1./r) ); } |
| | template< class _Real > inline Point3D operator / ( _Real r ) const { return (*this) * ( Real(1.)/r ); } |
| |
|
| | static Real Dot( const Point3D< Real >& p1 , const Point3D< Real >& p2 ){ return p1.coords[0]*p2.coords[0] + p1.coords[1]*p2.coords[1] + p1.coords[2]*p2.coords[2]; } |
| | template< class Real1 , class Real2 > |
| | static Real Dot( const Point3D< Real1 >& p1 , const Point3D< Real2 >& p2 ){ return Real( p1.coords[0]*p2.coords[0] + p1.coords[1]*p2.coords[1] + p1.coords[2]*p2.coords[2] ); } |
| | }; |
| |
|
| | template< class Real > |
| | struct XForm3x3 |
| | { |
| | Real coords[3][3]; |
| | XForm3x3( void ) { for( int i=0 ; i<3 ; i++ ) for( int j=0 ; j<3 ; j++ ) coords[i][j] = Real(0.); } |
| | static XForm3x3 Identity( void ) |
| | { |
| | XForm3x3 xForm; |
| | xForm(0,0) = xForm(1,1) = xForm(2,2) = Real(1.); |
| | return xForm; |
| | } |
| | Real& operator() ( int i , int j ){ return coords[i][j]; } |
| | const Real& operator() ( int i , int j ) const { return coords[i][j]; } |
| | template< class _Real > Point3D< _Real > operator * ( const Point3D< _Real >& p ) const |
| | { |
| | Point3D< _Real > q; |
| | for( int i=0 ; i<3 ; i++ ) for( int j=0 ; j<3 ; j++ ) q[i] += _Real( coords[j][i] * p[j] ); |
| | return q; |
| | } |
| | XForm3x3 operator * ( const XForm3x3& m ) const |
| | { |
| | XForm3x3 n; |
| | for( int i=0 ; i<3 ; i++ ) for( int j=0 ; j<3 ; j++ ) for( int k=0 ; k<3 ; k++ ) n.coords[i][j] += m.coords[i][k]*coords[k][j]; |
| | return n; |
| | } |
| | XForm3x3 transpose( void ) const |
| | { |
| | XForm3x3 xForm; |
| | for( int i=0 ; i<3 ; i++ ) for( int j=0 ; j<3 ; j++ ) xForm( i , j ) = coords[j][i]; |
| | return xForm; |
| | } |
| | Real subDeterminant( int i , int j ) const |
| | { |
| | int i1 = (i+1)%3 , i2 = (i+2)%3; |
| | int j1 = (j+1)%3 , j2 = (j+2)%3; |
| | return coords[i1][j1] * coords[i2][j2] - coords[i1][j2] * coords[i2][j1]; |
| | } |
| | Real determinant( void ) const { return coords[0][0] * subDeterminant( 0 , 0 ) + coords[1][0] * subDeterminant( 1 , 0 ) + coords[2][0] * subDeterminant( 2 , 0 ); } |
| | XForm3x3 inverse( void ) const |
| | { |
| | XForm3x3 xForm; |
| | Real d = determinant(); |
| | for( int i=0 ; i<3 ; i++ ) for( int j=0 ; j<3 ;j++ ) xForm.coords[j][i] = subDeterminant( i , j ) / d; |
| | return xForm; |
| | } |
| | }; |
| |
|
| | template< class Real > |
| | struct XForm4x4 |
| | { |
| | Real coords[4][4]; |
| | XForm4x4( void ) { for( int i=0 ; i<4 ; i++ ) for( int j=0 ; j<4 ; j++ ) coords[i][j] = Real(0.); } |
| | static XForm4x4 Identity( void ) |
| | { |
| | XForm4x4 xForm; |
| | xForm(0,0) = xForm(1,1) = xForm(2,2) = xForm(3,3) = Real(1.); |
| | return xForm; |
| | } |
| | Real& operator() ( int i , int j ){ return coords[i][j]; } |
| | const Real& operator() ( int i , int j ) const { return coords[i][j]; } |
| | template< class _Real > Point3D< _Real > operator * ( const Point3D< _Real >& p ) const |
| | { |
| | Point3D< _Real > q; |
| | for( int i=0 ; i<3 ; i++ ) |
| | { |
| | for( int j=0 ; j<3 ; j++ ) q[i] += (_Real)( coords[j][i] * p[j] ); |
| | q[i] += (_Real)coords[3][i]; |
| | } |
| | return q; |
| | } |
| | XForm4x4 operator * ( const XForm4x4& m ) const |
| | { |
| | XForm4x4 n; |
| | for( int i=0 ; i<4 ; i++ ) for( int j=0 ; j<4 ; j++ ) for( int k=0 ; k<4 ; k++ ) n.coords[i][j] += m.coords[i][k]*coords[k][j]; |
| | return n; |
| | } |
| | XForm4x4 transpose( void ) const |
| | { |
| | XForm4x4 xForm; |
| | for( int i=0 ; i<4 ; i++ ) for( int j=0 ; j<4 ; j++ ) xForm( i , j ) = coords[j][i]; |
| | return xForm; |
| | } |
| | Real subDeterminant( int i , int j ) const |
| | { |
| | XForm3x3< Real > xForm; |
| | int ii[] = { (i+1)%4 , (i+2)%4 , (i+3)%4 } , jj[] = { (j+1)%4 , (j+2)%4 , (j+3)%4 }; |
| | for( int _i=0 ; _i<3 ; _i++ ) for( int _j=0 ; _j<3 ; _j++ ) xForm( _i , _j ) = coords[ ii[_i] ][ jj[_j] ]; |
| | return xForm.determinant(); |
| | } |
| | Real determinant( void ) const { return coords[0][0] * subDeterminant( 0 , 0 ) - coords[1][0] * subDeterminant( 1 , 0 ) + coords[2][0] * subDeterminant( 2 , 0 ) - coords[3][0] * subDeterminant( 3 , 0 ); } |
| | XForm4x4 inverse( void ) const |
| | { |
| | XForm4x4 xForm; |
| | Real d = determinant(); |
| | for( int i=0 ; i<4 ; i++ ) for( int j=0 ; j<4 ;j++ ) |
| | if( (i+j)%2==0 ) xForm.coords[j][i] = subDeterminant( i , j ) / d; |
| | else xForm.coords[j][i] = -subDeterminant( i , j ) / d; |
| | return xForm; |
| | } |
| | }; |
| |
|
| |
|
| | template<class Real> |
| | Point3D<Real> RandomBallPoint(void); |
| |
|
| | template<class Real> |
| | Point3D<Real> RandomSpherePoint(void); |
| |
|
| | template<class Real> |
| | double Length(const Point3D<Real>& p); |
| |
|
| | template<class Real> |
| | double SquareLength(const Point3D<Real>& p); |
| |
|
| | template<class Real> |
| | double Distance(const Point3D<Real>& p1,const Point3D<Real>& p2); |
| |
|
| | template<class Real> |
| | double SquareDistance(const Point3D<Real>& p1,const Point3D<Real>& p2); |
| |
|
| | template <class Real> |
| | void CrossProduct(const Point3D<Real>& p1,const Point3D<Real>& p2,Point3D<Real>& p); |
| |
|
| |
|
| | class Edge{ |
| | public: |
| | double p[2][2]; |
| | double Length(void) const{ |
| | double d[2]; |
| | d[0]=p[0][0]-p[1][0]; |
| | d[1]=p[0][1]-p[1][1]; |
| |
|
| | return sqrt(d[0]*d[0]+d[1]*d[1]); |
| | } |
| | }; |
| | class Triangle{ |
| | public: |
| | double p[3][3]; |
| | double Area(void) const{ |
| | double v1[3] , v2[3] , v[3]; |
| | for( int d=0 ; d<3 ; d++ ) |
| | { |
| | v1[d] = p[1][d] - p[0][d]; |
| | v2[d] = p[2][d] - p[0][d]; |
| | } |
| | v[0] = v1[1]*v2[2] - v1[2]*v2[1]; |
| | v[1] = -v1[0]*v2[2] + v1[2]*v2[0]; |
| | v[2] = v1[0]*v2[1] - v1[1]*v2[0]; |
| | return sqrt( v[0]*v[0] + v[1]*v[1] + v[2]*v[2] ) / 2; |
| | } |
| | double AspectRatio(void) const{ |
| | double d=0; |
| | int i,j; |
| | for(i=0;i<3;i++){ |
| | for(i=0;i<3;i++) |
| | for(j=0;j<3;j++){d+=(p[(i+1)%3][j]-p[i][j])*(p[(i+1)%3][j]-p[i][j]);} |
| | } |
| | return Area()/d; |
| | } |
| | |
| | }; |
| | class CoredPointIndex |
| | { |
| | public: |
| | int index; |
| | char inCore; |
| |
|
| | int operator == (const CoredPointIndex& cpi) const {return (index==cpi.index) && (inCore==cpi.inCore);}; |
| | int operator != (const CoredPointIndex& cpi) const {return (index!=cpi.index) || (inCore!=cpi.inCore);}; |
| | }; |
| | class EdgeIndex{ |
| | public: |
| | int idx[2]; |
| | }; |
| | class CoredEdgeIndex |
| | { |
| | public: |
| | CoredPointIndex idx[2]; |
| | }; |
| | class TriangleIndex{ |
| | public: |
| | int idx[3]; |
| | }; |
| |
|
| | class TriangulationEdge |
| | { |
| | public: |
| | TriangulationEdge(void); |
| | int pIndex[2]; |
| | int tIndex[2]; |
| | }; |
| |
|
| | class TriangulationTriangle |
| | { |
| | public: |
| | TriangulationTriangle(void); |
| | int eIndex[3]; |
| | }; |
| |
|
| | template<class Real> |
| | class Triangulation |
| | { |
| | public: |
| |
|
| | std::vector<Point3D<Real> > points; |
| | std::vector<TriangulationEdge> edges; |
| | std::vector<TriangulationTriangle> triangles; |
| |
|
| | int factor( int tIndex,int& p1,int& p2,int& p3); |
| | double area(void); |
| | double area( int tIndex ); |
| | double area( int p1 , int p2 , int p3 ); |
| | int flipMinimize( int eIndex); |
| | int addTriangle( int p1 , int p2 , int p3 ); |
| |
|
| | protected: |
| | hash_map<long long,int> edgeMap; |
| | static long long EdgeIndex( int p1 , int p2 ); |
| | double area(const Triangle& t); |
| | }; |
| |
|
| |
|
| | template<class Real> |
| | void EdgeCollapse(const Real& edgeRatio,std::vector<TriangleIndex>& triangles,std::vector< Point3D<Real> >& positions,std::vector<Point3D<Real> >* normals); |
| | template<class Real> |
| | void TriangleCollapse(const Real& edgeRatio,std::vector<TriangleIndex>& triangles,std::vector<Point3D<Real> >& positions,std::vector<Point3D<Real> >* normals); |
| |
|
| | struct CoredVertexIndex |
| | { |
| | int idx; |
| | bool inCore; |
| | }; |
| | template< class Vertex > |
| | class CoredMeshData |
| | { |
| | public: |
| | std::vector< Vertex > inCorePoints; |
| | virtual void resetIterator( void ) = 0; |
| |
|
| | virtual int addOutOfCorePoint( const Vertex& p ) = 0; |
| | virtual int addOutOfCorePoint_s( const Vertex& p ) = 0; |
| | virtual int addPolygon_s( const std::vector< CoredVertexIndex >& vertices ) = 0; |
| | virtual int addPolygon_s( const std::vector< int >& vertices ) = 0; |
| |
|
| | virtual int nextOutOfCorePoint( Vertex& p )=0; |
| | virtual int nextPolygon( std::vector< CoredVertexIndex >& vertices ) = 0; |
| |
|
| | virtual int outOfCorePointCount(void)=0; |
| | virtual int polygonCount( void ) = 0; |
| | }; |
| |
|
| | template< class Vertex > |
| | class CoredVectorMeshData : public CoredMeshData< Vertex > |
| | { |
| | std::vector< Vertex > oocPoints; |
| | std::vector< std::vector< int > > polygons; |
| | int polygonIndex; |
| | int oocPointIndex; |
| | public: |
| | CoredVectorMeshData(void); |
| |
|
| | void resetIterator(void); |
| |
|
| | int addOutOfCorePoint( const Vertex& p ); |
| | int addOutOfCorePoint_s( const Vertex& p ); |
| | int addPolygon_s( const std::vector< CoredVertexIndex >& vertices ); |
| | int addPolygon_s( const std::vector< int >& vertices ); |
| |
|
| | int nextOutOfCorePoint( Vertex& p ); |
| | int nextPolygon( std::vector< CoredVertexIndex >& vertices ); |
| |
|
| | int outOfCorePointCount(void); |
| | int polygonCount( void ); |
| | }; |
| | class BufferedReadWriteFile |
| | { |
| | bool tempFile; |
| | FILE* _fp; |
| | char *_buffer , _fileName[1024]; |
| | size_t _bufferIndex , _bufferSize; |
| | public: |
| | BufferedReadWriteFile( char* fileName=NULL , int bufferSize=(1<<20) ); |
| | ~BufferedReadWriteFile( void ); |
| | bool write( const void* data , size_t size ); |
| | bool read ( void* data , size_t size ); |
| | void reset( void ); |
| | }; |
| | template< class Vertex > |
| | class CoredFileMeshData : public CoredMeshData< Vertex > |
| | { |
| | char pointFileName[1024] , polygonFileName[1024]; |
| | BufferedReadWriteFile *oocPointFile , *polygonFile; |
| | int oocPoints , polygons; |
| | public: |
| | CoredFileMeshData( void ); |
| | ~CoredFileMeshData( void ); |
| |
|
| | void resetIterator( void ); |
| |
|
| | int addOutOfCorePoint( const Vertex& p ); |
| | int addOutOfCorePoint_s( const Vertex& p ); |
| | int addPolygon_s( const std::vector< CoredVertexIndex >& vertices ); |
| | int addPolygon_s( const std::vector< int >& vertices ); |
| |
|
| | int nextOutOfCorePoint( Vertex& p ); |
| | int nextPolygon( std::vector< CoredVertexIndex >& vertices ); |
| |
|
| | int outOfCorePointCount( void ); |
| | int polygonCount( void ); |
| | }; |
| | #include "Geometry.inl" |
| |
|
| | #endif |
| |
|