| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #ifndef __PLY_H__ |
| | #define __PLY_H__ |
| |
|
| | #define USE_PLY_WRAPPER 1 |
| |
|
| | #ifndef WIN32 |
| | #define _strdup strdup |
| | #endif |
| |
|
| | #ifdef __cplusplus |
| | extern "C" { |
| | #endif |
| | |
| | #include <stdlib.h> |
| | #include <stdio.h> |
| | #include <stddef.h> |
| | #include <string.h> |
| | |
| | #define PLY_ASCII 1 |
| | #define PLY_BINARY_BE 2 |
| | #define PLY_BINARY_LE 3 |
| | #define PLY_BINARY_NATIVE 4 |
| | |
| | #define PLY_OKAY 0 |
| | #define PLY_ERROR -1 |
| | |
| | |
| | |
| | #define PLY_START_TYPE 0 |
| | #define PLY_CHAR 1 |
| | #define PLY_SHORT 2 |
| | #define PLY_INT 3 |
| | #define PLY_UCHAR 4 |
| | #define PLY_USHORT 5 |
| | #define PLY_UINT 6 |
| | #define PLY_FLOAT 7 |
| | #define PLY_DOUBLE 8 |
| | #define PLY_INT_8 9 |
| | #define PLY_UINT_8 10 |
| | #define PLY_INT_16 11 |
| | #define PLY_UINT_16 12 |
| | #define PLY_INT_32 13 |
| | #define PLY_UINT_32 14 |
| | #define PLY_FLOAT_32 15 |
| | #define PLY_FLOAT_64 16 |
| | |
| | #define PLY_END_TYPE 17 |
| | |
| | #define PLY_SCALAR 0 |
| | #define PLY_LIST 1 |
| | |
| | #define PLY_STRIP_COMMENT_HEADER 0 |
| |
|
| | typedef struct PlyProperty { |
| | |
| | char *name; |
| | int external_type; |
| | int internal_type; |
| | int offset; |
| | |
| | int is_list; |
| | int count_external; |
| | int count_internal; |
| | int count_offset; |
| | |
| | } PlyProperty; |
| |
|
| | typedef struct PlyElement { |
| | char *name; |
| | int num; |
| | int size; |
| | int nprops; |
| | PlyProperty **props; |
| | char *store_prop; |
| | int other_offset; |
| | int other_size; |
| | } PlyElement; |
| |
|
| | typedef struct PlyOtherProp { |
| | char *name; |
| | int size; |
| | int nprops; |
| | PlyProperty **props; |
| | } PlyOtherProp; |
| |
|
| | typedef struct OtherData { |
| | void *other_props; |
| | } OtherData; |
| |
|
| | typedef struct OtherElem { |
| | char *elem_name; |
| | int elem_count; |
| | OtherData **other_data; |
| | PlyOtherProp *other_props; |
| | } OtherElem; |
| |
|
| | typedef struct PlyOtherElems { |
| | int num_elems; |
| | OtherElem *other_list; |
| | } PlyOtherElems; |
| |
|
| | typedef struct PlyFile { |
| | FILE *fp; |
| | int file_type; |
| | float version; |
| | int nelems; |
| | PlyElement **elems; |
| | int num_comments; |
| | char **comments; |
| | int num_obj_info; |
| | char **obj_info; |
| | PlyElement *which_elem; |
| | PlyOtherElems *other_elems; |
| | } PlyFile; |
| | |
| | |
| | extern char *my_alloc(); |
| | #define myalloc(mem_size) my_alloc((mem_size), __LINE__, __FILE__) |
| |
|
| | #ifndef ALLOCN |
| | #define REALLOCN(PTR,TYPE,OLD_N,NEW_N) \ |
| | { \ |
| | if ((OLD_N) == 0) \ |
| | { ALLOCN((PTR),TYPE,(NEW_N));} \ |
| | else \ |
| | { \ |
| | (PTR) = (TYPE *)realloc((PTR),(NEW_N)*sizeof(TYPE)); \ |
| | if (((PTR) == NULL) && ((NEW_N) != 0)) \ |
| | { \ |
| | fprintf(stderr, "Memory reallocation failed on line %d in %s\n", \ |
| | __LINE__, __FILE__); \ |
| | fprintf(stderr, " tried to reallocate %d->%d\n", \ |
| | (OLD_N), (NEW_N)); \ |
| | exit(-1); \ |
| | } \ |
| | if ((NEW_N)>(OLD_N)) \ |
| | memset((char *)(PTR)+(OLD_N)*sizeof(TYPE), 0, \ |
| | ((NEW_N)-(OLD_N))*sizeof(TYPE)); \ |
| | } \ |
| | } |
| |
|
| | #define ALLOCN(PTR,TYPE,N) \ |
| | { (PTR) = (TYPE *) calloc(((unsigned)(N)),sizeof(TYPE));\ |
| | if ((PTR) == NULL) { \ |
| | fprintf(stderr, "Memory allocation failed on line %d in %s\n", \ |
| | __LINE__, __FILE__); \ |
| | exit(-1); \ |
| | } \ |
| | } |
| |
|
| |
|
| | #define FREE(PTR) { free((PTR)); (PTR) = NULL; } |
| | #endif |
| |
|
| |
|
| | |
| |
|
| | extern PlyFile *ply_write(FILE *, int, const char **, int); |
| | extern PlyFile *ply_open_for_writing(char *, int, const char **, int, float *); |
| | extern void ply_describe_element(PlyFile *, char *, int, int, PlyProperty *); |
| | extern void ply_describe_property(PlyFile *, const char *, PlyProperty *); |
| | extern void ply_element_count(PlyFile *, const char *, int); |
| | extern void ply_header_complete(PlyFile *); |
| | extern void ply_put_element_setup(PlyFile *, const char *); |
| | extern void ply_put_element(PlyFile *, void *); |
| | extern void ply_put_comment(PlyFile *, char *); |
| | extern void ply_put_obj_info(PlyFile *, char *); |
| | extern PlyFile *ply_read(FILE *, int *, char ***); |
| | extern PlyFile *ply_open_for_reading( char *, int *, char ***, int *, float *); |
| | extern PlyProperty **ply_get_element_description(PlyFile *, char *, int*, int*); |
| | extern void ply_get_element_setup( PlyFile *, char *, int, PlyProperty *); |
| | extern int ply_get_property(PlyFile *, char *, PlyProperty *); |
| | extern PlyOtherProp *ply_get_other_properties(PlyFile *, char *, int); |
| | extern void ply_get_element(PlyFile *, void *); |
| | extern char **ply_get_comments(PlyFile *, int *); |
| | extern char **ply_get_obj_info(PlyFile *, int *); |
| | extern void ply_close(PlyFile *); |
| | extern void ply_get_info(PlyFile *, float *, int *); |
| | extern PlyOtherElems *ply_get_other_element (PlyFile *, char *, int); |
| | extern void ply_describe_other_elements ( PlyFile *, PlyOtherElems *); |
| | extern void ply_put_other_elements (PlyFile *); |
| | extern void ply_free_other_elements (PlyOtherElems *); |
| | extern void ply_describe_other_properties(PlyFile *, PlyOtherProp *, int); |
| |
|
| | extern int equal_strings(const char *, const char *); |
| |
|
| | #ifdef __cplusplus |
| | } |
| | #endif |
| | #include "Geometry.h" |
| | #include <vector> |
| |
|
| | template< class Real > int PLYType( void ); |
| | template<> inline int PLYType< int >( void ){ return PLY_INT ; } |
| | template<> inline int PLYType< char >( void ){ return PLY_CHAR ; } |
| | template<> inline int PLYType< unsigned char >( void ){ return PLY_UCHAR ; } |
| | template<> inline int PLYType< float >( void ){ return PLY_FLOAT ; } |
| | template<> inline int PLYType< double >( void ){ return PLY_DOUBLE; } |
| | template< class Real > inline int PLYType( void ){ fprintf( stderr , "[ERROR] Unrecognized type\n" ) , exit( 0 ); } |
| |
|
| | typedef struct PlyFace |
| | { |
| | unsigned char nr_vertices; |
| | int *vertices; |
| | int segment; |
| | } PlyFace; |
| | static PlyProperty face_props[] = |
| | { |
| | { _strdup( "vertex_indices" ) , PLY_INT , PLY_INT , offsetof( PlyFace , vertices ) , 1 , PLY_UCHAR, PLY_UCHAR , offsetof(PlyFace,nr_vertices) }, |
| | }; |
| |
|
| |
|
| | |
| | |
| | |
| |
|
| | |
| | template< class Real > |
| | class PlyVertex |
| | { |
| | public: |
| | typedef PlyVertex Wrapper; |
| |
|
| | const static int ReadComponents=3; |
| | const static int WriteComponents=3; |
| | static PlyProperty ReadProperties[]; |
| | static PlyProperty WriteProperties[]; |
| |
|
| | Point3D< Real > point; |
| |
|
| | PlyVertex( void ) { ; } |
| | PlyVertex( Point3D< Real > p ) { point=p; } |
| | PlyVertex operator + ( PlyVertex p ) const { return PlyVertex( point+p.point ); } |
| | PlyVertex operator - ( PlyVertex p ) const { return PlyVertex( point-p.point ); } |
| | template< class _Real > PlyVertex operator * ( _Real s ) const { return PlyVertex( point*s ); } |
| | template< class _Real > PlyVertex operator / ( _Real s ) const { return PlyVertex( point/s ); } |
| | PlyVertex& operator += ( PlyVertex p ) { point += p.point ; return *this; } |
| | PlyVertex& operator -= ( PlyVertex p ) { point -= p.point ; return *this; } |
| | template< class _Real > PlyVertex& operator *= ( _Real s ) { point *= s ; return *this; } |
| | template< class _Real > PlyVertex& operator /= ( _Real s ) { point /= s ; return *this; } |
| | }; |
| | template< class Real , class _Real > PlyVertex< Real > operator * ( XForm4x4< _Real > xForm , PlyVertex< Real > v ) { return PlyVertex< Real >( xForm * v.point ); } |
| | template< class Real > PlyProperty PlyVertex< Real >::ReadProperties[]= |
| | { |
| | { _strdup( "x" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyVertex , point.coords[0] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "y" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyVertex , point.coords[1] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "z" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyVertex , point.coords[2] ) ) , 0 , 0 , 0 , 0 } |
| | }; |
| | template< class Real > PlyProperty PlyVertex< Real >::WriteProperties[]= |
| | { |
| | { _strdup( "x" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyVertex , point.coords[0] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "y" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyVertex , point.coords[1] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "z" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyVertex , point.coords[2] ) ) , 0 , 0 , 0 , 0 } |
| | }; |
| | template< class Real > |
| | class PlyValueVertex |
| | { |
| | public: |
| | typedef PlyValueVertex Wrapper; |
| |
|
| | const static int ReadComponents=4; |
| | const static int WriteComponents=4; |
| | static PlyProperty ReadProperties[]; |
| | static PlyProperty WriteProperties[]; |
| |
|
| | Point3D<Real> point; |
| | Real value; |
| |
|
| | PlyValueVertex( void ) : value( Real(0) ) { ; } |
| | PlyValueVertex( Point3D< Real > p , Real v ) : point(p) , value(v) { ; } |
| | PlyValueVertex operator + ( PlyValueVertex p ) const { return PlyValueVertex( point+p.point , value+p.value ); } |
| | PlyValueVertex operator - ( PlyValueVertex p ) const { return PlyValueVertex( point-p.value , value-p.value ); } |
| | template< class _Real > PlyValueVertex operator * ( _Real s ) const { return PlyValueVertex( point*s , Real(value*s) ); } |
| | template< class _Real > PlyValueVertex operator / ( _Real s ) const { return PlyValueVertex( point/s , Real(value/s) ); } |
| | PlyValueVertex& operator += ( PlyValueVertex p ) { point += p.point , value += p.value ; return *this; } |
| | PlyValueVertex& operator -= ( PlyValueVertex p ) { point -= p.point , value -= p.value ; return *this; } |
| | template< class _Real > PlyValueVertex& operator *= ( _Real s ) { point *= s , value *= Real(s) ; return *this; } |
| | template< class _Real > PlyValueVertex& operator /= ( _Real s ) { point /= s , value /= Real(s) ; return *this; } |
| | }; |
| | template< class Real , class _Real > PlyValueVertex< Real > operator * ( XForm4x4< _Real > xForm , PlyValueVertex< Real > v ) { return PlyValueVertex< Real >( xForm * v.point , v.value ); } |
| | template< class Real > PlyProperty PlyValueVertex< Real >::ReadProperties[]= |
| | { |
| | { _strdup( "x" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyValueVertex , point.coords[0] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "y" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyValueVertex , point.coords[1] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "z" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyValueVertex , point.coords[2] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "value" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyValueVertex , value ) ) , 0 , 0 , 0 , 0 } |
| | }; |
| | template< class Real > PlyProperty PlyValueVertex< Real >::WriteProperties[]= |
| | { |
| | { _strdup( "x" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyValueVertex , point.coords[0] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "y" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyValueVertex , point.coords[1] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "z" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyValueVertex , point.coords[2] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "value" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyValueVertex , value ) ) , 0 , 0 , 0 , 0 } |
| | }; |
| | template< class Real > |
| | class PlyOrientedVertex |
| | { |
| | public: |
| | typedef PlyOrientedVertex Wrapper; |
| |
|
| | const static int ReadComponents=6; |
| | const static int WriteComponents=6; |
| | static PlyProperty ReadProperties[]; |
| | static PlyProperty WriteProperties[]; |
| |
|
| | Point3D<Real> point , normal; |
| |
|
| | PlyOrientedVertex( void ) { ; } |
| | PlyOrientedVertex( Point3D< Real > p , Point3D< Real > n ) : point(p) , normal(n) { ; } |
| | PlyOrientedVertex operator + ( PlyOrientedVertex p ) const { return PlyOrientedVertex( point+p.point , normal+p.normal ); } |
| | PlyOrientedVertex operator - ( PlyOrientedVertex p ) const { return PlyOrientedVertex( point-p.value , normal-p.normal ); } |
| | template< class _Real > PlyOrientedVertex operator * ( _Real s ) const { return PlyOrientedVertex( point*s , normal*s ); } |
| | template< class _Real > PlyOrientedVertex operator / ( _Real s ) const { return PlyOrientedVertex( point/s , normal/s ); } |
| | PlyOrientedVertex& operator += ( PlyOrientedVertex p ) { point += p.point , normal += p.normal ; return *this; } |
| | PlyOrientedVertex& operator -= ( PlyOrientedVertex p ) { point -= p.point , normal -= p.normal ; return *this; } |
| | template< class _Real > PlyOrientedVertex& operator *= ( _Real s ) { point *= s , normal *= s ; return *this; } |
| | template< class _Real > PlyOrientedVertex& operator /= ( _Real s ) { point /= s , normal /= s ; return *this; } |
| | }; |
| | template< class Real , class _Real > PlyOrientedVertex< Real > operator * ( XForm4x4< _Real > xForm , PlyOrientedVertex< Real > v ) { return PlyOrientedVertex< Real >( xForm * v.point , xForm.inverse().transpose() * v.normal ); } |
| | template< class Real > PlyProperty PlyOrientedVertex< Real >::ReadProperties[]= |
| | { |
| | { _strdup( "x" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyOrientedVertex , point.coords[0] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "y" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyOrientedVertex , point.coords[1] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "z" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyOrientedVertex , point.coords[2] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "nx" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyOrientedVertex , normal.coords[0] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "ny" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyOrientedVertex , normal.coords[1] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "nz" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyOrientedVertex , normal.coords[2] ) ) , 0 , 0 , 0 , 0 } |
| | }; |
| | template< class Real > PlyProperty PlyOrientedVertex< Real >::WriteProperties[]= |
| | { |
| | { _strdup( "x" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyOrientedVertex , point.coords[0] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "y" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyOrientedVertex , point.coords[1] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "z" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyOrientedVertex , point.coords[2] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "nx" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyOrientedVertex , normal.coords[0] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "ny" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyOrientedVertex , normal.coords[1] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "nz" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyOrientedVertex , normal.coords[2] ) ) , 0 , 0 , 0 , 0 } |
| | }; |
| | template< class Real > |
| | class PlyColorVertex |
| | { |
| | public: |
| | struct _PlyColorVertex |
| | { |
| | Point3D< Real > point , color; |
| | _PlyColorVertex( void ) { ; } |
| | _PlyColorVertex( Point3D< Real > p , Point3D< Real > c ) : point(p) , color(c) { ; } |
| | _PlyColorVertex( PlyColorVertex< Real > p ){ point = p.point ; for( int c=0 ; c<3 ; c++ ) color[c] = (Real) p.color[c]; } |
| | operator PlyColorVertex< Real > () |
| | { |
| | PlyColorVertex< Real > p; |
| | p.point = point; |
| | for( int c=0 ; c<3 ; c++ ) p.color[c] = (unsigned char)std::max< int >( 0 , std::min< int >( 255 , (int)( color[c]+0.5 ) ) ); |
| | return p; |
| | } |
| |
|
| | _PlyColorVertex operator + ( _PlyColorVertex p ) const { return _PlyColorVertex( point+p.point , color+p.color ); } |
| | _PlyColorVertex operator - ( _PlyColorVertex p ) const { return _PlyColorVertex( point-p.value , color-p.color ); } |
| | template< class _Real > _PlyColorVertex operator * ( _Real s ) const { return _PlyColorVertex( point*s , color*s ); } |
| | template< class _Real > _PlyColorVertex operator / ( _Real s ) const { return _PlyColorVertex( point/s , color/s ); } |
| | _PlyColorVertex& operator += ( _PlyColorVertex p ) { point += p.point , color += p.color ; return *this; } |
| | _PlyColorVertex& operator -= ( _PlyColorVertex p ) { point -= p.point , color -= p.color ; return *this; } |
| | template< class _Real > _PlyColorVertex& operator *= ( _Real s ) { point *= s , color *= s ; return *this; } |
| | template< class _Real > _PlyColorVertex& operator /= ( _Real s ) { point /= s , color /= s ; return *this; } |
| | }; |
| |
|
| | typedef _PlyColorVertex Wrapper; |
| |
|
| | const static int ReadComponents=9; |
| | const static int WriteComponents=6; |
| | static PlyProperty ReadProperties[]; |
| | static PlyProperty WriteProperties[]; |
| |
|
| | Point3D< Real > point; |
| | unsigned char color[3]; |
| |
|
| | operator Point3D< Real >& (){ return point; } |
| | operator const Point3D< Real >& () const { return point; } |
| | PlyColorVertex( void ) { point.coords[0] = point.coords[1] = point.coords[2] = 0 , color[0] = color[1] = color[2] = 0; } |
| | PlyColorVertex( const Point3D<Real>& p ) { point=p; } |
| | PlyColorVertex( const Point3D< Real >& p , const unsigned char c[3] ) { point = p , color[0] = c[0] , color[1] = c[1] , color[2] = c[2]; } |
| | }; |
| | template< class Real , class _Real > PlyColorVertex< Real > operator * ( XForm4x4< _Real > xForm , PlyColorVertex< Real > v ) { return PlyColorVertex< Real >( xForm * v.point , v.color ); } |
| |
|
| | template< class Real > PlyProperty PlyColorVertex< Real >::ReadProperties[]= |
| | { |
| | { _strdup( "x" ) , PLYType< Real >() , PLYType< Real >(), int( offsetof( PlyColorVertex , point.coords[0] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "y" ) , PLYType< Real >() , PLYType< Real >(), int( offsetof( PlyColorVertex , point.coords[1] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "z" ) , PLYType< Real >() , PLYType< Real >(), int( offsetof( PlyColorVertex , point.coords[2] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "red" ) , PLYType< unsigned char >() , PLYType< unsigned char >(), int( offsetof( PlyColorVertex , color[0] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "green" ) , PLYType< unsigned char >() , PLYType< unsigned char >(), int( offsetof( PlyColorVertex , color[1] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "blue" ) , PLYType< unsigned char >() , PLYType< unsigned char >(), int( offsetof( PlyColorVertex , color[2] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "r" ) , PLYType< unsigned char >() , PLYType< unsigned char >(), int( offsetof( PlyColorVertex , color[0] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "g" ) , PLYType< unsigned char >() , PLYType< unsigned char >(), int( offsetof( PlyColorVertex , color[1] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "b" ) , PLYType< unsigned char >() , PLYType< unsigned char >(), int( offsetof( PlyColorVertex , color[2] ) ) , 0 , 0 , 0 , 0 } |
| | }; |
| | template< class Real > PlyProperty PlyColorVertex< Real >::WriteProperties[]= |
| | { |
| | { _strdup( "x" ) , PLYType< Real >() , PLYType< Real >(), int( offsetof( PlyColorVertex , point.coords[0] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "y" ) , PLYType< Real >() , PLYType< Real >(), int( offsetof( PlyColorVertex , point.coords[1] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "z" ) , PLYType< Real >() , PLYType< Real >(), int( offsetof( PlyColorVertex , point.coords[2] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "red" ) , PLYType< unsigned char >() , PLYType< unsigned char >(), int( offsetof( PlyColorVertex , color[0] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "green" ) , PLYType< unsigned char >() , PLYType< unsigned char >(), int( offsetof( PlyColorVertex , color[1] ) ) , 0 , 0 , 0 , 0 }, |
| | { _strdup( "blue" ) , PLYType< unsigned char >() , PLYType< unsigned char >(), int( offsetof( PlyColorVertex , color[2] ) ) , 0 , 0 , 0 , 0 } |
| | }; |
| | template< class Real > |
| | class PlyColorAndValueVertex |
| | { |
| | public: |
| | struct _PlyColorAndValueVertex |
| | { |
| | Point3D< Real > point , color; |
| | Real value; |
| | _PlyColorAndValueVertex( void ) : value(0) { ; } |
| | _PlyColorAndValueVertex( Point3D< Real > p , Point3D< Real > c , Real v ) : point(p) , color(c) , value(v) { ; } |
| | _PlyColorAndValueVertex( PlyColorAndValueVertex< Real > p ){ point = p.point ; for( int c=0 ; c<3 ; c++ ) color[c] = (Real) p.color[c] ; value = p.value; } |
| | operator PlyColorAndValueVertex< Real > () |
| | { |
| | PlyColorAndValueVertex< Real > p; |
| | p.point = point; |
| | for( int c=0 ; c<3 ; c++ ) p.color[c] = (unsigned char)std::max< int >( 0 , std::min< int >( 255 , (int)( color[c]+0.5 ) ) ); |
| | p.value = value; |
| | return p; |
| | } |
| |
|
| | _PlyColorAndValueVertex operator + ( _PlyColorAndValueVertex p ) const { return _PlyColorAndValueVertex( point+p.point , color+p.color , value+p.value ); } |
| | _PlyColorAndValueVertex operator - ( _PlyColorAndValueVertex p ) const { return _PlyColorAndValueVertex( point-p.value , color-p.color , value+p.value ); } |
| | template< class _Real > _PlyColorAndValueVertex operator * ( _Real s ) const { return _PlyColorAndValueVertex( point*s , color*s , value*s ); } |
| | template< class _Real > _PlyColorAndValueVertex operator / ( _Real s ) const { return _PlyColorAndValueVertex( point/s , color/s , value/s ); } |
| | _PlyColorAndValueVertex& operator += ( _PlyColorAndValueVertex p ) { point += p.point , color += p.color , value += p.value ; return *this; } |
| | _PlyColorAndValueVertex& operator -= ( _PlyColorAndValueVertex p ) { point -= p.point , color -= p.color , value -= p.value ; return *this; } |
| | template< class _Real > _PlyColorAndValueVertex& operator *= ( _Real s ) { point *= s , color *= s , value *= (Real)s ; return *this; } |
| | template< class _Real > _PlyColorAndValueVertex& operator /= ( _Real s ) { point /= s , color /= s , value /= (Real)s ; return *this; } |
| | }; |
| |
|
| | typedef _PlyColorAndValueVertex Wrapper; |
| |
|
| | const static int ReadComponents=10; |
| | const static int WriteComponents=7; |
| | static PlyProperty ReadProperties[]; |
| | static PlyProperty WriteProperties[]; |
| |
|
| | Point3D< Real > point; |
| | unsigned char color[3]; |
| | Real value; |
| |
|
| | operator Point3D< Real >& (){ return point; } |
| | operator const Point3D< Real >& () const { return point; } |
| | PlyColorAndValueVertex( void ) { point.coords[0] = point.coords[1] = point.coords[2] = (Real)0 , color[0] = color[1] = color[2] = 0 , value = (Real)0; } |
| | PlyColorAndValueVertex( const Point3D< Real >& p ) { point=p; } |
| | PlyColorAndValueVertex( const Point3D< Real >& p , const unsigned char c[3] , Real v) { point = p , color[0] = c[0] , color[1] = c[1] , color[2] = c[2] , value = v; } |
| | }; |
| | template< class Real , class _Real > PlyColorAndValueVertex< Real > operator * ( XForm4x4< _Real > xForm , PlyColorAndValueVertex< Real > v ) { return PlyColorAndValueVertex< Real >( xForm * v.point , v.color , v.value ); } |
| | template< class Real > PlyProperty PlyColorAndValueVertex< Real >::ReadProperties[]= |
| | { |
| | { _strdup( "x" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyColorAndValueVertex , point.coords[0] ) ) , 0 , 0 , 0 , 0 } , |
| | { _strdup( "y" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyColorAndValueVertex , point.coords[1] ) ) , 0 , 0 , 0 , 0 } , |
| | { _strdup( "z" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyColorAndValueVertex , point.coords[2] ) ) , 0 , 0 , 0 , 0 } , |
| | { _strdup( "value" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyColorAndValueVertex , value ) ) , 0 , 0 , 0 , 0 } , |
| | { _strdup( "red" ) , PLYType< unsigned char >() , PLYType< unsigned char >() , int( offsetof( PlyColorAndValueVertex , color[0] ) ) , 0 , 0 , 0 , 0 } , |
| | { _strdup( "green" ) , PLYType< unsigned char >() , PLYType< unsigned char >() , int( offsetof( PlyColorAndValueVertex , color[1] ) ) , 0 , 0 , 0 , 0 } , |
| | { _strdup( "blue" ) , PLYType< unsigned char >() , PLYType< unsigned char >() , int( offsetof( PlyColorAndValueVertex , color[2] ) ) , 0 , 0 , 0 , 0 } , |
| | { _strdup( "r" ) , PLYType< unsigned char >() , PLYType< unsigned char >() , int( offsetof( PlyColorAndValueVertex , color[0] ) ) , 0 , 0 , 0 , 0 } , |
| | { _strdup( "g" ) , PLYType< unsigned char >() , PLYType< unsigned char >() , int( offsetof( PlyColorAndValueVertex , color[1] ) ) , 0 , 0 , 0 , 0 } , |
| | { _strdup( "b" ) , PLYType< unsigned char >() , PLYType< unsigned char >() , int( offsetof( PlyColorAndValueVertex , color[2] ) ) , 0 , 0 , 0 , 0 } |
| | }; |
| | template< class Real > PlyProperty PlyColorAndValueVertex< Real >::WriteProperties[]= |
| | { |
| | { _strdup( "x" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyColorAndValueVertex , point.coords[0] ) ) , 0 , 0 , 0 , 0 } , |
| | { _strdup( "y" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyColorAndValueVertex , point.coords[1] ) ) , 0 , 0 , 0 , 0 } , |
| | { _strdup( "z" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyColorAndValueVertex , point.coords[2] ) ) , 0 , 0 , 0 , 0 } , |
| | { _strdup( "value" ) , PLYType< Real >() , PLYType< Real >() , int( offsetof( PlyColorAndValueVertex , value ) ) , 0 , 0 , 0 , 0 } , |
| | { _strdup( "red" ) , PLYType< unsigned char >() , PLYType< unsigned char >() , int( offsetof( PlyColorAndValueVertex , color[0] ) ) , 0 , 0 , 0 , 0 } , |
| | { _strdup( "green" ) , PLYType< unsigned char >() , PLYType< unsigned char >() , int( offsetof( PlyColorAndValueVertex , color[1] ) ) , 0 , 0 , 0 , 0 } , |
| | { _strdup( "blue" ) , PLYType< unsigned char >() , PLYType< unsigned char >() , int( offsetof( PlyColorAndValueVertex , color[2] ) ) , 0 , 0 , 0 , 0 } |
| | }; |
| |
|
| | template< class Vertex , class Real > |
| | int PlyWritePolygons( char* fileName , CoredMeshData< Vertex >* mesh , int file_type , const Point3D< float >& translate , float scale , char** comments=NULL , int commentNum=0 , XForm4x4< Real > xForm=XForm4x4< Real >::Identity() ); |
| |
|
| | template< class Vertex , class Real > |
| | int PlyWritePolygons( char* fileName , CoredMeshData< Vertex >* mesh , int file_type , char** comments=NULL , int commentNum=0 , XForm4x4< Real > xForm=XForm4x4< Real >::Identity() ); |
| |
|
| | inline bool PlyReadHeader( char* fileName , PlyProperty* properties , int propertyNum , bool* readFlags , int& file_type ) |
| | { |
| | int nr_elems; |
| | char **elist; |
| | float version; |
| | PlyFile* ply; |
| | char* elem_name; |
| | int num_elems; |
| | int nr_props; |
| | PlyProperty** plist; |
| |
|
| | ply = ply_open_for_reading( fileName , &nr_elems , &elist , &file_type , &version ); |
| | if( !ply ) return false; |
| |
|
| | for( int i=0 ; i<nr_elems ; i++ ) |
| | { |
| | elem_name = elist[i]; |
| | plist = ply_get_element_description( ply , elem_name , &num_elems , &nr_props ); |
| | if( !plist ) |
| | { |
| | for( int i=0 ; i<nr_elems ; i++ ) |
| | { |
| | free( ply->elems[i]->name ); |
| | free( ply->elems[i]->store_prop ); |
| | for( int j=0 ; j<ply->elems[i]->nprops ; j++ ) |
| | { |
| | free( ply->elems[i]->props[j]->name ); |
| | free( ply->elems[i]->props[j] ); |
| | } |
| | free( ply->elems[i]->props ); |
| | } |
| | for( int i=0 ; i<nr_elems ; i++ ) free( ply->elems[i] ); |
| | free( ply->elems ); |
| | for( int i=0 ; i<ply->num_comments ; i++ ) free( ply->comments[i] ); |
| | free( ply->comments ); |
| | for( int i=0 ; i<ply->num_obj_info ; i++ ) free( ply->obj_info[i] ); |
| | free( ply->obj_info ); |
| | ply_free_other_elements( ply->other_elems ); |
| | |
| | for( int i=0 ; i<nr_elems ; i++ ) free( elist[i] ); |
| | free( elist ); |
| | ply_close( ply ); |
| | return 0; |
| | } |
| | if( equal_strings( "vertex" , elem_name ) ) |
| | for( int i=0 ; i<propertyNum ; i++ ) |
| | if( readFlags ) readFlags[i] = ply_get_property( ply , elem_name , &properties[i] )!=0; |
| |
|
| | for( int j=0 ; j<nr_props ; j++ ) |
| | { |
| | free( plist[j]->name ); |
| | free( plist[j] ); |
| | } |
| | free( plist ); |
| | } |
| | |
| | for( int i=0 ; i<nr_elems ; i++ ) |
| | { |
| | free( ply->elems[i]->name ); |
| | free( ply->elems[i]->store_prop ); |
| | for( int j=0 ; j<ply->elems[i]->nprops ; j++ ) |
| | { |
| | free( ply->elems[i]->props[j]->name ); |
| | free( ply->elems[i]->props[j] ); |
| | } |
| | if( ply->elems[i]->props && ply->elems[i]->nprops ) free(ply->elems[i]->props); |
| | } |
| | for( int i=0 ; i<nr_elems ; i++ ) free(ply->elems[i]); |
| | free( ply->elems) ; |
| | for( int i=0 ; i<ply->num_comments ; i++ ) free( ply->comments[i] ); |
| | free( ply->comments ); |
| | for( int i=0 ; i<ply->num_obj_info ; i++ ) free( ply->obj_info[i] ); |
| | free( ply->obj_info ); |
| | ply_free_other_elements(ply->other_elems); |
| | |
| | |
| | for( int i=0 ; i<nr_elems ; i++ ) free( elist[i] ); |
| | free( elist ); |
| | ply_close( ply ); |
| | return true; |
| | } |
| | inline bool PlyReadHeader( char* fileName , PlyProperty* properties , int propertyNum , bool* readFlags ) |
| | { |
| | int file_type; |
| | return PlyReadHeader( fileName , properties , propertyNum , readFlags , file_type ); |
| | } |
| |
|
| |
|
| | template<class Vertex> |
| | int PlyReadPolygons(char* fileName, |
| | std::vector<Vertex>& vertices,std::vector<std::vector<int> >& polygons, |
| | PlyProperty* properties,int propertyNum, |
| | int& file_type, |
| | char*** comments=NULL,int* commentNum=NULL , bool* readFlags=NULL ); |
| |
|
| | template<class Vertex> |
| | int PlyWritePolygons(char* fileName, |
| | const std::vector<Vertex>& vertices,const std::vector<std::vector<int> >& polygons, |
| | PlyProperty* properties,int propertyNum, |
| | int file_type, |
| | char** comments=NULL,const int& commentNum=0); |
| |
|
| | template<class Vertex> |
| | int PlyWritePolygons(char* fileName, |
| | const std::vector<Vertex>& vertices , const std::vector< std::vector< int > >& polygons, |
| | PlyProperty* properties,int propertyNum, |
| | int file_type, |
| | char** comments,const int& commentNum) |
| | { |
| | int nr_vertices=int(vertices.size()); |
| | int nr_faces=int(polygons.size()); |
| | float version; |
| | const char *elem_names[] = { "vertex" , "face" }; |
| | PlyFile *ply = ply_open_for_writing( fileName , 2 , elem_names , file_type , &version ); |
| | if (!ply){return 0;} |
| | |
| | |
| | |
| | |
| | ply_element_count(ply, "vertex", nr_vertices); |
| | for(int i=0;i<propertyNum;i++) |
| | ply_describe_property(ply, "vertex", &properties[i]); |
| | |
| | ply_element_count(ply, "face", nr_faces); |
| | ply_describe_property(ply, "face", &face_props[0]); |
| | |
| | |
| | if(comments && commentNum) |
| | for(int i=0;i<commentNum;i++) |
| | ply_put_comment(ply,comments[i]); |
| |
|
| | ply_header_complete(ply); |
| | |
| | |
| | ply_put_element_setup(ply, "vertex"); |
| | for (int i=0; i < int(vertices.size()); i++) |
| | ply_put_element(ply, (void *) &vertices[i]); |
| |
|
| | |
| | PlyFace ply_face; |
| | int maxFaceVerts=3; |
| | ply_face.nr_vertices = 3; |
| | ply_face.vertices = new int[3]; |
| |
|
| | ply_put_element_setup(ply, "face"); |
| | for (int i=0; i < nr_faces; i++) |
| | { |
| | if(int(polygons[i].size())>maxFaceVerts) |
| | { |
| | delete[] ply_face.vertices; |
| | maxFaceVerts=int(polygons[i].size()); |
| | ply_face.vertices=new int[maxFaceVerts]; |
| | } |
| | ply_face.nr_vertices=int(polygons[i].size()); |
| | for(int j=0;j<ply_face.nr_vertices;j++) |
| | ply_face.vertices[j]=polygons[i][j]; |
| | ply_put_element(ply, (void *) &ply_face); |
| | } |
| |
|
| | delete[] ply_face.vertices; |
| | ply_close(ply); |
| | return 1; |
| | } |
| | template<class Vertex> |
| | int PlyReadPolygons(char* fileName, |
| | std::vector<Vertex>& vertices , std::vector<std::vector<int> >& polygons , |
| | PlyProperty* properties , int propertyNum , |
| | int& file_type , |
| | char*** comments , int* commentNum , bool* readFlags ) |
| | { |
| | int nr_elems; |
| | char **elist; |
| | float version; |
| | int i,j,k; |
| | PlyFile* ply; |
| | char* elem_name; |
| | int num_elems; |
| | int nr_props; |
| | PlyProperty** plist; |
| | PlyFace ply_face; |
| |
|
| | ply = ply_open_for_reading(fileName, &nr_elems, &elist, &file_type, &version); |
| | if(!ply) return 0; |
| |
|
| | if(comments) |
| | { |
| | (*comments)=new char*[*commentNum+ply->num_comments]; |
| | for(int i=0;i<ply->num_comments;i++) |
| | (*comments)[i]=_strdup(ply->comments[i]); |
| | *commentNum=ply->num_comments; |
| | } |
| |
|
| | for (i=0; i < nr_elems; i++) { |
| | elem_name = elist[i]; |
| | plist = ply_get_element_description(ply, elem_name, &num_elems, &nr_props); |
| | if(!plist) |
| | { |
| | for(i=0;i<nr_elems;i++){ |
| | free(ply->elems[i]->name); |
| | free(ply->elems[i]->store_prop); |
| | for(j=0;j<ply->elems[i]->nprops;j++){ |
| | free(ply->elems[i]->props[j]->name); |
| | free(ply->elems[i]->props[j]); |
| | } |
| | free(ply->elems[i]->props); |
| | } |
| | for(i=0;i<nr_elems;i++){free(ply->elems[i]);} |
| | free(ply->elems); |
| | for(i=0;i<ply->num_comments;i++){free(ply->comments[i]);} |
| | free(ply->comments); |
| | for(i=0;i<ply->num_obj_info;i++){free(ply->obj_info[i]);} |
| | free(ply->obj_info); |
| | ply_free_other_elements (ply->other_elems); |
| | |
| | for(i=0;i<nr_elems;i++){free(elist[i]);} |
| | free(elist); |
| | ply_close(ply); |
| | return 0; |
| | } |
| | if (equal_strings("vertex", elem_name)) |
| | { |
| | for( int i=0 ; i<propertyNum ; i++) |
| | { |
| | int hasProperty = ply_get_property(ply,elem_name,&properties[i]); |
| | if( readFlags ) readFlags[i] = (hasProperty!=0); |
| | } |
| | vertices.resize(num_elems); |
| | for (j=0; j < num_elems; j++) ply_get_element (ply, (void *) &vertices[j]); |
| | } |
| | else if (equal_strings("face", elem_name)) |
| | { |
| | ply_get_property (ply, elem_name, &face_props[0]); |
| | polygons.resize(num_elems); |
| | for (j=0; j < num_elems; j++) |
| | { |
| | ply_get_element (ply, (void *) &ply_face); |
| | polygons[j].resize(ply_face.nr_vertices); |
| | for(k=0;k<ply_face.nr_vertices;k++) polygons[j][k]=ply_face.vertices[k]; |
| | delete[] ply_face.vertices; |
| | } |
| | } |
| | else{ply_get_other_element (ply, elem_name, num_elems);} |
| |
|
| | for(j=0;j<nr_props;j++){ |
| | free(plist[j]->name); |
| | free(plist[j]); |
| | } |
| | free(plist); |
| | } |
| | |
| | for(i=0;i<nr_elems;i++){ |
| | free(ply->elems[i]->name); |
| | free(ply->elems[i]->store_prop); |
| | for(j=0;j<ply->elems[i]->nprops;j++){ |
| | free(ply->elems[i]->props[j]->name); |
| | free(ply->elems[i]->props[j]); |
| | } |
| | if(ply->elems[i]->props && ply->elems[i]->nprops){free(ply->elems[i]->props);} |
| | } |
| | for(i=0;i<nr_elems;i++){free(ply->elems[i]);} |
| | free(ply->elems); |
| | for(i=0;i<ply->num_comments;i++){free(ply->comments[i]);} |
| | free(ply->comments); |
| | for(i=0;i<ply->num_obj_info;i++){free(ply->obj_info[i]);} |
| | free(ply->obj_info); |
| | ply_free_other_elements (ply->other_elems); |
| | |
| | |
| | for(i=0;i<nr_elems;i++){free(elist[i]);} |
| | free(elist); |
| | ply_close(ply); |
| | return 1; |
| | } |
| |
|
| | template< class Vertex , class Real > |
| | int PlyWritePolygons( char* fileName , CoredMeshData< Vertex >* mesh , int file_type , const Point3D<float>& translate , float scale , char** comments , int commentNum , XForm4x4< Real > xForm ) |
| | { |
| | int i; |
| | int nr_vertices=int(mesh->outOfCorePointCount()+mesh->inCorePoints.size()); |
| | int nr_faces=mesh->polygonCount(); |
| | float version; |
| | const char *elem_names[] = { "vertex" , "face" }; |
| | PlyFile *ply = ply_open_for_writing( fileName , 2 , elem_names , file_type , &version ); |
| | if( !ply ) return 0; |
| |
|
| | mesh->resetIterator(); |
| | |
| | |
| | |
| | |
| | ply_element_count( ply , "vertex" , nr_vertices ); |
| | for( int i=0 ; i<Vertex::Components ; i++ ) ply_describe_property( ply , "vertex" , &Vertex::Properties[i] ); |
| | |
| | ply_element_count( ply , "face" , nr_faces ); |
| | ply_describe_property( ply , "face" , &face_props[0] ); |
| | |
| | |
| | for( i=0 ; i<commentNum ; i++ ) ply_put_comment( ply , comments[i] ); |
| |
|
| | ply_header_complete( ply ); |
| | |
| | |
| | ply_put_element_setup( ply , "vertex" ); |
| | for( i=0 ; i<int( mesh->inCorePoints.size() ) ; i++ ) |
| | { |
| | Vertex vertex = xForm * ( mesh->inCorePoints[i] * scale + translate ); |
| | ply_put_element(ply, (void *) &vertex); |
| | } |
| | for( i=0; i<mesh->outOfCorePointCount() ; i++ ) |
| | { |
| | Vertex vertex; |
| | mesh->nextOutOfCorePoint( vertex ); |
| | vertex = xForm * ( vertex * scale +translate ); |
| | ply_put_element(ply, (void *) &vertex); |
| | } |
| | |
| | |
| | std::vector< CoredVertexIndex > polygon; |
| | ply_put_element_setup( ply , "face" ); |
| | for( i=0 ; i<nr_faces ; i++ ) |
| | { |
| | |
| | |
| | |
| | PlyFace ply_face; |
| | mesh->nextPolygon( polygon ); |
| | ply_face.nr_vertices = int( polygon.size() ); |
| | ply_face.vertices = new int[ polygon.size() ]; |
| | for( int i=0 ; i<int(polygon.size()) ; i++ ) |
| | if( polygon[i].inCore ) ply_face.vertices[i] = polygon[i].idx; |
| | else ply_face.vertices[i] = polygon[i].idx + int( mesh->inCorePoints.size() ); |
| | ply_put_element( ply, (void *) &ply_face ); |
| | delete[] ply_face.vertices; |
| | } |
| | |
| | ply_close( ply ); |
| | return 1; |
| | } |
| | template< class Vertex , class Real > |
| | int PlyWritePolygons( char* fileName , CoredMeshData< Vertex >* mesh , int file_type , char** comments , int commentNum , XForm4x4< Real > xForm ) |
| | { |
| | int i; |
| | int nr_vertices=int(mesh->outOfCorePointCount()+mesh->inCorePoints.size()); |
| | int nr_faces=mesh->polygonCount(); |
| | float version; |
| | const char *elem_names[] = { "vertex" , "face" }; |
| | PlyFile *ply = ply_open_for_writing( fileName , 2 , elem_names , file_type , &version ); |
| | if( !ply ) return 0; |
| |
|
| | mesh->resetIterator(); |
| | |
| | |
| | |
| | |
| | ply_element_count( ply , "vertex" , nr_vertices ); |
| | for( int i=0 ; i<Vertex::WriteComponents ; i++ ) ply_describe_property( ply , "vertex" , &Vertex::WriteProperties[i] ); |
| | |
| | ply_element_count( ply , "face" , nr_faces ); |
| | ply_describe_property( ply , "face" , &face_props[0] ); |
| | |
| | |
| | for( i=0 ; i<commentNum ; i++ ) ply_put_comment( ply , comments[i] ); |
| |
|
| | ply_header_complete( ply ); |
| | |
| | |
| | ply_put_element_setup( ply , "vertex" ); |
| | for( i=0 ; i<int( mesh->inCorePoints.size() ) ; i++ ) |
| | { |
| | Vertex vertex = xForm * mesh->inCorePoints[i]; |
| | ply_put_element(ply, (void *) &vertex); |
| | } |
| | for( i=0; i<mesh->outOfCorePointCount() ; i++ ) |
| | { |
| | Vertex vertex; |
| | mesh->nextOutOfCorePoint( vertex ); |
| | vertex = xForm * ( vertex ); |
| | ply_put_element(ply, (void *) &vertex); |
| | } |
| | |
| | |
| | std::vector< CoredVertexIndex > polygon; |
| | ply_put_element_setup( ply , "face" ); |
| | for( i=0 ; i<nr_faces ; i++ ) |
| | { |
| | |
| | |
| | |
| | PlyFace ply_face; |
| | mesh->nextPolygon( polygon ); |
| | ply_face.nr_vertices = int( polygon.size() ); |
| | ply_face.vertices = new int[ polygon.size() ]; |
| | for( int i=0 ; i<int(polygon.size()) ; i++ ) |
| | if( polygon[i].inCore ) ply_face.vertices[i] = polygon[i].idx; |
| | else ply_face.vertices[i] = polygon[i].idx + int( mesh->inCorePoints.size() ); |
| | ply_put_element( ply, (void *) &ply_face ); |
| | delete[] ply_face.vertices; |
| | } |
| | |
| | ply_close( ply ); |
| | return 1; |
| | } |
| | inline int PlyDefaultFileType(void){return PLY_ASCII;} |
| |
|
| | #endif |
| |
|