diff --git a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/ConvexDecomposition.cpp b/convex_decomposition/ConvexDecomposition/ConvexDecomposition/ConvexDecomposition.cpp deleted file mode 100644 index 4198082..0000000 --- a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/ConvexDecomposition.cpp +++ /dev/null @@ -1,1065 +0,0 @@ -#include -#include -#include -#include - -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - - - -#include -#include - -#include "ConvexDecomposition.h" -#include "cd_vector.h" -#include "cd_hull.h" -#include "bestfit.h" -#include "planetri.h" -#include "vlookup.h" -#include "splitplane.h" -#include "meshvolume.h" -#include "concavity.h" -#include "bestfitobb.h" -#include "fitsphere.h" -#include "triangulate.h" -#include "float_math.h" - -#define MAKE_MESH 1 -#define CLOSE_FACE 0 - -static unsigned int MAXDEPTH=8; -static double CONCAVE_PERCENT=1.0f; -static double MERGE_PERCENT=2.0f; - - -using namespace ConvexDecomposition; - -typedef std::vector< unsigned int > UintVector; - -namespace ConvexDecomposition -{ - -class Edge -{ -public: - - Edge(unsigned int i1,unsigned int i2) - { - mE1 = i1; - mE2 = i2; - mUsed = false; - } - - unsigned int mE1; - unsigned int mE2; - bool mUsed; -}; - -typedef std::vector< Edge > EdgeVector; - -class FaceTri -{ -public: - FaceTri(void) { }; - - FaceTri(const double *vertices,unsigned int i1,unsigned int i2,unsigned int i3) - { - mP1.Set( &vertices[i1*3] ); - mP2.Set( &vertices[i2*3] ); - mP3.Set( &vertices[i3*3] ); - } - - Vector3d mP1; - Vector3d mP2; - Vector3d mP3; - Vector3d mNormal; - -}; - - - -class CHull -{ -public: - CHull(const ConvexResult &result) - { - mResult = new ConvexResult(result); - mVolume = computeMeshVolume( result.mHullVertices, result.mHullTcount, result.mHullIndices ); - - mDiagonal = getBoundingRegion( result.mHullVcount, result.mHullVertices, sizeof(double)*3, mMin, mMax ); - - double dx = mMax[0] - mMin[0]; - double dy = mMax[1] - mMin[1]; - double dz = mMax[2] - mMin[2]; - - dx*=0.1f; // inflate 1/10th on each edge - dy*=0.1f; // inflate 1/10th on each edge - dz*=0.1f; // inflate 1/10th on each edge - - mMin[0]-=dx; - mMin[1]-=dy; - mMin[2]-=dz; - - mMax[0]+=dx; - mMax[1]+=dy; - mMax[2]+=dz; - - - } - - ~CHull(void) - { - delete mResult; - } - - bool overlap(const CHull &h) const - { - return overlapAABB(mMin,mMax, h.mMin, h.mMax ); - } - - double mMin[3]; - double mMax[3]; - double mVolume; - double mDiagonal; // long edge.. - ConvexResult *mResult; -}; - -// Usage: std::sort( list.begin(), list.end(), StringSortRef() ); -class CHullSort -{ - public: - - bool operator()(const CHull *a,const CHull *b) const - { - return a->mVolume < b->mVolume; - } -}; - - -typedef std::vector< CHull * > CHullVector; - - -class ConvexBuilder : public ConvexDecompInterface -{ -public: - ConvexBuilder(ConvexDecompInterface *callback) - { - mCallback = callback; - }; - - ~ConvexBuilder(void) - { - CHullVector::iterator i; - for (i=mChulls.begin(); i!=mChulls.end(); ++i) - { - CHull *cr = (*i); - delete cr; - } - } - - bool isDuplicate(unsigned int i1,unsigned int i2,unsigned int i3, - unsigned int ci1,unsigned int ci2,unsigned int ci3) - { - unsigned int dcount = 0; - - assert( i1 != i2 && i1 != i3 && i2 != i3 ); - assert( ci1 != ci2 && ci1 != ci3 && ci2 != ci3 ); - - if ( i1 == ci1 || i1 == ci2 || i1 == ci3 ) dcount++; - if ( i2 == ci1 || i2 == ci2 || i2 == ci3 ) dcount++; - if ( i3 == ci1 || i3 == ci2 || i3 == ci3 ) dcount++; - - return dcount == 3; - } - - void getMesh(const ConvexResult &cr,VertexLookup vc) - { - unsigned int *src = cr.mHullIndices; - - for (unsigned int i=0; ioverlap(*b) ) return 0; // if their AABB's (with a little slop) don't overlap, then return. - - if ( MERGE_PERCENT < 0 ) return 0; - - assert( a->mVolume > 0 ); - assert( b->mVolume > 0 ); - - CHull *ret = 0; - - // ok..we are going to combine both meshes into a single mesh - // and then we are going to compute the concavity... - - VertexLookup vc = Vl_createVertexLookup(); - - getMesh( *a->mResult, vc); - getMesh( *b->mResult, vc); - - unsigned int vcount = Vl_getVcount(vc); - const double *vertices = Vl_getVertices(vc); - - HullResult hresult; - HullLibrary hl; - HullDesc desc; - - desc.SetHullFlag(QF_TRIANGLES); - - desc.mVcount = vcount; - desc.mVertices = vertices; - desc.mVertexStride = sizeof(double)*3; - - HullError hret = hl.CreateConvexHull(desc,hresult); - - if ( hret == QE_OK ) - { - - double combineVolume = computeMeshVolume( hresult.mOutputVertices, hresult.mNumFaces, hresult.mIndices ); - double sumVolume = a->mVolume + b->mVolume; - - double percent = (sumVolume*100) / combineVolume; - - if ( percent >= (100.0f-MERGE_PERCENT) ) - { - ConvexResult cr(hresult.mNumOutputVertices, hresult.mOutputVertices, hresult.mNumFaces, hresult.mIndices); - ret = new CHull(cr); - } - } - - - Vl_releaseVertexLookup(vc); - - return ret; - } - - bool combineHulls(void) - { - - bool combine = false; - - sortChulls(mChulls); // sort the convex hulls, largest volume to least... - - CHullVector output; // the output hulls... - - - CHullVector::iterator i; - - for (i=mChulls.begin(); i!=mChulls.end() && !combine; ++i) - { - CHull *cr = (*i); - - CHullVector::iterator j; - for (j=mChulls.begin(); j!=mChulls.end(); ++j) - { - CHull *match = (*j); - - if ( cr != match ) // don't try to merge a hull with itself, that be stoopid - { - - CHull *merge = canMerge(cr,match); // if we can merge these two.... - - if ( merge ) - { - - output.push_back(merge); - - - ++i; - while ( i != mChulls.end() ) - { - CHull *cr = (*i); - if ( cr != match ) - { - output.push_back(cr); - } - i++; - } - - delete cr; - delete match; - combine = true; - break; - } - } - } - - if ( combine ) - { - break; - } - else - { - output.push_back(cr); - } - - } - - if ( combine ) - { - mChulls.clear(); - mChulls = output; - output.clear(); - } - - - return combine; - } - - unsigned int process(const DecompDesc &desc) - { - - unsigned int ret = 0; - - MAXDEPTH = desc.mDepth; - CONCAVE_PERCENT = desc.mCpercent; - MERGE_PERCENT = desc.mPpercent; - - - doConvexDecomposition(desc.mVcount, desc.mVertices, desc.mTcount, desc.mIndices,this,0,0); - - - while ( combineHulls() ); // keep combinging hulls until I can't combine any more... - - CHullVector::iterator i; - for (i=mChulls.begin(); i!=mChulls.end(); ++i) - { - CHull *cr = (*i); - - // before we hand it back to the application, we need to regenerate the hull based on the - // limits given by the user. - - const ConvexResult &c = *cr->mResult; // the high resolution hull... - - HullResult result; - HullLibrary hl; - HullDesc hdesc; - - hdesc.SetHullFlag(QF_TRIANGLES); - - hdesc.mVcount = c.mHullVcount; - hdesc.mVertices = c.mHullVertices; - hdesc.mVertexStride = sizeof(double)*3; - hdesc.mMaxVertices = desc.mMaxVertices; // maximum number of vertices allowed in the output - - if ( desc.mSkinWidth > 0 ) - { - hdesc.mSkinWidth = desc.mSkinWidth; - hdesc.SetHullFlag(QF_SKIN_WIDTH); // do skin width computation. - } - - HullError ret = hl.CreateConvexHull(hdesc,result); - - if ( ret == QE_OK ) - { - ConvexResult r(result.mNumOutputVertices, result.mOutputVertices, result.mNumFaces, result.mIndices); - - r.mHullVolume = computeMeshVolume( result.mOutputVertices, result.mNumFaces, result.mIndices ); // the volume of the hull. - - mCallback->ConvexDecompResult(r); - } - - - delete cr; - } - - ret = mChulls.size(); - - mChulls.clear(); - - return ret; - } - - - virtual void ConvexDebugTri(const double *p1,const double *p2,const double *p3,unsigned int color) - { - mCallback->ConvexDebugTri(p1,p2,p3,color); - } - - virtual void ConvexDebugOBB(const double *sides, const double *matrix,unsigned int color) - { - mCallback->ConvexDebugOBB(sides,matrix,color); - } - virtual void ConvexDebugPoint(const double *p,double dist,unsigned int color) - { - mCallback->ConvexDebugPoint(p,dist,color); - } - - virtual void ConvexDebugBound(const double *bmin,const double *bmax,unsigned int color) - { - mCallback->ConvexDebugBound(bmin,bmax,color); - } - - virtual void ConvexDecompResult(ConvexResult &result) - { - CHull *ch = new CHull(result); - mChulls.push_back(ch); - } - - void sortChulls(CHullVector &hulls) - { - std::sort( hulls.begin(), hulls.end(), CHullSort() ); - } - -#define EPSILON 0.001f - - bool isEdge(const Vector3d &p,const double *plane) - { - bool ret = false; - - double dist = fabs(fm_distToPlane(plane,p.Ptr())); - - if ( dist < EPSILON ) - { - ret = true; - } - - - return ret; - } - - void addEdge(const Vector3d &p1,const Vector3d &p2,EdgeVector &edges,VertexLookup split,const double *plane) - { - if ( isEdge(p1,plane) && isEdge(p2,plane) ) - { - unsigned int i1 = Vl_getIndex(split,p1.Ptr()); - unsigned int i2 = Vl_getIndex(split,p2.Ptr()); - - bool found = false; - - for (unsigned int i=0; i &p1, - const Vector3d &p2, - const Vector3d &p3, - EdgeVector &edges, - VertexLookup split, - const double *plane) - { - bool ret = false; - - unsigned int i1 = Vl_getIndex(vl, p1.Ptr() ); - unsigned int i2 = Vl_getIndex(vl, p2.Ptr() ); - unsigned int i3 = Vl_getIndex(vl, p3.Ptr() ); - - // do *not* process degenerate triangles! - - if ( i1 != i2 && i1 != i3 && i2 != i3 ) - { - - list.push_back(i1); - list.push_back(i2); - list.push_back(i3); -#if CLOSE_FACE - addEdge(p1,p2,edges,split,plane); - addEdge(p2,p3,edges,split,plane); - addEdge(p3,p1,edges,split,plane); -#endif - ret = true; - } - return ret; - } - - void saveEdges(VertexLookup vl,const EdgeVector &edges,bool front) - { - char scratch[512]; - if ( front ) - { - static int fcount=1; - sprintf(scratch,"CD_Front%d.obj", fcount++); - } - else - { - static int bcount=1; - sprintf(scratch,"CD_Back%d.obj", bcount++); - } - - FILE *fph = fopen(scratch,"wb"); - if (fph) - { - unsigned int vcount = Vl_getVcount(vl); - const double *vertices = Vl_getVertices(vl); - fprintf(fph,"v 10 10 0\r\n"); - for (unsigned int i=0; i= 0 ) - { - double volume; - - double c = computeConcavity( vcount, vertices, tcount, indices, callback, plane, volume ); - - if ( depth == 0 ) - { - masterVolume = volume; - } - - double percent = (c*100.0f)/masterVolume; - - if ( percent > CONCAVE_PERCENT ) // if great than 5% of the total volume is concave, go ahead and keep splitting. - { - split = true; - } - } - else - { - split = computeSplitPlane(vcount,vertices,tcount,indices,callback,plane); - } - - } - - if ( depth >= MAXDEPTH || !split ) - { - - HullResult result; - HullLibrary hl; - HullDesc desc; - - desc.SetHullFlag(QF_TRIANGLES); - - desc.mVcount = vcount; - desc.mVertices = vertices; - desc.mVertexStride = sizeof(double)*3; - - HullError ret = hl.CreateConvexHull(desc,result); - - if ( ret == QE_OK ) - { - - ConvexResult r(result.mNumOutputVertices, result.mOutputVertices, result.mNumFaces, result.mIndices); - - - callback->ConvexDecompResult(r); - } - - - return; - } - - UintVector ifront; - UintVector iback; - - EdgeVector frontEdges; - EdgeVector backEdges; - - VertexLookup vfront = Vl_createVertexLookup(); - VertexLookup vback = Vl_createVertexLookup(); - - VertexLookup splitFront = Vl_createVertexLookup(); - VertexLookup splitBack = Vl_createVertexLookup(); - - - - if ( 1 ) - { - - // ok..now we are going to 'split' all of the input triangles against this plane! - - const unsigned int *source = indices; - - for (unsigned int i=0; i front[4]; - Vector3d back[4]; - - unsigned int fcount=0; - unsigned int bcount=0; - - PlaneTriResult result; - - result = planeTriIntersection(plane,t.mP1.Ptr(),sizeof(Vector3d),0.00001f,front[0].Ptr(),fcount,back[0].Ptr(),bcount ); - - if( fcount > 4 || bcount > 4 ) - { - result = planeTriIntersection(plane,t.mP1.Ptr(),sizeof(Vector3d),0.00001f,front[0].Ptr(),fcount,back[0].Ptr(),bcount ); - } - - switch ( result ) - { - case PTR_FRONT: - - assert( fcount == 3 ); - - #if MAKE_MESH - addTri( vfront, ifront, front[0], front[1], front[2], frontEdges, splitFront, plane ); - #endif - - break; - case PTR_BACK: - assert( bcount == 3 ); - - #if MAKE_MESH - addTri( vback, iback, back[0], back[1], back[2], backEdges, splitBack, plane ); - #endif - - break; - case PTR_SPLIT: - - assert( fcount >= 3 && fcount <= 4); - assert( bcount >= 3 && bcount <= 4); - - #if MAKE_MESH - addTri( vfront, ifront, front[0], front[1], front[2], frontEdges, splitFront, plane ); - addTri( vback, iback, back[0], back[1], back[2], backEdges, splitBack, plane ); - - if ( fcount == 4 ) - { - addTri( vfront, ifront, front[0], front[2], front[3], frontEdges, splitFront, plane ); - } - - if ( bcount == 4 ) - { - addTri( vback, iback, back[0], back[2], back[3], backEdges, splitBack, plane ); - } - #endif - - break; - } - } - - -// saveEdges(vfront,frontEdges,true); -// saveEdges(vback,backEdges,false); - - // Triangulate the front surface... - if ( frontEdges.size() ) // extract polygons for the front - { - UintVector polygon; - - bool ok = extractPolygon(frontEdges,polygon,splitFront); - - while ( ok ) - { - - const double *vertices = Vl_getVertices(splitFront); - unsigned int pcount = polygon.size(); - unsigned int maxTri = pcount*3; - double *tris = new double[maxTri*9]; - - unsigned int tcount = triangulate3d(pcount,(const unsigned int *) &polygon[0], vertices, tris, maxTri, plane ); - - if ( tcount ) - { - // cool! now add these triangles to the frong.. - const double *source = tris; - for (unsigned int i=0; i= 0 ) - { - Edge &e = edges[root]; - polygon.push_back(e.mE1); - int link; - - do - { - link = findEdge(edges,e.mE2); - if ( link < 0 ) - link = findNearestEdge(edges,e.mE2,split); - - if ( link >= 0 ) - { - e = edges[link]; - polygon.push_back(e.mE1 ); - } - } while ( link >= 0 ); - - - if ( polygon.size() >= 3 ) - { - ret = true; - } - - } - - return ret; - } - -CHullVector mChulls; -ConvexDecompInterface *mCallback; - -}; - -unsigned int performConvexDecomposition(const DecompDesc &desc) -{ - unsigned int ret = 0; - - if ( desc.mCallback ) - { - ConvexBuilder cb(desc.mCallback); - - ret = cb.process(desc); - } - - return ret; -} - - - -}; diff --git a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/ConvexDecomposition.h b/convex_decomposition/ConvexDecomposition/ConvexDecomposition/ConvexDecomposition.h deleted file mode 100644 index b590e2d..0000000 --- a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/ConvexDecomposition.h +++ /dev/null @@ -1,249 +0,0 @@ -#ifndef CONVEX_DECOMPOSITION_H - -#define CONVEX_DECOMPOSITION_H - -namespace ConvexDecomposition -{ - - /*! - ** - ** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net - ** - ** Portions of this source has been released with the PhysXViewer application, as well as - ** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. - ** - ** If you find this code useful or you are feeling particularily generous I would - ** ask that you please go to http://www.amillionpixels.us and make a donation - ** to Troy DeMolay. - ** - ** DeMolay is a youth group for young men between the ages of 12 and 21. - ** It teaches strong moral principles, as well as leadership skills and - ** public speaking. The donations page uses the 'pay for pixels' paradigm - ** where, in this case, a pixel is only a single penny. Donations can be - ** made for as small as $4 or as high as a $100 block. Each person who donates - ** will get a link to their own site as well as acknowledgement on the - ** donations blog located here http://www.amillionpixels.blogspot.com/ - ** - ** If you wish to contact me you can use the following methods: - ** - ** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) - ** Skype ID: jratcliff63367 - ** Yahoo: jratcliff63367 - ** AOL: jratcliff1961 - ** email: jratcliff@infiniplex.net - ** Personal website: http://jratcliffscarab.blogspot.com - ** Coding Website: http://codesuppository.blogspot.com - ** FundRaising Blog: http://amillionpixels.blogspot.com - ** Fundraising site: http://www.amillionpixels.us - ** New Temple Site: http://newtemple.blogspot.com - ** - ** - ** The MIT license: - ** - ** Permission is hereby granted, free of charge, to any person obtaining a copy - ** of this software and associated documentation files (the "Software"), to deal - ** in the Software without restriction, including without limitation the rights - ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - ** copies of the Software, and to permit persons to whom the Software is furnished - ** to do so, subject to the following conditions: - ** - ** The above copyright notice and this permission notice shall be included in all - ** copies or substantial portions of the Software. - - ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - ** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - ** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - */ - - - -class ConvexResult -{ -public: - ConvexResult(void) - { - mHullVcount = 0; - mHullVertices = 0; - mHullTcount = 0; - mHullIndices = 0; - } - - ConvexResult(unsigned int hvcount,const double *hvertices,unsigned int htcount,const unsigned int *hindices) - { - mHullVcount = hvcount; - if ( mHullVcount ) - { - mHullVertices = new double[mHullVcount*sizeof(double)*3]; - memcpy(mHullVertices, hvertices, sizeof(double)*3*mHullVcount ); - } - else - { - mHullVertices = 0; - } - - mHullTcount = htcount; - - if ( mHullTcount ) - { - mHullIndices = new unsigned int[sizeof(unsigned int)*mHullTcount*3]; - memcpy(mHullIndices,hindices, sizeof(unsigned int)*mHullTcount*3 ); - } - else - { - mHullIndices = 0; - } - - } - - ConvexResult(const ConvexResult &r) // copy constructor, perform a deep copy of the data. - { - mHullVcount = r.mHullVcount; - if ( mHullVcount ) - { - mHullVertices = new double[mHullVcount*sizeof(double)*3]; - memcpy(mHullVertices, r.mHullVertices, sizeof(double)*3*mHullVcount ); - } - else - { - mHullVertices = 0; - } - mHullTcount = r.mHullTcount; - if ( mHullTcount ) - { - mHullIndices = new unsigned int[sizeof(unsigned int)*mHullTcount*3]; - memcpy(mHullIndices, r.mHullIndices, sizeof(unsigned int)*mHullTcount*3 ); - } - else - { - mHullIndices = 0; - } - } - - ~ConvexResult(void) - { - delete mHullVertices; - delete mHullIndices; - } - -// the convex hull. - unsigned int mHullVcount; - double * mHullVertices; - unsigned int mHullTcount; - unsigned int *mHullIndices; - - double mHullVolume; // the volume of the convex hull. - -}; - -// convert from doubles back down to floats. -class FConvexResult -{ -public: - FConvexResult(const ConvexResult &r) - { - mHullVcount = r.mHullVcount; - mHullVertices = 0; - if ( mHullVcount ) - { - mHullVertices = new float[mHullVcount*3]; - - const double *src = r.mHullVertices; - float * dest = mHullVertices; - for (unsigned int i=0; i -#include -#include -#include -#include - -// Geometric Tools, Inc. -// http://www.geometrictools.com -// Copyright (c) 1998-2006. All Rights Reserved -// -// The Wild Magic Library (WM3) source code is supplied under the terms of -// the license agreement -// http://www.geometrictools.com/License/WildMagic3License.pdf -// and may not be copied or disclosed except in accordance with the terms -// of that agreement. - -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - - - -#include "bestfit.h" - -namespace ConvexDecomposition -{ - -class Vec3 -{ -public: - Vec3(void) { }; - Vec3(double _x,double _y,double _z) { x = _x; y = _y; z = _z; }; - - - double dot(const Vec3 &v) - { - return x*v.x + y*v.y + z*v.z; // the dot product - } - - double x; - double y; - double z; -}; - - -class Eigen -{ -public: - - - void DecrSortEigenStuff(void) - { - Tridiagonal(); //diagonalize the matrix. - QLAlgorithm(); // - DecreasingSort(); - GuaranteeRotation(); - } - - void Tridiagonal(void) - { - double fM00 = mElement[0][0]; - double fM01 = mElement[0][1]; - double fM02 = mElement[0][2]; - double fM11 = mElement[1][1]; - double fM12 = mElement[1][2]; - double fM22 = mElement[2][2]; - - m_afDiag[0] = fM00; - m_afSubd[2] = 0; - if (fM02 != (double)0.0) - { - double fLength = sqrt(fM01*fM01+fM02*fM02); - double fInvLength = ((double)1.0)/fLength; - fM01 *= fInvLength; - fM02 *= fInvLength; - double fQ = ((double)2.0)*fM01*fM12+fM02*(fM22-fM11); - m_afDiag[1] = fM11+fM02*fQ; - m_afDiag[2] = fM22-fM02*fQ; - m_afSubd[0] = fLength; - m_afSubd[1] = fM12-fM01*fQ; - mElement[0][0] = (double)1.0; - mElement[0][1] = (double)0.0; - mElement[0][2] = (double)0.0; - mElement[1][0] = (double)0.0; - mElement[1][1] = fM01; - mElement[1][2] = fM02; - mElement[2][0] = (double)0.0; - mElement[2][1] = fM02; - mElement[2][2] = -fM01; - m_bIsRotation = false; - } - else - { - m_afDiag[1] = fM11; - m_afDiag[2] = fM22; - m_afSubd[0] = fM01; - m_afSubd[1] = fM12; - mElement[0][0] = (double)1.0; - mElement[0][1] = (double)0.0; - mElement[0][2] = (double)0.0; - mElement[1][0] = (double)0.0; - mElement[1][1] = (double)1.0; - mElement[1][2] = (double)0.0; - mElement[2][0] = (double)0.0; - mElement[2][1] = (double)0.0; - mElement[2][2] = (double)1.0; - m_bIsRotation = true; - } - } - - bool QLAlgorithm(void) - { - const int iMaxIter = 32; - - for (int i0 = 0; i0 <3; i0++) - { - int i1; - for (i1 = 0; i1 < iMaxIter; i1++) - { - int i2; - for (i2 = i0; i2 <= (3-2); i2++) - { - double fTmp = fabs(m_afDiag[i2]) + fabs(m_afDiag[i2+1]); - if ( fabs(m_afSubd[i2]) + fTmp == fTmp ) - break; - } - if (i2 == i0) - { - break; - } - - double fG = (m_afDiag[i0+1] - m_afDiag[i0])/(((double)2.0) * m_afSubd[i0]); - double fR = sqrt(fG*fG+(double)1.0); - if (fG < (double)0.0) - { - fG = m_afDiag[i2]-m_afDiag[i0]+m_afSubd[i0]/(fG-fR); - } - else - { - fG = m_afDiag[i2]-m_afDiag[i0]+m_afSubd[i0]/(fG+fR); - } - double fSin = (double)1.0, fCos = (double)1.0, fP = (double)0.0; - for (int i3 = i2-1; i3 >= i0; i3--) - { - double fF = fSin*m_afSubd[i3]; - double fB = fCos*m_afSubd[i3]; - if (fabs(fF) >= fabs(fG)) - { - fCos = fG/fF; - fR = sqrt(fCos*fCos+(double)1.0); - m_afSubd[i3+1] = fF*fR; - fSin = ((double)1.0)/fR; - fCos *= fSin; - } - else - { - fSin = fF/fG; - fR = sqrt(fSin*fSin+(double)1.0); - m_afSubd[i3+1] = fG*fR; - fCos = ((double)1.0)/fR; - fSin *= fCos; - } - fG = m_afDiag[i3+1]-fP; - fR = (m_afDiag[i3]-fG)*fSin+((double)2.0)*fB*fCos; - fP = fSin*fR; - m_afDiag[i3+1] = fG+fP; - fG = fCos*fR-fB; - for (int i4 = 0; i4 < 3; i4++) - { - fF = mElement[i4][i3+1]; - mElement[i4][i3+1] = fSin*mElement[i4][i3]+fCos*fF; - mElement[i4][i3] = fCos*mElement[i4][i3]-fSin*fF; - } - } - m_afDiag[i0] -= fP; - m_afSubd[i0] = fG; - m_afSubd[i2] = (double)0.0; - } - if (i1 == iMaxIter) - { - return false; - } - } - return true; - } - - void DecreasingSort(void) - { - //sort eigenvalues in decreasing order, e[0] >= ... >= e[iSize-1] - for (int i0 = 0, i1; i0 <= 3-2; i0++) - { - // locate maximum eigenvalue - i1 = i0; - double fMax = m_afDiag[i1]; - int i2; - for (i2 = i0+1; i2 < 3; i2++) - { - if (m_afDiag[i2] > fMax) - { - i1 = i2; - fMax = m_afDiag[i1]; - } - } - - if (i1 != i0) - { - // swap eigenvalues - m_afDiag[i1] = m_afDiag[i0]; - m_afDiag[i0] = fMax; - // swap eigenvectors - for (i2 = 0; i2 < 3; i2++) - { - double fTmp = mElement[i2][i0]; - mElement[i2][i0] = mElement[i2][i1]; - mElement[i2][i1] = fTmp; - m_bIsRotation = !m_bIsRotation; - } - } - } - } - - - void GuaranteeRotation(void) - { - if (!m_bIsRotation) - { - // change sign on the first column - for (int iRow = 0; iRow <3; iRow++) - { - mElement[iRow][0] = -mElement[iRow][0]; - } - } - } - - double mElement[3][3]; - double m_afDiag[3]; - double m_afSubd[3]; - bool m_bIsRotation; -}; - - -bool getBestFitPlane(unsigned int vcount, - const double *points, - unsigned int vstride, - const double *weights, - unsigned int wstride, - double *plane) -{ - bool ret = false; - - Vec3 kOrigin(0,0,0); - - double wtotal = 0; - - if ( 1 ) - { - const char *source = (const char *) points; - const char *wsource = (const char *) weights; - - for (unsigned int i=0; i bmax[0] ) bmax[0] = p[0]; - if ( p[1] > bmax[1] ) bmax[1] = p[1]; - if ( p[2] > bmax[2] ) bmax[2] = p[2]; - - } - - double dx = bmax[0] - bmin[0]; - double dy = bmax[1] - bmin[1]; - double dz = bmax[2] - bmin[2]; - - return sqrt( dx*dx + dy*dy + dz*dz ); - -} - - -bool overlapAABB(const double *bmin1,const double *bmax1,const double *bmin2,const double *bmax2) // return true if the two AABB's overlap. -{ - if ( bmax2[0] < bmin1[0] ) return false; // if the maximum is less than our minimum on any axis - if ( bmax2[1] < bmin1[1] ) return false; - if ( bmax2[2] < bmin1[2] ) return false; - - if ( bmin2[0] > bmax1[0] ) return false; // if the minimum is greater than our maximum on any axis - if ( bmin2[1] > bmax1[1] ) return false; // if the minimum is greater than our maximum on any axis - if ( bmin2[2] > bmax1[2] ) return false; // if the minimum is greater than our maximum on any axis - - - return true; // the extents overlap -} - -}; // end of namespace diff --git a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/bestfit.h b/convex_decomposition/ConvexDecomposition/ConvexDecomposition/bestfit.h deleted file mode 100644 index 2cd05dc..0000000 --- a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/bestfit.h +++ /dev/null @@ -1,90 +0,0 @@ -#ifndef BEST_FIT_H - -#define BEST_FIT_H - -// This routine was released in 'snippet' form -// by John W. Ratcliff mailto:jratcliff@infiniplex.net -// on March 22, 2006. -// -// This routine computes the 'best fit' plane equation to -// a set of input data points with an optional per vertex -// weighting component. -// -// The implementation for this was lifted directly from -// David Eberly's Magic Software implementation. - -// computes the best fit plane to a collection of data points. -// returns the plane equation as A,B,C,D format. (Ax+By+Cz+D) - -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - -namespace ConvexDecomposition -{ - - -bool getBestFitPlane(unsigned int vcount, // number of input data points - const double *points, // starting address of points array. - unsigned int vstride, // stride between input points. - const double *weights, // *optional point weighting values. - unsigned int wstride, // weight stride for each vertex. - double *plane); - - -double getBoundingRegion(unsigned int vcount,const double *points,unsigned int pstride,double *bmin,double *bmax); // returns the diagonal distance -bool overlapAABB(const double *bmin1,const double *bmax1,const double *bmin2,const double *bmax2); // return true if the two AABB's overlap. - -}; - -#endif diff --git a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/bestfitobb.cpp b/convex_decomposition/ConvexDecomposition/ConvexDecomposition/bestfitobb.cpp deleted file mode 100644 index d84dd6d..0000000 --- a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/bestfitobb.cpp +++ /dev/null @@ -1,368 +0,0 @@ -#include -#include -#include -#include -#include - -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - - - -// compute the 'best fit' oriented bounding box of an input point cloud by doing an exhaustive search. -// it spins the point cloud around searching for the minimal volume. It keeps narrowing down until -// it fails to find a better fit. The only dependency is on 'double_math' -// -// The inputs are: -// -// vcount : number of input vertices in the point cloud. -// points : a pointer to the first vertex. -// pstride : The stride between each point measured in bytes. -// -// The outputs are: -// -// sides : The length of the sides of the OBB as X, Y, Z distance. -// matrix : A pointer to a 4x4 matrix. This will contain the 3x3 rotation and the translation component. -// pos : The center of the OBB -// quat : The orientation of the OBB expressed as quaternion in the form of X,Y,Z,W -// -// -// Please email bug fixes or improvements to John W. Ratcliff at mailto:jratcliff@infiniplex.net -// -// If you find this source code useful donate a couple of bucks to my kid's fund raising website at -// www.amillionpixels.us -// -// More snippets at: www.codesuppository.com -// - - -#include "bestfitobb.h" -#include "float_math.h" - -namespace ConvexDecomposition -{ - -// computes the OBB for this set of points relative to this transform matrix. -void computeOBB(unsigned int vcount,const double *points,unsigned int pstride,double *sides,double *matrix) -{ - const char *src = (const char *) points; - - double bmin[3] = { 1e9, 1e9, 1e9 }; - double bmax[3] = { -1e9, -1e9, -1e9 }; - - for (unsigned int i=0; i bmax[0] ) bmax[0] = t[0]; - if ( t[1] > bmax[1] ) bmax[1] = t[1]; - if ( t[2] > bmax[2] ) bmax[2] = t[2]; - - src+=pstride; - } - - double center[3]; - - sides[0] = bmax[0]-bmin[0]; - sides[1] = bmax[1]-bmin[1]; - sides[2] = bmax[2]-bmin[2]; - - center[0] = sides[0]*0.5f+bmin[0]; - center[1] = sides[1]*0.5f+bmin[1]; - center[2] = sides[2]*0.5f+bmin[2]; - - double ocenter[3]; - - fm_rotate(matrix,center,ocenter); - - matrix[12]+=ocenter[0]; - matrix[13]+=ocenter[1]; - matrix[14]+=ocenter[2]; - -} - -void computeBestFitOBB(unsigned int vcount,const double *points,unsigned int pstride,double *sides,double *matrix) -{ - - double bmin[3]; - double bmax[3]; - - fm_getAABB(vcount,points,pstride,bmin,bmax); - - double center[3]; - - center[0] = (bmax[0]-bmin[0])*0.5f + bmin[0]; - center[1] = (bmax[1]-bmin[1])*0.5f + bmin[1]; - center[2] = (bmax[2]-bmin[2])*0.5f + bmin[2]; - - double ax = 0; - double ay = 0; - double az = 0; - - double sweep = 45.0f; // 180 degree sweep on all three axes. - double steps = 7.0f; // 7 steps on each axis) - - double bestVolume = 1e9; - double angle[3]; - - while ( sweep >= 1 ) - { - - bool found = false; - - double stepsize = sweep / steps; - - for (double x=ax-sweep; x<=ax+sweep; x+=stepsize) - { - for (double y=ay-sweep; y<=ay+sweep; y+=stepsize) - { - for (double z=az-sweep; z<=az+sweep; z+=stepsize) - { - double pmatrix[16]; - - fm_eulerMatrix( x*FM_DEG_TO_RAD, y*FM_DEG_TO_RAD, z*FM_DEG_TO_RAD, pmatrix ); - - pmatrix[3*4+0] = center[0]; - pmatrix[3*4+1] = center[1]; - pmatrix[3*4+2] = center[2]; - - double psides[3]; - - computeOBB( vcount, points, pstride, psides, pmatrix ); - - double volume = psides[0]*psides[1]*psides[2]; // the volume of the cube - - if ( volume < bestVolume ) - { - bestVolume = volume; - - sides[0] = psides[0]; - sides[1] = psides[1]; - sides[2] = psides[2]; - - angle[0] = ax; - angle[1] = ay; - angle[2] = az; - - memcpy(matrix,pmatrix,sizeof(double)*16); - found = true; // yes, we found an improvement. - } - } - } - } - - if ( found ) - { - - ax = angle[0]; - ay = angle[1]; - az = angle[2]; - - sweep*=0.5f; // sweep 1/2 the distance as the last time. - } - else - { - break; // no improvement, so just - } - - } - -} - - -void computeBestFitOBB(unsigned int vcount,const double *points,unsigned int pstride,double *sides,double *pos,double *quat) -{ - double matrix[16]; - - computeBestFitOBB(vcount,points,pstride,sides,matrix); - fm_getTranslation(matrix,pos); - fm_matrixToQuat(matrix,quat); - -} - - -void computeBestFitABB(unsigned int vcount,const double *points,unsigned int pstride,double *sides,double *pos) -{ - double bmin[3]; - double bmax[3]; - - bmin[0] = points[0]; - bmin[1] = points[1]; - bmin[2] = points[2]; - - bmax[0] = points[0]; - bmax[1] = points[1]; - bmax[2] = points[2]; - - const char *cp = (const char *) points; - for (unsigned int i=0; i bmax[0] ) bmax[0] = p[0]; - if ( p[1] > bmax[1] ) bmax[1] = p[1]; - if ( p[2] > bmax[2] ) bmax[2] = p[2]; - - cp+=pstride; - } - - - sides[0] = bmax[0] - bmin[0]; - sides[1] = bmax[1] - bmin[1]; - sides[2] = bmax[2] - bmin[2]; - - pos[0] = bmin[0]+sides[0]*0.5f; - pos[1] = bmin[1]+sides[1]*0.5f; - pos[2] = bmin[2]+sides[2]*0.5f; - -} - - -void computeBestFitOBB(unsigned int vcount,const float *points,unsigned int pstride,float *sides,float *pos,float *quat) // the float version of the routine. -{ - double *temp = new double[vcount*3]; - const char *src = (const char *)points; - double *dest = temp; - for (unsigned int i=0; i bmax[0] ) bmax[0] = p[0]; - if ( p[1] > bmax[1] ) bmax[1] = p[1]; - if ( p[2] > bmax[2] ) bmax[2] = p[2]; - - cp+=pstride; - } - - - sides[0] = bmax[0] - bmin[0]; - sides[1] = bmax[1] - bmin[1]; - sides[2] = bmax[2] - bmin[2]; - - pos[0] = bmin[0]+sides[0]*0.5f; - pos[1] = bmin[1]+sides[1]*0.5f; - pos[2] = bmin[2]+sides[2]*0.5f; - -} - -}; diff --git a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/bestfitobb.h b/convex_decomposition/ConvexDecomposition/ConvexDecomposition/bestfitobb.h deleted file mode 100644 index 720c717..0000000 --- a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/bestfitobb.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef BEST_FIT_OBB_H - -#define BEST_FIT_OBB_H - -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - - - -// compute the 'best fit' oriented bounding box of an input point cloud by doing an exhaustive search. -// it spins the point cloud around searching for the minimal volume. It keeps narrowing down until -// it fails to find a better fit. The only dependency is on 'double_math' -// -// The inputs are: -// -// vcount : number of input vertices in the point cloud. -// points : a pointer to the first vertex. -// pstride : The stride between each point measured in bytes. -// -// The outputs are: -// -// sides : The length of the sides of the OBB as X, Y, Z distance. -// matrix : A pointer to a 4x4 matrix. This will contain the 3x3 rotation and the translation component. -// pos : The center of the OBB -// quat : The orientation of the OBB expressed as quaternion in the form of X,Y,Z,W -// -// -// Please email bug fixes or improvements to John W. Ratcliff at mailto:jratcliff@infiniplex.net -// -// If you find this source code useful donate a couple of bucks to my kid's fund raising website at -// www.amillionpixels.us -// -// More snippets at: www.codesuppository.com -// - -namespace ConvexDecomposition -{ - -void computeBestFitOBB(unsigned int vcount,const double *points,unsigned int pstride,double *sides,double *matrix); -void computeBestFitOBB(unsigned int vcount,const double *points,unsigned int pstride,double *sides,double *pos,double *quat); -void computeBestFitABB(unsigned int vcount,const double *points,unsigned int pstride,double *sides,double *pos); - - -void computeBestFitOBB(unsigned int vcount,const float *points,unsigned int pstride,float *sides,float *pos,float *quat); // the float version of the routine. -void computeBestFitABB(unsigned int vcount,const float *points,unsigned int pstride,float *sides,float *pos); - -}; - -#endif diff --git a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/cd_hull.cpp b/convex_decomposition/ConvexDecomposition/ConvexDecomposition/cd_hull.cpp deleted file mode 100644 index 74cec01..0000000 --- a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/cd_hull.cpp +++ /dev/null @@ -1,3650 +0,0 @@ -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - - -#include -#include -#include -#include -#include -#include - - -#include -#include - -#include "cd_hull.h" - -#define STANDALONE 1 // This #define is used when tranferring this source code to other projects - -#if STANDALONE - -#undef NX_ALLOC -#undef NX_FREE - -#define NX_ALLOC(x,y) malloc(x) -#define NX_FREE(x) free(x) - -#else -#include "Allocateable.h" -#endif - -namespace ConvexDecomposition -{ - -//***************************************************** -//*** DARRAY.H -//***************************************************** - -template class ArrayRet; -template class Array -{ - public: - Array(int s=0); - Array(Array &array); - Array(ArrayRet &array); - ~Array(); - void allocate(int s); - void SetSize(int s); - void Pack(); - Type& Add(Type); - void AddUnique(Type); - int Contains(Type); - void Insert(Type,int); - int IndexOf(Type); - void Remove(Type); - void DelIndex(int i); - Type * element; - int count; - int array_size; - const Type &operator[](int i) const { assert(i>=0 && i=0 && i &operator=(Array &array); - Array &operator=(ArrayRet &array); - // operator ArrayRet &() { return *(ArrayRet *)this;} // this worked but i suspect could be dangerous -}; - -template class ArrayRet:public Array -{ -}; - -template Array::Array(int s) -{ - count=0; - array_size = 0; - element = NULL; - if(s) - { - allocate(s); - } -} - - -template Array::Array(Array &array) -{ - count=0; - array_size = 0; - element = NULL; - for(int i=0;i Array::Array(ArrayRet &array) -{ - *this = array; -} -template Array &Array::operator=(ArrayRet &array) -{ - count=array.count; - array_size = array.array_size; - element = array.element; - array.element=NULL; - array.count=0; - array.array_size=0; - return *this; -} - - -template Array &Array::operator=(Array &array) -{ - count=0; - for(int i=0;i Array::~Array() -{ - if (element != NULL) - { - NX_FREE(element); - } - count=0;array_size=0;element=NULL; -} - -template void Array::allocate(int s) -{ - assert(s>0); - assert(s>=count); - Type *old = element; - array_size =s; - element = (Type *) NX_ALLOC( sizeof(Type)*array_size, CONVEX_TEMP ); - assert(element); - for(int i=0;i void Array::SetSize(int s) -{ - if(s==0) - { - if(element) - { - NX_FREE(element); - element = NULL; - } - array_size = s; - } - else - { - allocate(s); - } - count=s; -} - -template void Array::Pack() -{ - allocate(count); -} - -template Type& Array::Add(Type t) -{ - assert(count<=array_size); - if(count==array_size) - { - allocate((array_size)?array_size *2:16); - } - element[count++] = t; - return element[count-1]; -} - -template int Array::Contains(Type t) -{ - int i; - int found=0; - for(i=0;i void Array::AddUnique(Type t) -{ - if(!Contains(t)) Add(t); -} - - -template void Array::DelIndex(int i) -{ - assert(i void Array::Remove(Type t) -{ - int i; - for(i=0;i void Array::Insert(Type t,int k) -{ - int i=count; - Add(t); // to allocate space - while(i>k) - { - element[i]=element[i-1]; - i--; - } - assert(i==k); - element[k]=t; -} - - -template int Array::IndexOf(Type t) -{ - int i; - for(i=0;i Member )))- ((char*)NULL)) - - - -int argmin(double a[],int n); -double sqr(double a); -double clampf(double a) ; -double Round(double a,double precision); -double Interpolate(const double &f0,const double &f1,double alpha) ; - -template -void Swap(T &a,T &b) -{ - T tmp = a; - a=b; - b=tmp; -} - - - -template -T Max(const T &a,const T &b) -{ - return (a>b)?a:b; -} - -template -T Min(const T &a,const T &b) -{ - return (a=0&&i<2);return ((double*)this)[i];} - const double& operator[](int i) const {assert(i>=0&&i<2);return ((double*)this)[i];} -}; -inline double2 operator-( const double2& a, const double2& b ){return double2(a.x-b.x,a.y-b.y);} -inline double2 operator+( const double2& a, const double2& b ){return double2(a.x+b.x,a.y+b.y);} - -//--------- 3D --------- - -class double3 // 3D -{ - public: - double x,y,z; - double3(){x=0;y=0;z=0;}; - double3(double _x,double _y,double _z){x=_x;y=_y;z=_z;}; - //operator double *() { return &x;}; - double& operator[](int i) {assert(i>=0&&i<3);return ((double*)this)[i];} - const double& operator[](int i) const {assert(i>=0&&i<3);return ((double*)this)[i];} -# ifdef PLUGIN_3DSMAX - double3(const Point3 &p):x(p.x),y(p.y),z(p.z){} - operator Point3(){return *((Point3*)this);} -# endif -}; - - -double3& operator+=( double3 &a, const double3& b ); -double3& operator-=( double3 &a ,const double3& b ); -double3& operator*=( double3 &v ,const double s ); -double3& operator/=( double3 &v, const double s ); - -double magnitude( const double3& v ); -double3 normalize( const double3& v ); -double3 safenormalize(const double3 &v); -double3 vabs(const double3 &v); -double3 operator+( const double3& a, const double3& b ); -double3 operator-( const double3& a, const double3& b ); -double3 operator-( const double3& v ); -double3 operator*( const double3& v, const double s ); -double3 operator*( const double s, const double3& v ); -double3 operator/( const double3& v, const double s ); -inline int operator==( const double3 &a, const double3 &b ) { return (a.x==b.x && a.y==b.y && a.z==b.z); } -inline int operator!=( const double3 &a, const double3 &b ) { return (a.x!=b.x || a.y!=b.y || a.z!=b.z); } -// due to ambiguity and inconsistent standards ther are no overloaded operators for mult such as va*vb. -double dot( const double3& a, const double3& b ); -double3 cmul( const double3 &a, const double3 &b); -double3 cross( const double3& a, const double3& b ); -double3 Interpolate(const double3 &v0,const double3 &v1,double alpha); -double3 Round(const double3& a,double precision); -double3 VectorMax(const double3 &a, const double3 &b); -double3 VectorMin(const double3 &a, const double3 &b); - - - -class double3x3 -{ - public: - double3 x,y,z; // the 3 rows of the Matrix - double3x3(){} - double3x3(double xx,double xy,double xz,double yx,double yy,double yz,double zx,double zy,double zz):x(xx,xy,xz),y(yx,yy,yz),z(zx,zy,zz){} - double3x3(double3 _x,double3 _y,double3 _z):x(_x),y(_y),z(_z){} - double3& operator[](int i) {assert(i>=0&&i<3);return (&x)[i];} - const double3& operator[](int i) const {assert(i>=0&&i<3);return (&x)[i];} - double& operator()(int r, int c) {assert(r>=0&&r<3&&c>=0&&c<3);return ((&x)[r])[c];} - const double& operator()(int r, int c) const {assert(r>=0&&r<3&&c>=0&&c<3);return ((&x)[r])[c];} -}; -double3x3 Transpose( const double3x3& m ); -double3 operator*( const double3& v , const double3x3& m ); -double3 operator*( const double3x3& m , const double3& v ); -double3x3 operator*( const double3x3& m , const double& s ); -double3x3 operator*( const double3x3& ma, const double3x3& mb ); -double3x3 operator/( const double3x3& a, const double& s ) ; -double3x3 operator+( const double3x3& a, const double3x3& b ); -double3x3 operator-( const double3x3& a, const double3x3& b ); -double3x3 &operator+=( double3x3& a, const double3x3& b ); -double3x3 &operator-=( double3x3& a, const double3x3& b ); -double3x3 &operator*=( double3x3& a, const double& s ); -double Determinant(const double3x3& m ); -double3x3 Inverse(const double3x3& a); // its just 3x3 so we simply do that cofactor method - - -//-------- 4D Math -------- - -class double4 -{ -public: - double x,y,z,w; - double4(){x=0;y=0;z=0;w=0;}; - double4(double _x,double _y,double _z,double _w){x=_x;y=_y;z=_z;w=_w;} - double4(const double3 &v,double _w){x=v.x;y=v.y;z=v.z;w=_w;} - //operator double *() { return &x;}; - double& operator[](int i) {assert(i>=0&&i<4);return ((double*)this)[i];} - const double& operator[](int i) const {assert(i>=0&&i<4);return ((double*)this)[i];} - const double3& xyz() const { return *((double3*)this);} - double3& xyz() { return *((double3*)this);} -}; - - -struct D3DXMATRIX; - -class double4x4 -{ - public: - double4 x,y,z,w; // the 4 rows - double4x4(){} - double4x4(const double4 &_x, const double4 &_y, const double4 &_z, const double4 &_w):x(_x),y(_y),z(_z),w(_w){} - double4x4(double m00, double m01, double m02, double m03, - double m10, double m11, double m12, double m13, - double m20, double m21, double m22, double m23, - double m30, double m31, double m32, double m33 ) - :x(m00,m01,m02,m03),y(m10,m11,m12,m13),z(m20,m21,m22,m23),w(m30,m31,m32,m33){} - double& operator()(int r, int c) {assert(r>=0&&r<4&&c>=0&&c<4);return ((&x)[r])[c];} - const double& operator()(int r, int c) const {assert(r>=0&&r<4&&c>=0&&c<4);return ((&x)[r])[c];} - operator double* () {return &x.x;} - operator const double* () const {return &x.x;} - operator struct D3DXMATRIX* () { return (struct D3DXMATRIX*) this;} - operator const struct D3DXMATRIX* () const { return (struct D3DXMATRIX*) this;} -}; - - -int operator==( const double4 &a, const double4 &b ); -double4 Homogenize(const double3 &v3,const double &w=1.0f); // Turns a 3D double3 4D vector4 by appending w -double4 cmul( const double4 &a, const double4 &b); -double4 operator*( const double4 &v, double s); -double4 operator*( double s, const double4 &v); -double4 operator+( const double4 &a, const double4 &b); -double4 operator-( const double4 &a, const double4 &b); -double4x4 operator*( const double4x4& a, const double4x4& b ); -double4 operator*( const double4& v, const double4x4& m ); -double4x4 Inverse(const double4x4 &m); -double4x4 MatrixRigidInverse(const double4x4 &m); -double4x4 MatrixTranspose(const double4x4 &m); -double4x4 MatrixPerspectiveFov(double fovy, double Aspect, double zn, double zf ); -double4x4 MatrixTranslation(const double3 &t); -double4x4 MatrixRotationZ(const double angle_radians); -double4x4 MatrixLookAt(const double3& eye, const double3& at, const double3& up); -int operator==( const double4x4 &a, const double4x4 &b ); - - -//-------- Quaternion ------------ - -class Quaternion :public double4 -{ - public: - Quaternion() { x = y = z = 0.0f; w = 1.0f; } - Quaternion( double3 v, double t ) { v = normalize(v); w = cos(t/2.0f); v = v*sin(t/2.0f); x = v.x; y = v.y; z = v.z; } - Quaternion(double _x, double _y, double _z, double _w){x=_x;y=_y;z=_z;w=_w;} - double angle() const { return acos(w)*2.0f; } - double3 axis() const { double3 a(x,y,z); if(fabs(angle())<0.0000001f) return double3(1,0,0); return a*(1/sin(angle()/2.0f)); } - double3 xdir() const { return double3( 1-2*(y*y+z*z), 2*(x*y+w*z), 2*(x*z-w*y) ); } - double3 ydir() const { return double3( 2*(x*y-w*z),1-2*(x*x+z*z), 2*(y*z+w*x) ); } - double3 zdir() const { return double3( 2*(x*z+w*y), 2*(y*z-w*x),1-2*(x*x+y*y) ); } - double3x3 getmatrix() const { return double3x3( xdir(), ydir(), zdir() ); } - operator double3x3() { return getmatrix(); } - void Normalize(); -}; - -Quaternion& operator*=(Quaternion& a, double s ); -Quaternion operator*( const Quaternion& a, double s ); -Quaternion operator*( const Quaternion& a, const Quaternion& b); -Quaternion operator+( const Quaternion& a, const Quaternion& b ); -Quaternion normalize( Quaternion a ); -double dot( const Quaternion &a, const Quaternion &b ); -double3 operator*( const Quaternion& q, const double3& v ); -double3 operator*( const double3& v, const Quaternion& q ); -Quaternion slerp( Quaternion a, const Quaternion& b, double interp ); -Quaternion Interpolate(const Quaternion &q0,const Quaternion &q1,double alpha); -Quaternion RotationArc(double3 v0, double3 v1 ); // returns quat q where q*v0=v1 -Quaternion Inverse(const Quaternion &q); -double4x4 MatrixFromQuatVec(const Quaternion &q, const double3 &v); - - -//------ Euler Angle ----- - -Quaternion YawPitchRoll( double yaw, double pitch, double roll ); -double Yaw( const Quaternion& q ); -double Pitch( const Quaternion& q ); -double Roll( Quaternion q ); -double Yaw( const double3& v ); -double Pitch( const double3& v ); - - -//------- Plane ---------- - -class Plane -{ - public: - double3 normal; - double dist; // distance below origin - the D from plane equasion Ax+By+Cz+D=0 - Plane(const double3 &n,double d):normal(n),dist(d){} - Plane():normal(),dist(0){} - void Transform(const double3 &position, const Quaternion &orientation); -}; - -inline Plane PlaneFlip(const Plane &plane){return Plane(-plane.normal,-plane.dist);} -inline int operator==( const Plane &a, const Plane &b ) { return (a.normal==b.normal && a.dist==b.dist); } -inline int coplanar( const Plane &a, const Plane &b ) { return (a==b || a==PlaneFlip(b)); } - - -//--------- Utility Functions ------ - -double3 PlaneLineIntersection(const Plane &plane, const double3 &p0, const double3 &p1); -double3 PlaneProject(const Plane &plane, const double3 &point); -double3 LineProject(const double3 &p0, const double3 &p1, const double3 &a); // projects a onto infinite line p0p1 -double LineProjectTime(const double3 &p0, const double3 &p1, const double3 &a); -double3 ThreePlaneIntersection(const Plane &p0,const Plane &p1, const Plane &p2); -int PolyHit(const double3 *vert,const int n,const double3 &v0, const double3 &v1, double3 *impact=NULL, double3 *normal=NULL); -int BoxInside(const double3 &p,const double3 &bmin, const double3 &bmax) ; -int BoxIntersect(const double3 &v0, const double3 &v1, const double3 &bmin, const double3 &bmax, double3 *impact); -double DistanceBetweenLines(const double3 &ustart, const double3 &udir, const double3 &vstart, const double3 &vdir, double3 *upoint=NULL, double3 *vpoint=NULL); -double3 TriNormal(const double3 &v0, const double3 &v1, const double3 &v2); -double3 NormalOf(const double3 *vert, const int n); -Quaternion VirtualTrackBall(const double3 &cop, const double3 &cor, const double3 &dir0, const double3 &dir1); - - - - -//***************************************************** -// ** VECMATH.CPP -//***************************************************** - - -double sqr(double a) {return a*a;} -double clampf(double a) {return Min(1.0,Max(0.0,a));} - - -double Round(double a,double precision) -{ - return floor(0.5f+a/precision)*precision; -} - - -double Interpolate(const double &f0,const double &f1,double alpha) -{ - return f0*(1-alpha) + f1*alpha; -} - - -int argmin(double a[],int n) -{ - int r=0; - for(int i=1;i=1.0) { - return a; - } - double theta = acos(d); - if(theta==0.0f) { return(a);} - return a*(sin(theta-interp*theta)/sin(theta)) + b*(sin(interp*theta)/sin(theta)); -} - - -Quaternion Interpolate(const Quaternion &q0,const Quaternion &q1,double alpha) { - return slerp(q0,q1,alpha); -} - - -Quaternion YawPitchRoll( double yaw, double pitch, double roll ) -{ - roll *= DEG2RAD; - yaw *= DEG2RAD; - pitch *= DEG2RAD; - return Quaternion(double3(0.0f,0.0f,1.0f),yaw)*Quaternion(double3(1.0f,0.0f,0.0f),pitch)*Quaternion(double3(0.0f,1.0f,0.0f),roll); -} - -double Yaw( const Quaternion& q ) -{ - static double3 v; - v=q.ydir(); - return (v.y==0.0&&v.x==0.0) ? 0.0: atan2(-v.x,v.y)*RAD2DEG; -} - -double Pitch( const Quaternion& q ) -{ - static double3 v; - v=q.ydir(); - return atan2(v.z,sqrt(sqr(v.x)+sqr(v.y)))*RAD2DEG; -} - -double Roll( Quaternion q ) -{ - q = Quaternion(double3(0.0f,0.0f,1.0f),-Yaw(q)*DEG2RAD) *q; - q = Quaternion(double3(1.0f,0.0f,0.0f),-Pitch(q)*DEG2RAD) *q; - return atan2(-q.xdir().z,q.xdir().x)*RAD2DEG; -} - -double Yaw( const double3& v ) -{ - return (v.y==0.0&&v.x==0.0) ? 0.0f: atan2(-v.x,v.y)*RAD2DEG; -} - -double Pitch( const double3& v ) -{ - return atan2(v.z,sqrt(sqr(v.x)+sqr(v.y)))*RAD2DEG; -} - - -//------------- Plane -------------- - - -void Plane::Transform(const double3 &position, const Quaternion &orientation) { - // Transforms the plane to the space defined by the - // given position/orientation. - static double3 newnormal; - static double3 origin; - - newnormal = Inverse(orientation)*normal; - origin = Inverse(orientation)*(-normal*dist - position); - - normal = newnormal; - dist = -dot(newnormal, origin); -} - - - - -//--------- utility functions ------------- - -// RotationArc() -// Given two vectors v0 and v1 this function -// returns quaternion q where q*v0==v1. -// Routine taken from game programming gems. -Quaternion RotationArc(double3 v0,double3 v1){ - static Quaternion q; - v0 = normalize(v0); // Comment these two lines out if you know its not needed. - v1 = normalize(v1); // If vector is already unit length then why do it again? - double3 c = cross(v0,v1); - double d = dot(v0,v1); - if(d<=-1.0f) { return Quaternion(1,0,0,0);} // 180 about x axis - double s = sqrt((1+d)*2); - q.x = c.x / s; - q.y = c.y / s; - q.z = c.z / s; - q.w = s /2.0f; - return q; -} - - -double4x4 MatrixFromQuatVec(const Quaternion &q, const double3 &v) -{ - // builds a 4x4 transformation matrix based on orientation q and translation v - double qx2 = q.x*q.x; - double qy2 = q.y*q.y; - double qz2 = q.z*q.z; - - double qxqy = q.x*q.y; - double qxqz = q.x*q.z; - double qxqw = q.x*q.w; - double qyqz = q.y*q.z; - double qyqw = q.y*q.w; - double qzqw = q.z*q.w; - - return double4x4( - 1-2*(qy2+qz2), - 2*(qxqy+qzqw), - 2*(qxqz-qyqw), - 0 , - 2*(qxqy-qzqw), - 1-2*(qx2+qz2), - 2*(qyqz+qxqw), - 0 , - 2*(qxqz+qyqw), - 2*(qyqz-qxqw), - 1-2*(qx2+qy2), - 0 , - v.x , - v.y , - v.z , - 1.0f ); -} - - -double3 PlaneLineIntersection(const Plane &plane, const double3 &p0, const double3 &p1) -{ - // returns the point where the line p0-p1 intersects the plane n&d - static double3 dif; - dif = p1-p0; - double dn= dot(plane.normal,dif); - double t = -(plane.dist+dot(plane.normal,p0) )/dn; - return p0 + (dif*t); -} - -double3 PlaneProject(const Plane &plane, const double3 &point) -{ - return point - plane.normal * (dot(point,plane.normal)+plane.dist); -} - -double3 LineProject(const double3 &p0, const double3 &p1, const double3 &a) -{ - double3 w; - w = p1-p0; - double t= dot(w,(a-p0)) / (sqr(w.x)+sqr(w.y)+sqr(w.z)); - return p0+ w*t; -} - - -double LineProjectTime(const double3 &p0, const double3 &p1, const double3 &a) -{ - double3 w; - w = p1-p0; - double t= dot(w,(a-p0)) / (sqr(w.x)+sqr(w.y)+sqr(w.z)); - return t; -} - - - -double3 TriNormal(const double3 &v0, const double3 &v1, const double3 &v2) -{ - // return the normal of the triangle - // inscribed by v0, v1, and v2 - double3 cp=cross(v1-v0,v2-v1); - double m=magnitude(cp); - if(m==0) return double3(1,0,0); - return cp*(1.0f/m); -} - - - -int BoxInside(const double3 &p, const double3 &bmin, const double3 &bmax) -{ - return (p.x >= bmin.x && p.x <=bmax.x && - p.y >= bmin.y && p.y <=bmax.y && - p.z >= bmin.z && p.z <=bmax.z ); -} - - -int BoxIntersect(const double3 &v0, const double3 &v1, const double3 &bmin, const double3 &bmax,double3 *impact) -{ - if(BoxInside(v0,bmin,bmax)) - { - *impact=v0; - return 1; - } - if(v0.x<=bmin.x && v1.x>=bmin.x) - { - double a = (bmin.x-v0.x)/(v1.x-v0.x); - //v.x = bmin.x; - double vy = (1-a) *v0.y + a*v1.y; - double vz = (1-a) *v0.z + a*v1.z; - if(vy>=bmin.y && vy<=bmax.y && vz>=bmin.z && vz<=bmax.z) - { - impact->x = bmin.x; - impact->y = vy; - impact->z = vz; - return 1; - } - } - else if(v0.x >= bmax.x && v1.x <= bmax.x) - { - double a = (bmax.x-v0.x)/(v1.x-v0.x); - //v.x = bmax.x; - double vy = (1-a) *v0.y + a*v1.y; - double vz = (1-a) *v0.z + a*v1.z; - if(vy>=bmin.y && vy<=bmax.y && vz>=bmin.z && vz<=bmax.z) - { - impact->x = bmax.x; - impact->y = vy; - impact->z = vz; - return 1; - } - } - if(v0.y<=bmin.y && v1.y>=bmin.y) - { - double a = (bmin.y-v0.y)/(v1.y-v0.y); - double vx = (1-a) *v0.x + a*v1.x; - //v.y = bmin.y; - double vz = (1-a) *v0.z + a*v1.z; - if(vx>=bmin.x && vx<=bmax.x && vz>=bmin.z && vz<=bmax.z) - { - impact->x = vx; - impact->y = bmin.y; - impact->z = vz; - return 1; - } - } - else if(v0.y >= bmax.y && v1.y <= bmax.y) - { - double a = (bmax.y-v0.y)/(v1.y-v0.y); - double vx = (1-a) *v0.x + a*v1.x; - // vy = bmax.y; - double vz = (1-a) *v0.z + a*v1.z; - if(vx>=bmin.x && vx<=bmax.x && vz>=bmin.z && vz<=bmax.z) - { - impact->x = vx; - impact->y = bmax.y; - impact->z = vz; - return 1; - } - } - if(v0.z<=bmin.z && v1.z>=bmin.z) - { - double a = (bmin.z-v0.z)/(v1.z-v0.z); - double vx = (1-a) *v0.x + a*v1.x; - double vy = (1-a) *v0.y + a*v1.y; - // v.z = bmin.z; - if(vy>=bmin.y && vy<=bmax.y && vx>=bmin.x && vx<=bmax.x) - { - impact->x = vx; - impact->y = vy; - impact->z = bmin.z; - return 1; - } - } - else if(v0.z >= bmax.z && v1.z <= bmax.z) - { - double a = (bmax.z-v0.z)/(v1.z-v0.z); - double vx = (1-a) *v0.x + a*v1.x; - double vy = (1-a) *v0.y + a*v1.y; - // v.z = bmax.z; - if(vy>=bmin.y && vy<=bmax.y && vx>=bmin.x && vx<=bmax.x) - { - impact->x = vx; - impact->y = vy; - impact->z = bmax.z; - return 1; - } - } - return 0; -} - - -double DistanceBetweenLines(const double3 &ustart, const double3 &udir, const double3 &vstart, const double3 &vdir, double3 *upoint, double3 *vpoint) -{ - static double3 cp; - cp = normalize(cross(udir,vdir)); - - double distu = -dot(cp,ustart); - double distv = -dot(cp,vstart); - double dist = (double)fabs(distu-distv); - if(upoint) - { - Plane plane; - plane.normal = normalize(cross(vdir,cp)); - plane.dist = -dot(plane.normal,vstart); - *upoint = PlaneLineIntersection(plane,ustart,ustart+udir); - } - if(vpoint) - { - Plane plane; - plane.normal = normalize(cross(udir,cp)); - plane.dist = -dot(plane.normal,ustart); - *vpoint = PlaneLineIntersection(plane,vstart,vstart+vdir); - } - return dist; -} - - -Quaternion VirtualTrackBall(const double3 &cop, const double3 &cor, const double3 &dir1, const double3 &dir2) -{ - // routine taken from game programming gems. - // Implement track ball functionality to spin stuf on the screen - // cop center of projection - // cor center of rotation - // dir1 old mouse direction - // dir2 new mouse direction - // pretend there is a sphere around cor. Then find the points - // where dir1 and dir2 intersect that sphere. Find the - // rotation that takes the first point to the second. - double m; - // compute plane - double3 nrml = cor - cop; - double fudgefactor = 1.0f/(magnitude(nrml) * 0.25f); // since trackball proportional to distance from cop - nrml = normalize(nrml); - double dist = -dot(nrml,cor); - double3 u= PlaneLineIntersection(Plane(nrml,dist),cop,cop+dir1); - u=u-cor; - u=u*fudgefactor; - m= magnitude(u); - if(m>1) - { - u/=m; - } - else - { - u=u - (nrml * sqrt(1-m*m)); - } - double3 v= PlaneLineIntersection(Plane(nrml,dist),cop,cop+dir2); - v=v-cor; - v=v*fudgefactor; - m= magnitude(v); - if(m>1) - { - v/=m; - } - else - { - v=v - (nrml * sqrt(1-m*m)); - } - return RotationArc(u,v); -} - - -int countpolyhit=0; -int PolyHit(const double3 *vert, const int n, const double3 &v0, const double3 &v1, double3 *impact, double3 *normal) -{ - countpolyhit++; - int i; - double3 nrml(0,0,0); - for(i=0;i0) - { - return 0; - } - - static double3 the_point; - // By using the cached plane distances d0 and d1 - // we can optimize the following: - // the_point = planelineintersection(nrml,dist,v0,v1); - double a = d0/(d0-d1); - the_point = v0*(1-a) + v1*a; - - - int inside=1; - for(int j=0;inside && j= 0.0); - } - if(inside) - { - if(normal){*normal=nrml;} - if(impact){*impact=the_point;} - } - return inside; -} - -//**************************************************** -// HULL.H source code goes here -//**************************************************** -class PHullResult -{ -public: - - PHullResult(void) - { - mVcount = 0; - mIndexCount = 0; - mFaceCount = 0; - mVertices = 0; - mIndices = 0; - } - - unsigned int mVcount; - unsigned int mIndexCount; - unsigned int mFaceCount; - double *mVertices; - unsigned int *mIndices; -}; - -bool ComputeHull(unsigned int vcount,const double *vertices,PHullResult &result,unsigned int maxverts,double inflate); -void ReleaseHull(PHullResult &result); - -//***************************************************** -// HULL.cpp source code goes here -//***************************************************** - - -#define REAL3 double3 -#define REAL double - -#define COPLANAR (0) -#define UNDER (1) -#define OVER (2) -#define SPLIT (OVER|UNDER) -#define PAPERWIDTH (0.001f) -#define VOLUME_EPSILON (1e-20f) - -double planetestepsilon = PAPERWIDTH; - -#if STANDALONE -class ConvexH -#else -class ConvexH : public NxFoundation::NxAllocateable -#endif -{ - public: - class HalfEdge - { - public: - short ea; // the other half of the edge (index into edges list) - unsigned char v; // the vertex at the start of this edge (index into vertices list) - unsigned char p; // the facet on which this edge lies (index into facets list) - HalfEdge(){} - HalfEdge(short _ea,unsigned char _v, unsigned char _p):ea(_ea),v(_v),p(_p){} - }; - Array vertices; - Array edges; - Array facets; - ConvexH(int vertices_size,int edges_size,int facets_size); -}; - -typedef ConvexH::HalfEdge HalfEdge; - -ConvexH::ConvexH(int vertices_size,int edges_size,int facets_size) - :vertices(vertices_size) - ,edges(edges_size) - ,facets(facets_size) -{ - vertices.count=vertices_size; - edges.count = edges_size; - facets.count = facets_size; -} - -ConvexH *ConvexHDup(ConvexH *src) -{ -#if STANDALONE - ConvexH *dst = new ConvexH(src->vertices.count,src->edges.count,src->facets.count); -#else - ConvexH *dst = NX_NEW_MEM(ConvexH(src->vertices.count,src->edges.count,src->facets.count), CONVEX_TEMP); -#endif - - memcpy(dst->vertices.element,src->vertices.element,sizeof(double3)*src->vertices.count); - memcpy(dst->edges.element,src->edges.element,sizeof(HalfEdge)*src->edges.count); - memcpy(dst->facets.element,src->facets.element,sizeof(Plane)*src->facets.count); - return dst; -} - - -int PlaneTest(const Plane &p, const REAL3 &v) { - REAL a = dot(v,p.normal)+p.dist; - int flag = (a>planetestepsilon)?OVER:((a<-planetestepsilon)?UNDER:COPLANAR); - return flag; -} - -int SplitTest(ConvexH &convex,const Plane &plane) { - int flag=0; - for(int i=0;i= convex.edges.count || convex.edges[inext].p != convex.edges[i].p) { - inext = estart; - } - assert(convex.edges[inext].p == convex.edges[i].p); - HalfEdge &edge = convex.edges[i]; - int nb = convex.edges[i].ea; - assert(nb!=255); - if(nb==255 || nb==-1) return 0; - assert(nb!=-1); - assert(i== convex.edges[nb].ea); - } - for(i=0;i= convex.edges.count || convex.edges[i1].p != convex.edges[i].p) { - i1 = estart; - } - int i2 = i1+1; - if(i2>= convex.edges.count || convex.edges[i2].p != convex.edges[i].p) { - i2 = estart; - } - if(i==i2) continue; // i sliced tangent to an edge and created 2 meaningless edges - REAL3 localnormal = TriNormal(convex.vertices[convex.edges[i ].v], - convex.vertices[convex.edges[i1].v], - convex.vertices[convex.edges[i2].v]); - //assert(dot(localnormal,convex.facets[convex.edges[i].p].normal)>0);//Commented out on Stan Melax' advice - if(dot(localnormal,convex.facets[convex.edges[i].p].normal)<=0)return 0; - } - return 1; -} - -// back to back quads -ConvexH *test_btbq() -{ - -#if STANDALONE - ConvexH *convex = new ConvexH(4,8,2); -#else - ConvexH *convex = NX_NEW_MEM(ConvexH(4,8,2), CONVEX_TEMP); -#endif - - convex->vertices[0] = REAL3(0,0,0); - convex->vertices[1] = REAL3(1,0,0); - convex->vertices[2] = REAL3(1,1,0); - convex->vertices[3] = REAL3(0,1,0); - convex->facets[0] = Plane(REAL3(0,0,1),0); - convex->facets[1] = Plane(REAL3(0,0,-1),0); - convex->edges[0] = HalfEdge(7,0,0); - convex->edges[1] = HalfEdge(6,1,0); - convex->edges[2] = HalfEdge(5,2,0); - convex->edges[3] = HalfEdge(4,3,0); - - convex->edges[4] = HalfEdge(3,0,1); - convex->edges[5] = HalfEdge(2,3,1); - convex->edges[6] = HalfEdge(1,2,1); - convex->edges[7] = HalfEdge(0,1,1); - AssertIntact(*convex); - return convex; -} - -ConvexH *test_cube() -{ -#if STANDALONE - ConvexH *convex = new ConvexH(8,24,6); -#else - ConvexH *convex = NX_NEW_MEM(ConvexH(8,24,6), CONVEX_TEMP); -#endif - convex->vertices[0] = REAL3(0,0,0); - convex->vertices[1] = REAL3(0,0,1); - convex->vertices[2] = REAL3(0,1,0); - convex->vertices[3] = REAL3(0,1,1); - convex->vertices[4] = REAL3(1,0,0); - convex->vertices[5] = REAL3(1,0,1); - convex->vertices[6] = REAL3(1,1,0); - convex->vertices[7] = REAL3(1,1,1); - - convex->facets[0] = Plane(REAL3(-1,0,0),0); - convex->facets[1] = Plane(REAL3(1,0,0),-1); - convex->facets[2] = Plane(REAL3(0,-1,0),0); - convex->facets[3] = Plane(REAL3(0,1,0),-1); - convex->facets[4] = Plane(REAL3(0,0,-1),0); - convex->facets[5] = Plane(REAL3(0,0,1),-1); - - convex->edges[0 ] = HalfEdge(11,0,0); - convex->edges[1 ] = HalfEdge(23,1,0); - convex->edges[2 ] = HalfEdge(15,3,0); - convex->edges[3 ] = HalfEdge(16,2,0); - - convex->edges[4 ] = HalfEdge(13,6,1); - convex->edges[5 ] = HalfEdge(21,7,1); - convex->edges[6 ] = HalfEdge( 9,5,1); - convex->edges[7 ] = HalfEdge(18,4,1); - - convex->edges[8 ] = HalfEdge(19,0,2); - convex->edges[9 ] = HalfEdge( 6,4,2); - convex->edges[10] = HalfEdge(20,5,2); - convex->edges[11] = HalfEdge( 0,1,2); - - convex->edges[12] = HalfEdge(22,3,3); - convex->edges[13] = HalfEdge( 4,7,3); - convex->edges[14] = HalfEdge(17,6,3); - convex->edges[15] = HalfEdge( 2,2,3); - - convex->edges[16] = HalfEdge( 3,0,4); - convex->edges[17] = HalfEdge(14,2,4); - convex->edges[18] = HalfEdge( 7,6,4); - convex->edges[19] = HalfEdge( 8,4,4); - - convex->edges[20] = HalfEdge(10,1,5); - convex->edges[21] = HalfEdge( 5,5,5); - convex->edges[22] = HalfEdge(12,7,5); - convex->edges[23] = HalfEdge( 1,3,5); - - - return convex; -} -ConvexH *ConvexHMakeCube(const REAL3 &bmin, const REAL3 &bmax) { - ConvexH *convex = test_cube(); - convex->vertices[0] = REAL3(bmin.x,bmin.y,bmin.z); - convex->vertices[1] = REAL3(bmin.x,bmin.y,bmax.z); - convex->vertices[2] = REAL3(bmin.x,bmax.y,bmin.z); - convex->vertices[3] = REAL3(bmin.x,bmax.y,bmax.z); - convex->vertices[4] = REAL3(bmax.x,bmin.y,bmin.z); - convex->vertices[5] = REAL3(bmax.x,bmin.y,bmax.z); - convex->vertices[6] = REAL3(bmax.x,bmax.y,bmin.z); - convex->vertices[7] = REAL3(bmax.x,bmax.y,bmax.z); - - convex->facets[0] = Plane(REAL3(-1,0,0), bmin.x); - convex->facets[1] = Plane(REAL3(1,0,0), -bmax.x); - convex->facets[2] = Plane(REAL3(0,-1,0), bmin.y); - convex->facets[3] = Plane(REAL3(0,1,0), -bmax.y); - convex->facets[4] = Plane(REAL3(0,0,-1), bmin.z); - convex->facets[5] = Plane(REAL3(0,0,1), -bmax.z); - return convex; -} -ConvexH *ConvexHCrop(ConvexH &convex,const Plane &slice) -{ - int i; - int vertcountunder=0; - int vertcountover =0; - int edgecountunder=0; - int edgecountover =0; - int planecountunder=0; - int planecountover =0; - static Array vertscoplanar; // existing vertex members of convex that are coplanar - vertscoplanar.count=0; - static Array edgesplit; // existing edges that members of convex that cross the splitplane - edgesplit.count=0; - - assert(convex.edges.count<480); - - EdgeFlag edgeflag[512]; - VertFlag vertflag[256]; - PlaneFlag planeflag[128]; - HalfEdge tmpunderedges[512]; - Plane tmpunderplanes[128]; - Coplanar coplanaredges[512]; - int coplanaredges_num=0; - - Array createdverts; - // do the side-of-plane tests - for(i=0;i= convex.edges.count || convex.edges[e1].p!=currentplane) { - enextface = e1; - e1=estart; - } - HalfEdge &edge0 = convex.edges[e0]; - HalfEdge &edge1 = convex.edges[e1]; - HalfEdge &edgea = convex.edges[edge0.ea]; - - - planeside |= vertflag[edge0.v].planetest; - //if((vertflag[edge0.v].planetest & vertflag[edge1.v].planetest) == COPLANAR) { - // assert(ecop==-1); - // ecop=e; - //} - - - if(vertflag[edge0.v].planetest == OVER && vertflag[edge1.v].planetest == OVER){ - // both endpoints over plane - edgeflag[e0].undermap = -1; - } - else if((vertflag[edge0.v].planetest | vertflag[edge1.v].planetest) == UNDER) { - // at least one endpoint under, the other coplanar or under - - edgeflag[e0].undermap = under_edge_count; - tmpunderedges[under_edge_count].v = vertflag[edge0.v].undermap; - tmpunderedges[under_edge_count].p = underplanescount; - if(edge0.ea < e0) { - // connect the neighbors - assert(edgeflag[edge0.ea].undermap !=-1); - tmpunderedges[under_edge_count].ea = edgeflag[edge0.ea].undermap; - tmpunderedges[edgeflag[edge0.ea].undermap].ea = under_edge_count; - } - under_edge_count++; - } - else if((vertflag[edge0.v].planetest | vertflag[edge1.v].planetest) == COPLANAR) { - // both endpoints coplanar - // must check a 3rd point to see if UNDER - int e2 = e1+1; - if(e2>=convex.edges.count || convex.edges[e2].p!=currentplane) { - e2 = estart; - } - assert(convex.edges[e2].p==currentplane); - HalfEdge &edge2 = convex.edges[e2]; - if(vertflag[edge2.v].planetest==UNDER) { - - edgeflag[e0].undermap = under_edge_count; - tmpunderedges[under_edge_count].v = vertflag[edge0.v].undermap; - tmpunderedges[under_edge_count].p = underplanescount; - tmpunderedges[under_edge_count].ea = -1; - // make sure this edge is added to the "coplanar" list - coplanaredge = under_edge_count; - vout = vertflag[edge0.v].undermap; - vin = vertflag[edge1.v].undermap; - under_edge_count++; - } - else { - edgeflag[e0].undermap = -1; - } - } - else if(vertflag[edge0.v].planetest == UNDER && vertflag[edge1.v].planetest == OVER) { - // first is under 2nd is over - - edgeflag[e0].undermap = under_edge_count; - tmpunderedges[under_edge_count].v = vertflag[edge0.v].undermap; - tmpunderedges[under_edge_count].p = underplanescount; - if(edge0.ea < e0) { - assert(edgeflag[edge0.ea].undermap !=-1); - // connect the neighbors - tmpunderedges[under_edge_count].ea = edgeflag[edge0.ea].undermap; - tmpunderedges[edgeflag[edge0.ea].undermap].ea = under_edge_count; - vout = tmpunderedges[edgeflag[edge0.ea].undermap].v; - } - else { - Plane &p0 = convex.facets[edge0.p]; - Plane &pa = convex.facets[edgea.p]; - createdverts.Add(ThreePlaneIntersection(p0,pa,slice)); - //createdverts.Add(PlaneProject(slice,PlaneLineIntersection(slice,convex.vertices[edge0.v],convex.vertices[edgea.v]))); - //createdverts.Add(PlaneLineIntersection(slice,convex.vertices[edge0.v],convex.vertices[edgea.v])); - vout = vertcountunder++; - } - under_edge_count++; - /// hmmm something to think about: i might be able to output this edge regarless of - // wheter or not we know v-in yet. ok i;ll try this now: - tmpunderedges[under_edge_count].v = vout; - tmpunderedges[under_edge_count].p = underplanescount; - tmpunderedges[under_edge_count].ea = -1; - coplanaredge = under_edge_count; - under_edge_count++; - - if(vin!=-1) { - // we previously processed an edge where we came under - // now we know about vout as well - - // ADD THIS EDGE TO THE LIST OF EDGES THAT NEED NEIGHBOR ON PARTITION PLANE!! - } - - } - else if(vertflag[edge0.v].planetest == COPLANAR && vertflag[edge1.v].planetest == OVER) { - // first is coplanar 2nd is over - - edgeflag[e0].undermap = -1; - vout = vertflag[edge0.v].undermap; - // I hate this but i have to make sure part of this face is UNDER before ouputting this vert - int k=estart; - assert(edge0.p == currentplane); - while(!(planeside&UNDER) && k= vertcountunderold); // for debugging only - } - if(vout!=-1) { - // we previously processed an edge where we went over - // now we know vin too - // ADD THIS EDGE TO THE LIST OF EDGES THAT NEED NEIGHBOR ON PARTITION PLANE!! - } - // output edge - tmpunderedges[under_edge_count].v = vin; - tmpunderedges[under_edge_count].p = underplanescount; - edgeflag[e0].undermap = under_edge_count; - if(e0>edge0.ea) { - assert(edgeflag[edge0.ea].undermap !=-1); - // connect the neighbors - tmpunderedges[under_edge_count].ea = edgeflag[edge0.ea].undermap; - tmpunderedges[edgeflag[edge0.ea].undermap].ea = under_edge_count; - } - assert(edgeflag[e0].undermap == under_edge_count); - under_edge_count++; - } - else if(vertflag[edge0.v].planetest == OVER && vertflag[edge1.v].planetest == COPLANAR) { - // first is over next is coplanar - - edgeflag[e0].undermap = -1; - vin = vertflag[edge1.v].undermap; - if (vin==-1) return NULL; - if(vout!=-1) { - // we previously processed an edge where we came under - // now we know both endpoints - // ADD THIS EDGE TO THE LIST OF EDGES THAT NEED NEIGHBOR ON PARTITION PLANE!! - } - - } - else { - assert(0); - } - - - e0=e1; - e1++; // do the modulo at the beginning of the loop - - } while(e0!=estart) ; - e0 = enextface; - if(planeside&UNDER) { - planeflag[currentplane].undermap = underplanescount; - tmpunderplanes[underplanescount] = convex.facets[currentplane]; - underplanescount++; - } - else { - planeflag[currentplane].undermap = 0; - } - if(vout>=0 && (planeside&UNDER)) { - assert(vin>=0); - assert(coplanaredge>=0); - assert(coplanaredge!=511); - coplanaredges[coplanaredges_num].ea = coplanaredge; - coplanaredges[coplanaredges_num].v0 = vin; - coplanaredges[coplanaredges_num].v1 = vout; - coplanaredges_num++; - } - } - - // add the new plane to the mix: - if(coplanaredges_num>0) { - tmpunderplanes[underplanescount++]=slice; - } - for(i=0;i=coplanaredges_num) - { - // assert(jvertices.count;j++) - { - dmax = Max(dmax,dot(convex->vertices[j],planes[i].normal)+planes[i].dist); - dmin = Min(dmin,dot(convex->vertices[j],planes[i].normal)+planes[i].dist); - } - double dr = dmax-dmin; - if(drfacets.count;j++) - { - if(planes[i]==convex->facets[j]) - { - d=0;continue; - } - if(dot(planes[i].normal,convex->facets[j].normal)>maxdot_minang) - { - for(int k=0;kedges.count;k++) - { - if(convex->edges[k].p!=j) continue; - if(dot(convex->vertices[convex->edges[k].v],planes[i].normal)+planes[i].dist<0) - { - d=0; // so this plane wont get selected. - break; - } - } - } - } - if(d>md) - { - p=i; - md=d; - } - } - return (md>epsilon)?p:-1; -} - - - -template -inline int maxdir(const T *p,int count,const T &dir) -{ - assert(count); - int m=0; - for(int i=1;idot(p[m],dir)) m=i; - } - return m; -} - - -template -int maxdirfiltered(const T *p,int count,const T &dir,Array &allow) -{ - assert(count); - int m=-1; - for(int i=0;idot(p[m],dir)) m=i; - } - assert(m!=-1); - return m; -} - -double3 orth(const double3 &v) -{ - double3 a=cross(v,double3(0,0,1)); - double3 b=cross(v,double3(0,1,0)); - return normalize((magnitude(a)>magnitude(b))?a:b); -} - - -template -int maxdirsterid(const T *p,int count,const T &dir,Array &allow) -{ - int m=-1; - while(m==-1) - { - m = maxdirfiltered(p,count,dir,allow); - if(allow[m]==3) return m; - T u = orth(dir); - T v = cross(u,dir); - int ma=-1; - for(double x = 0.0f ; x<= 360.0f ; x+= 45.0f) - { - double s = sin(DEG2RAD*(x)); - double c = cos(DEG2RAD*(x)); - int mb = maxdirfiltered(p,count,dir+(u*s+v*c)*0.025f,allow); - if(ma==m && mb==m) - { - allow[m]=3; - return m; - } - if(ma!=-1 && ma!=mb) // Yuck - this is really ugly - { - int mc = ma; - for(double xx = x-40.0f ; xx <= x ; xx+= 5.0f) - { - double s = sin(DEG2RAD*(xx)); - double c = cos(DEG2RAD*(xx)); - int md = maxdirfiltered(p,count,dir+(u*s+v*c)*0.025f,allow); - if(mc==m && md==m) - { - allow[m]=3; - return m; - } - mc=md; - } - } - ma=mb; - } - allow[m]=0; - m=-1; - } - assert(0); - return m; -} - - - - -int operator ==(const int3 &a,const int3 &b) -{ - for(int i=0;i<3;i++) - { - if(a[i]!=b[i]) return 0; - } - return 1; -} - -int3 roll3(int3 a) -{ - int tmp=a[0]; - a[0]=a[1]; - a[1]=a[2]; - a[2]=tmp; - return a; -} -int isa(const int3 &a,const int3 &b) -{ - return ( a==b || roll3(a)==b || a==roll3(b) ); -} -int b2b(const int3 &a,const int3 &b) -{ - return isa(a,int3(b[2],b[1],b[0])); -} -int above(double3* vertices,const int3& t, const double3 &p, double epsilon) -{ - double3 n=TriNormal(vertices[t[0]],vertices[t[1]],vertices[t[2]]); - return (dot(n,p-vertices[t[0]]) > epsilon); // EPSILON??? -} -int hasedge(const int3 &t, int a,int b) -{ - for(int i=0;i<3;i++) - { - int i1= (i+1)%3; - if(t[i]==a && t[i1]==b) return 1; - } - return 0; -} -int hasvert(const int3 &t, int v) -{ - return (t[0]==v || t[1]==v || t[2]==v) ; -} -int shareedge(const int3 &a,const int3 &b) -{ - int i; - for(i=0;i<3;i++) - { - int i1= (i+1)%3; - if(hasedge(a,b[i1],b[i])) return 1; - } - return 0; -} - -class Tri; - -static Array tris; // djs: For heaven's sake!!!! - -#if STANDALONE -class Tri : public int3 -#else -class Tri : public int3, public NxFoundation::NxAllocateable -#endif -{ -public: - int3 n; - int id; - int vmax; - double rise; - Tri(int a,int b,int c):int3(a,b,c),n(-1,-1,-1) - { - id = tris.count; - tris.Add(this); - vmax=-1; - rise = 0.0f; - } - ~Tri() - { - assert(tris[id]==this); - tris[id]=NULL; - } - int &neib(int a,int b); -}; - - -int &Tri::neib(int a,int b) -{ - static int er=-1; - int i; - for(i=0;i<3;i++) - { - int i1=(i+1)%3; - int i2=(i+2)%3; - if((*this)[i]==a && (*this)[i1]==b) return n[i2]; - if((*this)[i]==b && (*this)[i1]==a) return n[i2]; - } - assert(0); - return er; -} -void b2bfix(Tri* s,Tri*t) -{ - int i; - for(i=0;i<3;i++) - { - int i1=(i+1)%3; - int i2=(i+2)%3; - int a = (*s)[i1]; - int b = (*s)[i2]; - assert(tris[s->neib(a,b)]->neib(b,a) == s->id); - assert(tris[t->neib(a,b)]->neib(b,a) == t->id); - tris[s->neib(a,b)]->neib(b,a) = t->neib(b,a); - tris[t->neib(b,a)]->neib(a,b) = s->neib(a,b); - } -} - -void removeb2b(Tri* s,Tri*t) -{ - b2bfix(s,t); - delete s; - delete t; -} - -void checkit(Tri *t) -{ - int i; - assert(tris[t->id]==t); - for(i=0;i<3;i++) - { - int i1=(i+1)%3; - int i2=(i+2)%3; - int a = (*t)[i1]; - int b = (*t)[i2]; - assert(a!=b); - assert( tris[t->n[i]]->neib(b,a) == t->id); - } -} -void extrude(Tri *t0,int v) -{ - int3 t= *t0; - int n = tris.count; -#if STANDALONE - Tri* ta = new Tri(v,t[1],t[2]); -#else - Tri* ta = NX_NEW_MEM(Tri(v,t[1],t[2]), CONVEX_TEMP); -#endif - ta->n = int3(t0->n[0],n+1,n+2); - tris[t0->n[0]]->neib(t[1],t[2]) = n+0; -#if STANDALONE - Tri* tb = new Tri(v,t[2],t[0]); -#else - Tri* tb = NX_NEW_MEM(Tri(v,t[2],t[0]), CONVEX_TEMP); -#endif - tb->n = int3(t0->n[1],n+2,n+0); - tris[t0->n[1]]->neib(t[2],t[0]) = n+1; -#if STANDALONE - Tri* tc = new Tri(v,t[0],t[1]); -#else - Tri* tc = NX_NEW_MEM(Tri(v,t[0],t[1]), CONVEX_TEMP); -#endif - tc->n = int3(t0->n[2],n+0,n+1); - tris[t0->n[2]]->neib(t[0],t[1]) = n+2; - checkit(ta); - checkit(tb); - checkit(tc); - if(hasvert(*tris[ta->n[0]],v)) removeb2b(ta,tris[ta->n[0]]); - if(hasvert(*tris[tb->n[0]],v)) removeb2b(tb,tris[tb->n[0]]); - if(hasvert(*tris[tc->n[0]],v)) removeb2b(tc,tris[tc->n[0]]); - delete t0; - -} - -Tri *extrudable(double epsilon) -{ - int i; - Tri *t=NULL; - for(i=0;iriserise)) - { - t = tris[i]; - } - } - return (t->rise >epsilon)?t:NULL ; -} - -class int4 -{ -public: - int x,y,z,w; - int4(){}; - int4(int _x,int _y, int _z,int _w){x=_x;y=_y;z=_z;w=_w;} - const int& operator[](int i) const {return (&x)[i];} - int& operator[](int i) {return (&x)[i];} -}; - - - -bool hasVolume(double3 *verts, int p0, int p1, int p2, int p3) -{ - double3 result3 = cross(verts[p1]-verts[p0], verts[p2]-verts[p0]); - if (magnitude(result3) < VOLUME_EPSILON && magnitude(result3) > -VOLUME_EPSILON) // Almost collinear or otherwise very close to each other - return false; - double result = dot(normalize(result3), verts[p3]-verts[p0]); - return (result > VOLUME_EPSILON || result < -VOLUME_EPSILON); // Returns true iff volume is significantly non-zero -} - -int4 FindSimplex(double3 *verts,int verts_count,Array &allow) -{ - double3 basis[3]; - basis[0] = double3( 0.01f, 0.02f, 1.0f ); - int p0 = maxdirsterid(verts,verts_count, basis[0],allow); - int p1 = maxdirsterid(verts,verts_count,-basis[0],allow); - basis[0] = verts[p0]-verts[p1]; - if(p0==p1 || basis[0]==double3(0,0,0)) - return int4(-1,-1,-1,-1); - basis[1] = cross(double3( 1, 0.02f, 0),basis[0]); - basis[2] = cross(double3(-0.02f, 1, 0),basis[0]); - basis[1] = normalize( (magnitude(basis[1])>magnitude(basis[2])) ? basis[1]:basis[2]); - int p2 = maxdirsterid(verts,verts_count,basis[1],allow); - if(p2 == p0 || p2 == p1) - { - p2 = maxdirsterid(verts,verts_count,-basis[1],allow); - } - if(p2 == p0 || p2 == p1) - return int4(-1,-1,-1,-1); - basis[1] = verts[p2] - verts[p0]; - basis[2] = normalize(cross(basis[1],basis[0])); - int p3 = maxdirsterid(verts,verts_count,basis[2],allow); - if(p3==p0||p3==p1||p3==p2||!hasVolume(verts, p0, p1, p2, p3)) p3 = maxdirsterid(verts,verts_count,-basis[2],allow); - if(p3==p0||p3==p1||p3==p2) - return int4(-1,-1,-1,-1); - assert(!(p0==p1||p0==p2||p0==p3||p1==p2||p1==p3||p2==p3)); - if(dot(verts[p3]-verts[p0],cross(verts[p1]-verts[p0],verts[p2]-verts[p0])) <0) {Swap(p2,p3);} - return int4(p0,p1,p2,p3); -} - -int calchullgen(double3 *verts,int verts_count, int vlimit) -{ - if(verts_count <4) return 0; - if(vlimit==0) vlimit=1000000000; - int j; - double3 bmin(*verts),bmax(*verts); - Array isextreme(verts_count); - Array allow(verts_count); - for(j=0;jn=int3(2,3,1); - Tri *t1 = new Tri(p[3],p[2],p[0]); t1->n=int3(3,2,0); - Tri *t2 = new Tri(p[0],p[1],p[3]); t2->n=int3(0,1,3); - Tri *t3 = new Tri(p[1],p[0],p[2]); t3->n=int3(1,0,2); -#else - Tri *t0 = NX_NEW_MEM(Tri(p[2],p[3],p[1]); t0->n=int3(2,3,1), CONVEX_TEMP); - Tri *t1 = NX_NEW_MEM(Tri(p[3],p[2],p[0]); t1->n=int3(3,2,0), CONVEX_TEMP); - Tri *t2 = NX_NEW_MEM(Tri(p[0],p[1],p[3]); t2->n=int3(0,1,3), CONVEX_TEMP); - Tri *t3 = NX_NEW_MEM(Tri(p[1],p[0],p[2]); t3->n=int3(1,0,2), CONVEX_TEMP); -#endif - isextreme[p[0]]=isextreme[p[1]]=isextreme[p[2]]=isextreme[p[3]]=1; - checkit(t0);checkit(t1);checkit(t2);checkit(t3); - - for(j=0;jvmax<0); - double3 n=TriNormal(verts[(*t)[0]],verts[(*t)[1]],verts[(*t)[2]]); - t->vmax = maxdirsterid(verts,verts_count,n,allow); - t->rise = dot(n,verts[t->vmax]-verts[(*t)[0]]); - } - Tri *te; - vlimit-=4; - while(vlimit >0 && (te=extrudable(epsilon))) - { - int3 ti=*te; - int v=te->vmax; - assert(!isextreme[v]); // wtf we've already done this vertex - isextreme[v]=1; - //if(v==p0 || v==p1 || v==p2 || v==p3) continue; // done these already - j=tris.count; - int newstart=j; - while(j--) { - if(!tris[j]) continue; - int3 t=*tris[j]; - if(above(verts,t,verts[v],0.01f*epsilon)) - { - extrude(tris[j],v); - } - } - // now check for those degenerate cases where we have a flipped triangle or a really skinny triangle - j=tris.count; - while(j--) - { - if(!tris[j]) continue; - if(!hasvert(*tris[j],v)) break; - int3 nt=*tris[j]; - if(above(verts,nt,center,0.01f*epsilon) || magnitude(cross(verts[nt[1]]-verts[nt[0]],verts[nt[2]]-verts[nt[1]]))< epsilon*epsilon*0.1f ) - { - Tri *nb = tris[tris[j]->n[0]]; - assert(nb);assert(!hasvert(*nb,v));assert(nb->idvmax>=0) break; - double3 n=TriNormal(verts[(*t)[0]],verts[(*t)[1]],verts[(*t)[2]]); - t->vmax = maxdirsterid(verts,verts_count,n,allow); - if(isextreme[t->vmax]) - { - t->vmax=-1; // already done that vertex - algorithm needs to be able to terminate. - } - else - { - t->rise = dot(n,verts[t->vmax]-verts[(*t)[0]]); - } - } - vlimit --; - } - return 1; -} - -int calchull(double3 *verts,int verts_count, int *&tris_out, int &tris_count,int vlimit) -{ - int rc=calchullgen(verts,verts_count, vlimit) ; - if(!rc) return 0; - Array ts; - for(int i=0;i &planes,double bevangle) -{ - int i,j; - Array bplanes; - planes.count=0; - int rc = calchullgen(verts,verts_count,vlimit); - if(!rc) return 0; - extern double minadjangle; // default is 3.0f; // in degrees - result wont have two adjacent facets within this angle of each other. - double maxdot_minang = cos(DEG2RAD*minadjangle); - for(i=0;in[j]id) continue; - Tri *s = tris[t->n[j]]; - REAL3 snormal = TriNormal(verts[(*s)[0]],verts[(*s)[1]],verts[(*s)[2]]); - if(dot(snormal,p.normal)>=cos(bevangle*DEG2RAD)) continue; - REAL3 e = verts[(*t)[(j+2)%3]] - verts[(*t)[(j+1)%3]]; - REAL3 n = (e!=REAL3(0,0,0))? cross(snormal,e)+cross(e,p.normal) : snormal+p.normal; - assert(n!=REAL3(0,0,0)); - if(n==REAL3(0,0,0)) return 0; - n=normalize(n); - bplanes.Add(Plane(n,-dot(n,verts[maxdir(verts,verts_count,n)]))); - } - } - for(i=0;imaxdot_minang) - { - // somebody has to die, keep the biggest triangle - if( area2(verts[(*ti)[0]],verts[(*ti)[1]],verts[(*ti)[2]]) < area2(verts[(*tj)[0]],verts[(*tj)[1]],verts[(*tj)[2]])) - { - delete tris[i]; tris[i]=NULL; - } - else - { - delete tris[j]; tris[j]=NULL; - } - } - } - for(i=0;imaxdot_minang) break; - } - if(j==planes.count) - { - planes.Add(bplanes[i]); - } - } - for(i=0;i maxdot_minang) - { - (*((j%2)?&bmax:&bmin)) += n * (diameter*0.5f); - break; - } - } - } - ConvexH *c = ConvexHMakeCube(REAL3(bmin),REAL3(bmax)); - int k; - while(maxplanes-- && (k=candidateplane(planes,planes_count,c,epsilon))>=0) - { - ConvexH *tmp = c; - c = ConvexHCrop(*tmp,planes[k]); - if(c==NULL) {c=tmp; break;} // might want to debug this case better!!! - if(!AssertIntact(*c)) {c=tmp; break;} // might want to debug this case better too!!! - delete tmp; - } - - assert(AssertIntact(*c)); - //return c; - faces_out = (int*)NX_ALLOC(sizeof(int)*(1+c->facets.count+c->edges.count), CONVEX_TEMP); // new int[1+c->facets.count+c->edges.count]; - faces_count_out=0; - i=0; - faces_out[faces_count_out++]=-1; - k=0; - while(iedges.count) - { - j=1; - while(j+iedges.count && c->edges[i].p==c->edges[i+j].p) { j++; } - faces_out[faces_count_out++]=j; - while(j--) - { - faces_out[faces_count_out++] = c->edges[i].v; - i++; - } - k++; - } - faces_out[0]=k; // number of faces. - assert(k==c->facets.count); - assert(faces_count_out == 1+c->facets.count+c->edges.count); - verts_out = c->vertices.element; // new double3[c->vertices.count]; - verts_count_out = c->vertices.count; - for(i=0;ivertices.count;i++) - { - verts_out[i] = double3(c->vertices[i]); - } - c->vertices.count=c->vertices.array_size=0; c->vertices.element=NULL; - delete c; - return 1; -} - -static int overhullv(double3 *verts, int verts_count,int maxplanes, - double3 *&verts_out, int &verts_count_out, int *&faces_out, int &faces_count_out ,double inflate,double bevangle,int vlimit) -{ - if(!verts_count) return 0; - extern int calchullpbev(double3 *verts,int verts_count,int vlimit, Array &planes,double bevangle) ; - Array planes; - int rc=calchullpbev(verts,verts_count,vlimit,planes,bevangle) ; - if(!rc) return 0; - return overhull(planes.element,planes.count,verts,verts_count,maxplanes,verts_out,verts_count_out,faces_out,faces_count_out,inflate); -} - - -//***************************************************** -//***************************************************** - - -bool ComputeHull(unsigned int vcount,const double *vertices,PHullResult &result,unsigned int vlimit,double inflate) -{ - - int index_count; - int *faces; - double3 *verts_out; - int verts_count_out; - - if(inflate==0.0f) - { - int *tris_out; - int tris_count; - int ret = calchull( (double3 *) vertices, (int) vcount, tris_out, tris_count, vlimit ); - if(!ret) return false; - result.mIndexCount = (unsigned int) (tris_count*3); - result.mFaceCount = (unsigned int) tris_count; - result.mVertices = (double*) vertices; - result.mVcount = (unsigned int) vcount; - result.mIndices = (unsigned int *) tris_out; - return true; - } - - int ret = overhullv((double3*)vertices,vcount,35,verts_out,verts_count_out,faces,index_count,inflate,120.0f,vlimit); - if(!ret) { - tris.SetSize(0); //have to set the size to 0 in order to protect from a "pure virtual function call" problem - return false; - } - - Array tris; - int n=faces[0]; - int k=1; - for(int i=0;i bmax[0] ) bmax[0] = v[0]; - if ( v[1] > bmax[1] ) bmax[1] = v[1]; - if ( v[2] > bmax[2] ) bmax[2] = v[2]; - } - - } - } - - double skinwidth = 0; - - if ( desc.HasHullFlag(QF_SKIN_WIDTH) ) - { - skinwidth = desc.mSkinWidth; - if ( skinwidth < 0 ) // if it is a negative skinwidth we shrink the hull points relative to the center. - { - double center[3]; - - center[0] = (bmax[0] - bmin[0])*0.5f + bmin[0]; - center[1] = (bmax[1] - bmin[1])*0.5f + bmin[1]; - center[2] = (bmax[2] - bmin[2])*0.5f + bmin[2]; - - double dx = (bmax[0]-bmin[0])*0.5f; - double dy = (bmax[1]-bmin[1])*0.5f; - double dz = (bmax[2]-bmin[2])*0.5f; - double dist = sqrt(dx*dx+dy*dy+dz*dz); - - skinwidth*=-1; // make it positive... - - double scale = 1.0f - (skinwidth/dist); - if ( scale < 0.3f ) scale = 0.3f; - for (unsigned int i=0; i bmax[j] ) bmax[j] = p[j]; - } - } - } - - double dx = bmax[0] - bmin[0]; - double dy = bmax[1] - bmin[1]; - double dz = bmax[2] - bmin[2]; - - double center[3]; - - center[0] = dx*0.5f + bmin[0]; - center[1] = dy*0.5f + bmin[1]; - center[2] = dz*0.5f + bmin[2]; - - if ( dx < EPSILON || dy < EPSILON || dz < EPSILON || svcount < 3 ) - { - - double len = FLT_MAX; - - if ( dx > EPSILON && dx < len ) len = dx; - if ( dy > EPSILON && dy < len ) len = dy; - if ( dz > EPSILON && dz < len ) len = dz; - - if ( len == FLT_MAX ) - { - dx = dy = dz = 0.01f; // one centimeter - } - else - { - if ( dx < EPSILON ) dx = len * 0.05f; // 1/5th the shortest non-zero edge. - if ( dy < EPSILON ) dy = len * 0.05f; - if ( dz < EPSILON ) dz = len * 0.05f; - } - - double x1 = center[0] - dx; - double x2 = center[0] + dx; - - double y1 = center[1] - dy; - double y2 = center[1] + dy; - - double z1 = center[2] - dz; - double z2 = center[2] + dz; - - AddPoint(vcount,vertices,x1,y1,z1); - AddPoint(vcount,vertices,x2,y1,z1); - AddPoint(vcount,vertices,x2,y2,z1); - AddPoint(vcount,vertices,x1,y2,z1); - AddPoint(vcount,vertices,x1,y1,z2); - AddPoint(vcount,vertices,x2,y1,z2); - AddPoint(vcount,vertices,x2,y2,z2); - AddPoint(vcount,vertices,x1,y2,z2); - - return true; // return cube - - - } - else - { - if ( scale ) - { - scale[0] = dx; - scale[1] = dy; - scale[2] = dz; - - recip[0] = 1 / dx; - recip[1] = 1 / dy; - recip[2] = 1 / dz; - - center[0]*=recip[0]; - center[1]*=recip[1]; - center[2]*=recip[2]; - - } - - } - - - - vtx = (const char *) svertices; - - for (unsigned int i=0; i dist2 ) - { - v[0] = px; - v[1] = py; - v[2] = pz; - } - - break; - } - } - - if ( j == vcount ) - { - double *dest = &vertices[vcount*3]; - dest[0] = px; - dest[1] = py; - dest[2] = pz; - vcount++; - } - } - } - - // ok..now make sure we didn't prune so many vertices it is now invalid. - if ( 1 ) - { - double bmin[3] = { FLT_MAX, FLT_MAX, FLT_MAX }; - double bmax[3] = { -FLT_MAX, -FLT_MAX, -FLT_MAX }; - - for (unsigned int i=0; i bmax[j] ) bmax[j] = p[j]; - } - } - - double dx = bmax[0] - bmin[0]; - double dy = bmax[1] - bmin[1]; - double dz = bmax[2] - bmin[2]; - - if ( dx < EPSILON || dy < EPSILON || dz < EPSILON || vcount < 3) - { - double cx = dx*0.5f + bmin[0]; - double cy = dy*0.5f + bmin[1]; - double cz = dz*0.5f + bmin[2]; - - double len = FLT_MAX; - - if ( dx >= EPSILON && dx < len ) len = dx; - if ( dy >= EPSILON && dy < len ) len = dy; - if ( dz >= EPSILON && dz < len ) len = dz; - - if ( len == FLT_MAX ) - { - dx = dy = dz = 0.01f; // one centimeter - } - else - { - if ( dx < EPSILON ) dx = len * 0.05f; // 1/5th the shortest non-zero edge. - if ( dy < EPSILON ) dy = len * 0.05f; - if ( dz < EPSILON ) dz = len * 0.05f; - } - - double x1 = cx - dx; - double x2 = cx + dx; - - double y1 = cy - dy; - double y2 = cy + dy; - - double z1 = cz - dz; - double z2 = cz + dz; - - vcount = 0; // add box - - AddPoint(vcount,vertices,x1,y1,z1); - AddPoint(vcount,vertices,x2,y1,z1); - AddPoint(vcount,vertices,x2,y2,z1); - AddPoint(vcount,vertices,x1,y2,z1); - AddPoint(vcount,vertices,x1,y1,z2); - AddPoint(vcount,vertices,x2,y1,z2); - AddPoint(vcount,vertices,x2,y2,z2); - AddPoint(vcount,vertices,x1,y2,z2); - - return true; - } - } - - return true; -} - -void HullLibrary::BringOutYourDead(const double *verts,unsigned int vcount, double *overts,unsigned int &ocount,unsigned int *indices,unsigned indexcount) -{ - unsigned int *used = (unsigned int *)NX_ALLOC(sizeof(unsigned int)*vcount, CONVEX_TEMP ); - memset(used,0,sizeof(unsigned int)*vcount); - - ocount = 0; - - for (unsigned int i=0; i= 0 && v < vcount ); - - if ( used[v] ) // if already remapped - { - indices[i] = used[v]-1; // index to new array - } - else - { - - indices[i] = ocount; // new index mapping - - overts[ocount*3+0] = verts[v*3+0]; // copy old vert to new vert array - overts[ocount*3+1] = verts[v*3+1]; - overts[ocount*3+2] = verts[v*3+2]; - - ocount++; // increment output vert count - - assert( ocount >=0 && ocount <= vcount ); - - used[v] = ocount; // assign new index remapping - } - } - - NX_FREE(used); -} - - -//================================================================================== -HullError HullLibrary::CreateTriangleMesh(HullResult &answer,ConvexHullTriangleInterface *iface) -{ - HullError ret = QE_FAIL; - - - const double *p = answer.mOutputVertices; - const unsigned int *idx = answer.mIndices; - unsigned int fcount = answer.mNumFaces; - - if ( p && idx && fcount ) - { - ret = QE_OK; - - for (unsigned int i=0; iConvexHullTriangle(v3,v2,v1); -} - -//================================================================================== -double HullLibrary::ComputeNormal(double *n,const double *A,const double *B,const double *C) -{ - double vx,vy,vz,wx,wy,wz,vw_x,vw_y,vw_z,mag; - - vx = (B[0] - C[0]); - vy = (B[1] - C[1]); - vz = (B[2] - C[2]); - - wx = (A[0] - B[0]); - wy = (A[1] - B[1]); - wz = (A[2] - B[2]); - - vw_x = vy * wz - vz * wy; - vw_y = vz * wx - vx * wz; - vw_z = vx * wy - vy * wx; - - mag = sqrt((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z)); - - if ( mag < 0.000001f ) - { - mag = 0; - } - else - { - mag = 1.0f/mag; - } - - n[0] = vw_x * mag; - n[1] = vw_y * mag; - n[2] = vw_z * mag; - - return mag; -} - - - -}; diff --git a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/cd_hull.h b/convex_decomposition/ConvexDecomposition/ConvexDecomposition/cd_hull.h deleted file mode 100644 index 68fb72a..0000000 --- a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/cd_hull.h +++ /dev/null @@ -1,250 +0,0 @@ -#ifndef HULL_LIB_H - -#define HULL_LIB_H - - -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - - - -namespace ConvexDecomposition -{ - -class HullResult -{ -public: - HullResult(void) - { - mPolygons = true; - mNumOutputVertices = 0; - mOutputVertices = 0; - mNumFaces = 0; - mNumIndices = 0; - mIndices = 0; - } - bool mPolygons; // true if indices represents polygons, false indices are triangles - unsigned int mNumOutputVertices; // number of vertices in the output hull - double *mOutputVertices; // array of vertices, 3 doubles each x,y,z - unsigned int mNumFaces; // the number of faces produced - unsigned int mNumIndices; // the total number of indices - unsigned int *mIndices; // pointer to indices. - -// If triangles, then indices are array indexes into the vertex list. -// If polygons, indices are in the form (number of points in face) (p1, p2, p3, ..) etc.. -}; - -class FHullResult -{ -public: - FHullResult(const HullResult &r) - { - mPolygons = r.mPolygons; - mNumOutputVertices = r.mNumOutputVertices; - mNumFaces = r.mNumFaces; - mNumIndices = r.mNumIndices; - mIndices = 0; - mOutputVertices = 0; - if ( mNumIndices ) - { - mIndices = new unsigned int[mNumIndices]; - memcpy(mIndices,r.mIndices,sizeof(unsigned int)*mNumIndices); - } - if ( mNumOutputVertices ) - { - mOutputVertices = new float[mNumOutputVertices*3]; - const double *src = r.mOutputVertices; - float *dst = mOutputVertices; - for (unsigned int i=0; i -#include -#include - -namespace ConvexDecomposition -{ - - -const double DEG_TO_RAD = ((2.0f * 3.14152654f) / 360.0f); -const double RAD_TO_DEG = (360.0f / (2.0f * 3.141592654f)); - -template class Vector3d -{ -public: - Vector3d(void) { }; // null constructor, does not inialize point. - - Vector3d(const Vector3d &a) // constructor copies existing vector. - { - x = a.x; - y = a.y; - z = a.z; - }; - - Vector3d(Type a,Type b,Type c) // construct with initial point. - { - x = a; - y = b; - z = c; - }; - - Vector3d(const double *t) - { - x = t[0]; - y = t[1]; - z = t[2]; - }; - - Vector3d(const int *t) - { - x = t[0]; - y = t[1]; - z = t[2]; - }; - - bool operator==(const Vector3d &a) const - { - return( a.x == x && a.y == y && a.z == z ); - }; - - bool operator!=(const Vector3d &a) const - { - return( a.x != x || a.y != y || a.z != z ); - }; - -// Operators - Vector3d& operator = (const Vector3d& A) // ASSIGNMENT (=) - { x=A.x; y=A.y; z=A.z; - return(*this); }; - - Vector3d operator + (const Vector3d& A) const // ADDITION (+) - { Vector3d Sum(x+A.x, y+A.y, z+A.z); - return(Sum); }; - - Vector3d operator - (const Vector3d& A) const // SUBTRACTION (-) - { Vector3d Diff(x-A.x, y-A.y, z-A.z); - return(Diff); }; - - Vector3d operator * (const double s) const // MULTIPLY BY SCALAR (*) - { Vector3d Scaled(x*s, y*s, z*s); - return(Scaled); }; - - - Vector3d operator + (const double s) const // ADD CONSTANT TO ALL 3 COMPONENTS (*) - { Vector3d Scaled(x+s, y+s, z+s); - return(Scaled); }; - - - - - Vector3d operator / (const double s) const // DIVIDE BY SCALAR (/) - { - double r = 1.0f / s; - Vector3d Scaled(x*r, y*r, z*r); - return(Scaled); - }; - - void operator /= (Type A) // ACCUMULATED VECTOR ADDITION (/=) - { x/=A; y/=A; z/=A; }; - - void operator += (const Vector3d A) // ACCUMULATED VECTOR ADDITION (+=) - { x+=A.x; y+=A.y; z+=A.z; }; - void operator -= (const Vector3d A) // ACCUMULATED VECTOR SUBTRACTION (+=) - { x-=A.x; y-=A.y; z-=A.z; }; - void operator *= (const double s) // ACCUMULATED SCALAR MULTIPLICATION (*=) (bpc 4/24/2000) - {x*=s; y*=s; z*=s;} - - void operator += (const double A) // ACCUMULATED VECTOR ADDITION (+=) - { x+=A; y+=A; z+=A; }; - - - Vector3d operator - (void) const // NEGATION (-) - { Vector3d Negated(-x, -y, -z); - return(Negated); }; - - Type operator [] (const int i) const // ALLOWS VECTOR ACCESS AS AN ARRAY. - { return( (i==0)?x:((i==1)?y:z) ); }; - Type & operator [] (const int i) - { return( (i==0)?x:((i==1)?y:z) ); }; -// - - // accessor methods. - Type GetX(void) const { return x; }; - Type GetY(void) const { return y; }; - Type GetZ(void) const { return z; }; - - Type X(void) const { return x; }; - Type Y(void) const { return y; }; - Type Z(void) const { return z; }; - - void SetX(Type t) { x = t; }; - void SetY(Type t) { y = t; }; - void SetZ(Type t) { z = t; }; - - bool IsSame(const Vector3d &v,double epsilon) const - { - double dx = fabsf( x - v.x ); - if ( dx > epsilon ) return false; - double dy = fabsf( y - v.y ); - if ( dy > epsilon ) return false; - double dz = fabsf( z - v.z ); - if ( dz > epsilon ) return false; - return true; - } - - - double ComputeNormal(const Vector3d &A, - const Vector3d &B, - const Vector3d &C) - { - double vx,vy,vz,wx,wy,wz,vw_x,vw_y,vw_z,mag; - - vx = (B.x - C.x); - vy = (B.y - C.y); - vz = (B.z - C.z); - - wx = (A.x - B.x); - wy = (A.y - B.y); - wz = (A.z - B.z); - - vw_x = vy * wz - vz * wy; - vw_y = vz * wx - vx * wz; - vw_z = vx * wy - vy * wx; - - mag = sqrtf((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z)); - - if ( mag < 0.000001f ) - { - mag = 0; - } - else - { - mag = 1.0f/mag; - } - - x = vw_x * mag; - y = vw_y * mag; - z = vw_z * mag; - - return mag; - } - - - void ScaleSumScale(double c0,double c1,const Vector3d &pos) - { - x = (x*c0) + (pos.x*c1); - y = (y*c0) + (pos.y*c1); - z = (z*c0) + (pos.z*c1); - } - - void SwapYZ(void) - { - double t = y; - y = z; - z = t; - }; - - void Get(Type *v) const - { - v[0] = x; - v[1] = y; - v[2] = z; - }; - - void Set(const int *p) - { - x = (Type) p[0]; - y = (Type) p[1]; - z = (Type) p[2]; - } - - void Set(const double *p) - { - x = (Type) p[0]; - y = (Type) p[1]; - z = (Type) p[2]; - } - - - void Set(Type a,Type b,Type c) - { - x = a; - y = b; - z = c; - }; - - void Zero(void) - { - x = y = z = 0; - }; - - const Type* Ptr() const { return &x; } - Type* Ptr() { return &x; } - - -// return -(*this). - Vector3d negative(void) const - { - Vector3d result; - result.x = -x; - result.y = -y; - result.z = -z; - return result; - } - - Type Magnitude(void) const - { - return Type(sqrt(x * x + y * y + z * z)); - }; - - Type FastMagnitude(void) const - { - return Type(sqrt(x * x + y * y + z * z)); - }; - - Type FasterMagnitude(void) const - { - return Type(sqrt(x * x + y * y + z * z)); - }; - - void Lerp(const Vector3d& from,const Vector3d& to,double slerp) - { - x = ((to.x - from.x) * slerp) + from.x; - y = ((to.y - from.y) * slerp) + from.y; - z = ((to.z - from.z) * slerp) + from.z; - }; - - // Highly specialized interpolate routine. Will compute the interpolated position - // shifted forward or backwards along the ray defined between (from) and (to). - // Reason for existance is so that when a bullet collides with a wall, for - // example, you can generate a graphic effect slightly *before* it hit the - // wall so that the effect doesn't sort into the wall itself. - void Interpolate(const Vector3d &from,const Vector3d &to,double offset) - { - x = to.x-from.x; - y = to.y-from.y; - z = to.z-from.z; - double d = sqrtf( x*x + y*y + z*z ); - double recip = 1.0f / d; - x*=recip; - y*=recip; - z*=recip; // normalize vector - d+=offset; // shift along ray - x = x*d + from.x; - y = y*d + from.y; - z = z*d + from.z; - }; - - bool BinaryEqual(const Vector3d &p) const - { - const int *source = (const int *) &x; - const int *dest = (const int *) &p.x; - - if ( source[0] == dest[0] && - source[1] == dest[1] && - source[2] == dest[2] ) return true; - - return false; - }; - - bool BinaryEqual(const Vector3d &p) const - { - if ( x == p.x && y == p.y && z == p.z ) return true; - return false; - } - - -/** Computes the reflection vector between two vectors.*/ - void Reflection(const Vector3d &a,const Vector3d &b)// compute reflection vector. - { - Vector3d c; - Vector3d d; - - double dot = a.Dot(b) * 2.0f; - - c = b * dot; - - d = c - a; - - x = -d.x; - y = -d.y; - z = -d.z; - }; - - void AngleAxis(Type angle,const Vector3d& axis) - { - x = axis.x*angle; - y = axis.y*angle; - z = axis.z*angle; - }; - - Type Length(void) const // length of vector. - { - return Type(sqrt( x*x + y*y + z*z )); - }; - - - double ComputePlane(const Vector3d &A, - const Vector3d &B, - const Vector3d &C) - { - double vx,vy,vz,wx,wy,wz,vw_x,vw_y,vw_z,mag; - - vx = (B.x - C.x); - vy = (B.y - C.y); - vz = (B.z - C.z); - - wx = (A.x - B.x); - wy = (A.y - B.y); - wz = (A.z - B.z); - - vw_x = vy * wz - vz * wy; - vw_y = vz * wx - vx * wz; - vw_z = vx * wy - vy * wx; - - mag = sqrt((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z)); - - if ( mag < 0.000001f ) - { - mag = 0; - } - else - { - mag = 1.0f/mag; - } - - x = vw_x * mag; - y = vw_y * mag; - z = vw_z * mag; - - - double D = 0.0f - ((x*A.x)+(y*A.y)+(z*A.z)); - - return D; - } - - - Type FastLength(void) const // length of vector. - { - return Type(sqrt( x*x + y*y + z*z )); - }; - - - Type FasterLength(void) const // length of vector. - { - return Type(sqrt( x*x + y*y + z*z )); - }; - - Type Length2(void) const // squared distance, prior to square root. - { - Type l2 = x*x+y*y+z*z; - return l2; - }; - - Type Distance(const Vector3d &a) const // distance between two points. - { - Vector3d d(a.x-x,a.y-y,a.z-z); - return d.Length(); - } - - Type FastDistance(const Vector3d &a) const // distance between two points. - { - Vector3d d(a.x-x,a.y-y,a.z-z); - return d.FastLength(); - } - - Type FasterDistance(const Vector3d &a) const // distance between two points. - { - Vector3d d(a.x-x,a.y-y,a.z-z); - return d.FasterLength(); - } - - - Type DistanceXY(const Vector3d &a) const - { - double dx = a.x - x; - double dy = a.y - y; - double dist = dx*dx + dy*dy; - return dist; - } - - Type Distance2(const Vector3d &a) const // squared distance. - { - double dx = a.x - x; - double dy = a.y - y; - double dz = a.z - z; - return dx*dx + dy*dy + dz*dz; - }; - - Type Partial(const Vector3d &p) const - { - return (x*p.y) - (p.x*y); - } - - Type Area(const Vector3d &p1,const Vector3d &p2) const - { - Type A = Partial(p1); - A+= p1.Partial(p2); - A+= p2.Partial(*this); - return A*0.5f; - } - - inline double Normalize(void) // normalize to a unit vector, returns distance. - { - double d = sqrtf( static_cast< double >( x*x + y*y + z*z ) ); - if ( d > 0 ) - { - double r = 1.0f / d; - x *= r; - y *= r; - z *= r; - } - else - { - x = y = z = 1; - } - return d; - }; - - inline double FastNormalize(void) // normalize to a unit vector, returns distance. - { - double d = sqrt( static_cast< double >( x*x + y*y + z*z ) ); - if ( d > 0 ) - { - double r = 1.0f / d; - x *= r; - y *= r; - z *= r; - } - else - { - x = y = z = 1; - } - return d; - }; - - inline double FasterNormalize(void) // normalize to a unit vector, returns distance. - { - double d = sqrt( static_cast< double >( x*x + y*y + z*z ) ); - if ( d > 0 ) - { - double r = 1.0f / d; - x *= r; - y *= r; - z *= r; - } - else - { - x = y = z = 1; - } - return d; - }; - - - - - Type Dot(const Vector3d &a) const // computes dot product. - { - return (x * a.x + y * a.y + z * a.z ); - }; - - - Vector3d Cross( const Vector3d& other ) const - { - Vector3d result( y*other.z - z*other.y, z*other.x - x*other.z, x*other.y - y*other.x ); - - return result; - } - - void Cross(const Vector3d &a,const Vector3d &b) // cross two vectors result in this one. - { - x = a.y*b.z - a.z*b.y; - y = a.z*b.x - a.x*b.z; - z = a.x*b.y - a.y*b.x; - }; - - /******************************************/ - // Check if next edge (b to c) turns inward - // - // Edge from a to b is already in face - // Edge from b to c is being considered for addition to face - /******************************************/ - bool Concave(const Vector3d& a,const Vector3d& b) - { - double vx,vy,vz,wx,wy,wz,vw_x,vw_y,vw_z,mag,nx,ny,nz,mag_a,mag_b; - - wx = b.x - a.x; - wy = b.y - a.y; - wz = b.z - a.z; - - mag_a = (double) sqrtf((wx * wx) + (wy * wy) + (wz * wz)); - - vx = x - b.x; - vy = y - b.y; - vz = z - b.z; - - mag_b = (double) sqrtf((vx * vx) + (vy * vy) + (vz * vz)); - - vw_x = (vy * wz) - (vz * wy); - vw_y = (vz * wx) - (vx * wz); - vw_z = (vx * wy) - (vy * wx); - - mag = (double) sqrtf((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z)); - - // Check magnitude of cross product, which is a sine function - // i.e., mag (a x b) = mag (a) * mag (b) * sin (theta); - // If sin (theta) small, then angle between edges is very close to - // 180, which we may want to call a concavity. Setting the - // CONCAVITY_TOLERANCE value greater than about 0.01 MAY cause - // face consolidation to get stuck on particular face. Most meshes - // convert properly with a value of 0.0 - - if (mag/(mag_a*mag_b) <= 0.0f ) return true; - - mag = 1.0f / mag; - - nx = vw_x * mag; - ny = vw_y * mag; - nz = vw_z * mag; - - // Dot product of tri normal with cross product result will - // yield positive number if edges are convex (+1.0 if two tris - // are coplanar), negative number if edges are concave (-1.0 if - // two tris are coplanar.) - - mag = ( x * nx) + ( y * ny) + ( z * nz); - - if (mag > 0.0f ) return false; - - return(true); - }; - - bool PointTestXY(const Vector3d &i,const Vector3d &j) const - { - if (((( i.y <= y ) && ( y < j.y )) || - (( j.y <= y ) && ( y < i.y ))) && - ( x < (j.x - i.x) * (y - i.y) / (j.y - i.y) + i.x)) return true; - return false; - } - - // test to see if this point is inside the triangle specified by - // these three points on the X/Y plane. - bool PointInTriXY(const Vector3d &p1, - const Vector3d &p2, - const Vector3d &p3) const - { - double ax = p3.x - p2.x; - double ay = p3.y - p2.y; - double bx = p1.x - p3.x; - double by = p1.y - p3.y; - double cx = p2.x - p1.x; - double cy = p2.y - p1.y; - double apx = x - p1.x; - double apy = y - p1.y; - double bpx = x - p2.x; - double bpy = y - p2.y; - double cpx = x - p3.x; - double cpy = y - p3.y; - - double aCROSSbp = ax*bpy - ay*bpx; - double cCROSSap = cx*apy - cy*apx; - double bCROSScp = bx*cpy - by*cpx; - - return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f)); - }; - - // test to see if this point is inside the triangle specified by - // these three points on the X/Y plane. - bool PointInTriYZ(const Vector3d &p1, - const Vector3d &p2, - const Vector3d &p3) const - { - double ay = p3.y - p2.y; - double az = p3.z - p2.z; - double by = p1.y - p3.y; - double bz = p1.z - p3.z; - double cy = p2.y - p1.y; - double cz = p2.z - p1.z; - double apy = y - p1.y; - double apz = z - p1.z; - double bpy = y - p2.y; - double bpz = z - p2.z; - double cpy = y - p3.y; - double cpz = z - p3.z; - - double aCROSSbp = ay*bpz - az*bpy; - double cCROSSap = cy*apz - cz*apy; - double bCROSScp = by*cpz - bz*cpy; - - return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f)); - }; - - - // test to see if this point is inside the triangle specified by - // these three points on the X/Y plane. - bool PointInTriXZ(const Vector3d &p1, - const Vector3d &p2, - const Vector3d &p3) const - { - double az = p3.z - p2.z; - double ax = p3.x - p2.x; - double bz = p1.z - p3.z; - double bx = p1.x - p3.x; - double cz = p2.z - p1.z; - double cx = p2.x - p1.x; - double apz = z - p1.z; - double apx = x - p1.x; - double bpz = z - p2.z; - double bpx = x - p2.x; - double cpz = z - p3.z; - double cpx = x - p3.x; - - double aCROSSbp = az*bpx - ax*bpz; - double cCROSSap = cz*apx - cx*apz; - double bCROSScp = bz*cpx - bx*cpz; - - return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f)); - }; - - // Given a point and a line (defined by two points), compute the closest point - // in the line. (The line is treated as infinitely long.) - void NearestPointInLine(const Vector3d &point, - const Vector3d &line0, - const Vector3d &line1) - { - Vector3d &nearestPoint = *this; - Vector3d lineDelta = line1 - line0; - - // Handle degenerate lines - if ( lineDelta == Vector3d(0, 0, 0) ) - { - nearestPoint = line0; - } - else - { - double delta = (point-line0).Dot(lineDelta) / (lineDelta).Dot(lineDelta); - nearestPoint = line0 + delta*lineDelta; - } - } - - // Given a point and a line segment (defined by two points), compute the closest point - // in the line. Cap the point at the endpoints of the line segment. - void NearestPointInLineSegment(const Vector3d &point, - const Vector3d &line0, - const Vector3d &line1) - { - Vector3d &nearestPoint = *this; - Vector3d lineDelta = line1 - line0; - - // Handle degenerate lines - if ( lineDelta == Vector3d(0, 0, 0) ) - { - nearestPoint = line0; - } - else - { - double delta = (point-line0).Dot(lineDelta) / (lineDelta).Dot(lineDelta); - - // Clamp the point to conform to the segment's endpoints - if ( delta < 0 ) - delta = 0; - else if ( delta > 1 ) - delta = 1; - - nearestPoint = line0 + delta*lineDelta; - } - } - - // Given a point and a plane (defined by three points), compute the closest point - // in the plane. (The plane is unbounded.) - void NearestPointInPlane(const Vector3d &point, - const Vector3d &triangle0, - const Vector3d &triangle1, - const Vector3d &triangle2) - { - Vector3d &nearestPoint = *this; - Vector3d lineDelta0 = triangle1 - triangle0; - Vector3d lineDelta1 = triangle2 - triangle0; - Vector3d pointDelta = point - triangle0; - Vector3d normal; - - // Get the normal of the polygon (doesn't have to be a unit vector) - normal.Cross(lineDelta0, lineDelta1); - - double delta = normal.Dot(pointDelta) / normal.Dot(normal); - nearestPoint = point - delta*normal; - } - - // Given a point and a plane (defined by a coplanar point and a normal), compute the closest point - // in the plane. (The plane is unbounded.) - void NearestPointInPlane(const Vector3d &point, - const Vector3d &planePoint, - const Vector3d &planeNormal) - { - Vector3d &nearestPoint = *this; - Vector3d pointDelta = point - planePoint; - - double delta = planeNormal.Dot(pointDelta) / planeNormal.Dot(planeNormal); - nearestPoint = point - delta*planeNormal; - } - - // Given a point and a triangle (defined by three points), compute the closest point - // in the triangle. Clamp the point so it's confined to the area of the triangle. - void NearestPointInTriangle(const Vector3d &point, - const Vector3d &triangle0, - const Vector3d &triangle1, - const Vector3d &triangle2) - { - static const Vector3d zeroVector(0, 0, 0); - - Vector3d &nearestPoint = *this; - - Vector3d lineDelta0 = triangle1 - triangle0; - Vector3d lineDelta1 = triangle2 - triangle0; - - // Handle degenerate triangles - if ( (lineDelta0 == zeroVector) || (lineDelta1 == zeroVector) ) - { - nearestPoint.NearestPointInLineSegment(point, triangle1, triangle2); - } - else if ( lineDelta0 == lineDelta1 ) - { - nearestPoint.NearestPointInLineSegment(point, triangle0, triangle1); - } - - else - { - static Vector3d axis[3]; - axis[0].NearestPointInLine(triangle0, triangle1, triangle2); - axis[1].NearestPointInLine(triangle1, triangle0, triangle2); - axis[2].NearestPointInLine(triangle2, triangle0, triangle1); - - Type axisDot[3]; - axisDot[0] = (triangle0-axis[0]).Dot(point-axis[0]); - axisDot[1] = (triangle1-axis[1]).Dot(point-axis[1]); - axisDot[2] = (triangle2-axis[2]).Dot(point-axis[2]); - - bool bForce = true; - Type bestMagnitude2 = 0; - Type closeMagnitude2; - Vector3d closePoint; - - if ( axisDot[0] < 0 ) - { - closePoint.NearestPointInLineSegment(point, triangle1, triangle2); - closeMagnitude2 = point.Distance2(closePoint); - if ( bForce || (bestMagnitude2 > closeMagnitude2) ) - { - bForce = false; - bestMagnitude2 = closeMagnitude2; - nearestPoint = closePoint; - } - } - if ( axisDot[1] < 0 ) - { - closePoint.NearestPointInLineSegment(point, triangle0, triangle2); - closeMagnitude2 = point.Distance2(closePoint); - if ( bForce || (bestMagnitude2 > closeMagnitude2) ) - { - bForce = false; - bestMagnitude2 = closeMagnitude2; - nearestPoint = closePoint; - } - } - if ( axisDot[2] < 0 ) - { - closePoint.NearestPointInLineSegment(point, triangle0, triangle1); - closeMagnitude2 = point.Distance2(closePoint); - if ( bForce || (bestMagnitude2 > closeMagnitude2) ) - { - bForce = false; - bestMagnitude2 = closeMagnitude2; - nearestPoint = closePoint; - } - } - - // If bForce is true at this point, it means the nearest point lies - // inside the triangle; use the nearest-point-on-a-plane equation - if ( bForce ) - { - Vector3d normal; - - // Get the normal of the polygon (doesn't have to be a unit vector) - normal.Cross(lineDelta0, lineDelta1); - - Vector3d pointDelta = point - triangle0; - double delta = normal.Dot(pointDelta) / normal.Dot(normal); - - nearestPoint = point - delta*normal; - } - } - } - - -//private: - - Type x; - Type y; - Type z; -}; - - -template class Vector2d -{ -public: - Vector2d(void) { }; // null constructor, does not inialize point. - - Vector2d(const Vector2d &a) // constructor copies existing vector. - { - x = a.x; - y = a.y; - }; - - Vector2d(const double *t) - { - x = t[0]; - y = t[1]; - }; - - - Vector2d(Type a,Type b) // construct with initial point. - { - x = a; - y = b; - }; - - const Type* Ptr() const { return &x; } - Type* Ptr() { return &x; } - - Vector2d & operator+=(const Vector2d &a) // += operator. - { - x+=a.x; - y+=a.y; - return *this; - }; - - Vector2d & operator-=(const Vector2d &a) - { - x-=a.x; - y-=a.y; - return *this; - }; - - Vector2d & operator*=(const Vector2d &a) - { - x*=a.x; - y*=a.y; - return *this; - }; - - Vector2d & operator/=(const Vector2d &a) - { - x/=a.x; - y/=a.y; - return *this; - }; - - bool operator==(const Vector2d &a) const - { - if ( a.x == x && a.y == y ) return true; - return false; - }; - - bool operator!=(const Vector2d &a) const - { - if ( a.x != x || a.y != y ) return true; - return false; - }; - - Vector2d operator+(Vector2d a) const - { - a.x+=x; - a.y+=y; - return a; - }; - - Vector2d operator-(Vector2d a) const - { - a.x = x-a.x; - a.y = y-a.y; - return a; - }; - - Vector2d operator - (void) const - { - return negative(); - }; - - Vector2d operator*(Vector2d a) const - { - a.x*=x; - a.y*=y; - return a; - }; - - Vector2d operator*(Type c) const - { - Vector2d a; - - a.x = x * c; - a.y = y * c; - - return a; - }; - - Vector2d operator/(Vector2d a) const - { - a.x = x/a.x; - a.y = y/a.y; - return a; - }; - - - Type Dot(const Vector2d &a) const // computes dot product. - { - return (x * a.x + y * a.y ); - }; - - Type GetX(void) const { return x; }; - Type GetY(void) const { return y; }; - - void SetX(Type t) { x = t; }; - void SetY(Type t) { y = t; }; - - void Set(Type a,Type b) - { - x = a; - y = b; - }; - - void Zero(void) - { - x = 0; - y = 0; - }; - - Vector2d negative(void) const - { - Vector2d result; - result.x = -x; - result.y = -y; - return result; - } - - Type magnitude(void) const - { - return (Type) sqrtf(x * x + y * y ); - } - - Type fastmagnitude(void) const - { - return (Type) sqrt(x * x + y * y ); - } - - Type fastermagnitude(void) const - { - return (Type) sqrt( x * x + y * y ); - } - - void Reflection(Vector2d &a,Vector2d &b); // compute reflection vector. - - Type Length(void) const // length of vector. - { - return Type(sqrtf( x*x + y*y )); - }; - - Type FastLength(void) const // length of vector. - { - return Type(sqrt( x*x + y*y )); - }; - - Type FasterLength(void) const // length of vector. - { - return Type(sqrt( x*x + y*y )); - }; - - Type Length2(void) // squared distance, prior to square root. - { - return x*x+y*y; - } - - Type Distance(const Vector2d &a) const // distance between two points. - { - Type dx = a.x - x; - Type dy = a.y - y; - Type d = dx*dx+dy*dy; - return sqrtf(d); - }; - - Type FastDistance(const Vector2d &a) const // distance between two points. - { - Type dx = a.x - x; - Type dy = a.y - y; - Type d = dx*dx+dy*dy; - return sqrt(d); - }; - - Type FasterDistance(const Vector2d &a) const // distance between two points. - { - Type dx = a.x - x; - Type dy = a.y - y; - Type d = dx*dx+dy*dy; - return sqrt(d); - }; - - Type Distance2(Vector2d &a) // squared distance. - { - Type dx = a.x - x; - Type dy = a.y - y; - return dx*dx + dy *dy; - }; - - void Lerp(const Vector2d& from,const Vector2d& to,double slerp) - { - x = ((to.x - from.x)*slerp) + from.x; - y = ((to.y - from.y)*slerp) + from.y; - }; - - - void Cross(const Vector2d &a,const Vector2d &b) // cross two vectors result in this one. - { - x = a.y*b.x - a.x*b.y; - y = a.x*b.x - a.x*b.x; - }; - - Type Normalize(void) // normalize to a unit vector, returns distance. - { - Type l = Length(); - if ( l != 0 ) - { - l = Type( 1 ) / l; - x*=l; - y*=l; - } - else - { - x = y = 0; - } - return l; - }; - - Type FastNormalize(void) // normalize to a unit vector, returns distance. - { - Type l = FastLength(); - if ( l != 0 ) - { - l = Type( 1 ) / l; - x*=l; - y*=l; - } - else - { - x = y = 0; - } - return l; - }; - - Type FasterNormalize(void) // normalize to a unit vector, returns distance. - { - Type l = FasterLength(); - if ( l != 0 ) - { - l = Type( 1 ) / l; - x*=l; - y*=l; - } - else - { - x = y = 0; - } - return l; - }; - - - Type x; - Type y; -}; - -class Line -{ -public: - Line(const Vector3d &from,const Vector3d &to) - { - mP1 = from; - mP2 = to; - }; - // JWR Test for the intersection of two lines. - - bool Intersect(const Line& src,Vector3d §); -private: - Vector3d mP1; - Vector3d mP2; - -}; - - -typedef std::vector< Vector3d > Vector3dVector; -typedef std::vector< Vector2d > Vector2dVector; - -template Vector3d operator * (Type s, const Vector3d &v ) - { Vector3d Scaled(v.x*s, v.y*s, v.z*s); - return(Scaled); }; - -template Vector2d operator * (Type s, const Vector2d &v ) - { Vector2d Scaled(v.x*s, v.y*s); - return(Scaled); }; - -}; - -#endif diff --git a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/cd_wavefront.cpp b/convex_decomposition/ConvexDecomposition/ConvexDecomposition/cd_wavefront.cpp deleted file mode 100644 index 04b7b8c..0000000 --- a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/cd_wavefront.cpp +++ /dev/null @@ -1,858 +0,0 @@ -#include -#include -#include -#include -#include - -#pragma warning(disable:4996) - -#include "cd_wavefront.h" - - -using namespace ConvexDecomposition; - -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - - - -#include - -namespace ConvexDecomposition -{ - -typedef std::vector< int > IntVector; -typedef std::vector< double > FloatVector; - -#if defined(__APPLE__) || defined(__CELLOS_LV2__) -#define stricmp(a, b) strcasecmp((a), (b)) -#endif - -/*******************************************************************/ -/******************** InParser.h ********************************/ -/*******************************************************************/ -class InPlaceParserInterface -{ -public: - virtual int ParseLine(int lineno,int argc,const char **argv) =0; // return TRUE to continue parsing, return FALSE to abort parsing process -}; - -enum SeparatorType -{ - ST_DATA, // is data - ST_HARD, // is a hard separator - ST_SOFT, // is a soft separator - ST_EOS // is a comment symbol, and everything past this character should be ignored -}; - -class InPlaceParser -{ -public: - InPlaceParser(void) - { - Init(); - } - - InPlaceParser(char *data,int len) - { - Init(); - SetSourceData(data,len); - } - - InPlaceParser(const char *fname) - { - Init(); - SetFile(fname); - } - - ~InPlaceParser(void); - - void Init(void) - { - mQuoteChar = 34; - mData = 0; - mLen = 0; - mMyAlloc = false; - for (int i=0; i<256; i++) - { - mHard[i] = ST_DATA; - mHardString[i*2] = i; - mHardString[i*2+1] = 0; - } - mHard[0] = ST_EOS; - mHard[32] = ST_SOFT; - mHard[9] = ST_SOFT; - mHard[13] = ST_SOFT; - mHard[10] = ST_SOFT; - } - - void SetFile(const char *fname); // use this file as source data to parse. - - void SetSourceData(char *data,int len) - { - mData = data; - mLen = len; - mMyAlloc = false; - }; - - int Parse(InPlaceParserInterface *callback); // returns true if entire file was parsed, false if it aborted for some reason - - int ProcessLine(int lineno,char *line,InPlaceParserInterface *callback); - - const char ** GetArglist(char *source,int &count); // convert source string into an arg list, this is a destructive parse. - - void SetHardSeparator(char c) // add a hard separator - { - mHard[c] = ST_HARD; - } - - void SetHard(char c) // add a hard separator - { - mHard[c] = ST_HARD; - } - - - void SetCommentSymbol(char c) // comment character, treated as 'end of string' - { - mHard[c] = ST_EOS; - } - - void ClearHardSeparator(char c) - { - mHard[c] = ST_DATA; - } - - - void DefaultSymbols(void); // set up default symbols for hard seperator and comment symbol of the '#' character. - - bool EOS(char c) - { - if ( mHard[c] == ST_EOS ) - { - return true; - } - return false; - } - - void SetQuoteChar(char c) - { - mQuoteChar = c; - } - -private: - - - inline char * AddHard(int &argc,const char **argv,char *foo); - inline bool IsHard(char c); - inline char * SkipSpaces(char *foo); - inline bool IsWhiteSpace(char c); - inline bool IsNonSeparator(char c); // non seperator,neither hard nor soft - - bool mMyAlloc; // whether or not *I* allocated the buffer and am responsible for deleting it. - char *mData; // ascii data to parse. - int mLen; // length of data - SeparatorType mHard[256]; - char mHardString[256*2]; - char mQuoteChar; -}; - -/*******************************************************************/ -/******************** InParser.cpp ********************************/ -/*******************************************************************/ -void InPlaceParser::SetFile(const char *fname) -{ - if ( mMyAlloc ) - { - free(mData); - } - mData = 0; - mLen = 0; - mMyAlloc = false; - - - FILE *fph = fopen(fname,"rb"); - if ( fph ) - { - fseek(fph,0L,SEEK_END); - mLen = ftell(fph); - fseek(fph,0L,SEEK_SET); - if ( mLen ) - { - mData = (char *) malloc(sizeof(char)*(mLen+1)); - int ok = fread(mData, mLen, 1, fph); - if ( !ok ) - { - free(mData); - mData = 0; - } - else - { - mData[mLen] = 0; // zero byte terminate end of file marker. - mMyAlloc = true; - } - } - fclose(fph); - } -} - -InPlaceParser::~InPlaceParser(void) -{ - if ( mMyAlloc ) - { - free(mData); - } -} - -#define MAXARGS 512 - -bool InPlaceParser::IsHard(char c) -{ - return mHard[c] == ST_HARD; -} - -char * InPlaceParser::AddHard(int &argc,const char **argv,char *foo) -{ - while ( IsHard(*foo) ) - { - const char *hard = &mHardString[*foo*2]; - if ( argc < MAXARGS ) - { - argv[argc++] = hard; - } - foo++; - } - return foo; -} - -bool InPlaceParser::IsWhiteSpace(char c) -{ - return mHard[c] == ST_SOFT; -} - -char * InPlaceParser::SkipSpaces(char *foo) -{ - while ( !EOS(*foo) && IsWhiteSpace(*foo) ) foo++; - return foo; -} - -bool InPlaceParser::IsNonSeparator(char c) -{ - if ( !IsHard(c) && !IsWhiteSpace(c) && c != 0 ) return true; - return false; -} - - -int InPlaceParser::ProcessLine(int lineno,char *line,InPlaceParserInterface *callback) -{ - int ret = 0; - - const char *argv[MAXARGS]; - int argc = 0; - - char *foo = line; - - while ( !EOS(*foo) && argc < MAXARGS ) - { - - foo = SkipSpaces(foo); // skip any leading spaces - - if ( EOS(*foo) ) break; - - if ( *foo == mQuoteChar ) // if it is an open quote - { - foo++; - if ( argc < MAXARGS ) - { - argv[argc++] = foo; - } - while ( !EOS(*foo) && *foo != mQuoteChar ) foo++; - if ( !EOS(*foo) ) - { - *foo = 0; // replace close quote with zero byte EOS - foo++; - } - } - else - { - - foo = AddHard(argc,argv,foo); // add any hard separators, skip any spaces - - if ( IsNonSeparator(*foo) ) // add non-hard argument. - { - bool quote = false; - if ( *foo == mQuoteChar ) - { - foo++; - quote = true; - } - - if ( argc < MAXARGS ) - { - argv[argc++] = foo; - } - - if ( quote ) - { - while (*foo && *foo != mQuoteChar ) foo++; - if ( *foo ) *foo = 32; - } - - // continue..until we hit an eos .. - while ( !EOS(*foo) ) // until we hit EOS - { - if ( IsWhiteSpace(*foo) ) // if we hit a space, stomp a zero byte, and exit - { - *foo = 0; - foo++; - break; - } - else if ( IsHard(*foo) ) // if we hit a hard separator, stomp a zero byte and store the hard separator argument - { - const char *hard = &mHardString[*foo*2]; - *foo = 0; - if ( argc < MAXARGS ) - { - argv[argc++] = hard; - } - foo++; - break; - } - foo++; - } // end of while loop... - } - } - } - - if ( argc ) - { - ret = callback->ParseLine(lineno, argc, argv ); - } - - return ret; -} - -int InPlaceParser::Parse(InPlaceParserInterface *callback) // returns true if entire file was parsed, false if it aborted for some reason -{ - assert( callback ); - if ( !mData ) return 0; - - int ret = 0; - - int lineno = 0; - - char *foo = mData; - char *begin = foo; - - - while ( *foo ) - { - if ( *foo == 10 || *foo == 13 ) - { - lineno++; - *foo = 0; - - if ( *begin ) // if there is any data to parse at all... - { - int v = ProcessLine(lineno,begin,callback); - if ( v ) ret = v; - } - - foo++; - if ( *foo == 10 ) foo++; // skip line feed, if it is in the carraige-return line-feed format... - begin = foo; - } - else - { - foo++; - } - } - - lineno++; // lasst line. - - int v = ProcessLine(lineno,begin,callback); - if ( v ) ret = v; - return ret; -} - - -void InPlaceParser::DefaultSymbols(void) -{ - SetHardSeparator(','); - SetHardSeparator('('); - SetHardSeparator(')'); - SetHardSeparator('='); - SetHardSeparator('['); - SetHardSeparator(']'); - SetHardSeparator('{'); - SetHardSeparator('}'); - SetCommentSymbol('#'); -} - - -const char ** InPlaceParser::GetArglist(char *line,int &count) // convert source string into an arg list, this is a destructive parse. -{ - const char **ret = 0; - - static const char *argv[MAXARGS]; - int argc = 0; - - char *foo = line; - - while ( !EOS(*foo) && argc < MAXARGS ) - { - - foo = SkipSpaces(foo); // skip any leading spaces - - if ( EOS(*foo) ) break; - - if ( *foo == mQuoteChar ) // if it is an open quote - { - foo++; - if ( argc < MAXARGS ) - { - argv[argc++] = foo; - } - while ( !EOS(*foo) && *foo != mQuoteChar ) foo++; - if ( !EOS(*foo) ) - { - *foo = 0; // replace close quote with zero byte EOS - foo++; - } - } - else - { - - foo = AddHard(argc,argv,foo); // add any hard separators, skip any spaces - - if ( IsNonSeparator(*foo) ) // add non-hard argument. - { - bool quote = false; - if ( *foo == mQuoteChar ) - { - foo++; - quote = true; - } - - if ( argc < MAXARGS ) - { - argv[argc++] = foo; - } - - if ( quote ) - { - while (*foo && *foo != mQuoteChar ) foo++; - if ( *foo ) *foo = 32; - } - - // continue..until we hit an eos .. - while ( !EOS(*foo) ) // until we hit EOS - { - if ( IsWhiteSpace(*foo) ) // if we hit a space, stomp a zero byte, and exit - { - *foo = 0; - foo++; - break; - } - else if ( IsHard(*foo) ) // if we hit a hard separator, stomp a zero byte and store the hard separator argument - { - const char *hard = &mHardString[*foo*2]; - *foo = 0; - if ( argc < MAXARGS ) - { - argv[argc++] = hard; - } - foo++; - break; - } - foo++; - } // end of while loop... - } - } - } - - count = argc; - if ( argc ) - { - ret = argv; - } - - return ret; -} - -/*******************************************************************/ -/******************** Geometry.h ********************************/ -/*******************************************************************/ - -class GeometryVertex -{ -public: - double mPos[3]; - double mNormal[3]; - double mTexel[2]; -}; - - -class GeometryInterface -{ -public: - - virtual void NodeTriangle(const GeometryVertex *v1,const GeometryVertex *v2,const GeometryVertex *v3) - { - } - -}; - - -/*******************************************************************/ -/******************** Obj.h ********************************/ -/*******************************************************************/ - - -class OBJ : public InPlaceParserInterface -{ -public: - int LoadMesh(const char *fname,GeometryInterface *callback); - int ParseLine(int lineno,int argc,const char **argv); // return TRUE to continue parsing, return FALSE to abort parsing process -private: - - void GetVertex(GeometryVertex &v,const char *face) const; - - FloatVector mVerts; - FloatVector mTexels; - FloatVector mNormals; - - GeometryInterface *mCallback; - friend class WavefrontObj; -}; - - -/*******************************************************************/ -/******************** Obj.cpp ********************************/ -/*******************************************************************/ - -int OBJ::LoadMesh(const char *fname,GeometryInterface *iface) -{ - int ret = 0; - - mVerts.clear(); - mTexels.clear(); - mNormals.clear(); - - mCallback = iface; - - InPlaceParser ipp(fname); - - ipp.Parse(this); - - - return ret; -} - -static const char * GetArg(const char **argv,int i,int argc) -{ - const char * ret = 0; - if ( i < argc ) ret = argv[i]; - return ret; -} - -void OBJ::GetVertex(GeometryVertex &v,const char *face) const -{ - v.mPos[0] = 0; - v.mPos[1] = 0; - v.mPos[2] = 0; - - v.mTexel[0] = 0; - v.mTexel[1] = 0; - - v.mNormal[0] = 0; - v.mNormal[1] = 1; - v.mNormal[2] = 0; - - int index = atoi( face )-1; - - const char *texel = strstr(face,"/"); - - if ( texel ) - { - int tindex = atoi( texel+1) - 1; - - if ( tindex >=0 && tindex < (int)(mTexels.size()/2) ) - { - const double *t = &mTexels[tindex*2]; - - v.mTexel[0] = t[0]; - v.mTexel[1] = t[1]; - - } - - const char *normal = strstr(texel+1,"/"); - if ( normal ) - { - int nindex = atoi( normal+1 ) - 1; - - if (nindex >= 0 && nindex < (int)(mNormals.size()/3) ) - { - const double *n = &mNormals[nindex*3]; - - v.mNormal[0] = n[0]; - v.mNormal[1] = n[1]; - v.mNormal[2] = n[2]; - } - } - } - - if ( index >= 0 && index < (int)(mVerts.size()/3) ) - { - - const double *p = &mVerts[index*3]; - - v.mPos[0] = p[0]; - v.mPos[1] = p[1]; - v.mPos[2] = p[2]; - } - -} - -int OBJ::ParseLine(int lineno,int argc,const char **argv) // return TRUE to continue parsing, return FALSE to abort parsing process -{ - int ret = 0; - - if ( argc >= 1 ) - { - const char *foo = argv[0]; - if ( *foo != '#' ) - { - if ( strcmp(argv[0],"v") == 0 && argc == 4 ) - { - double vx = (double) atof( argv[1] ); - double vy = (double) atof( argv[2] ); - double vz = (double) atof( argv[3] ); - mVerts.push_back(vx); - mVerts.push_back(vy); - mVerts.push_back(vz); - } - else if ( strcmp(argv[0],"vt") == 0 && argc == 3 ) - { - double tx = (double) atof( argv[1] ); - double ty = (double) atof( argv[2] ); - mTexels.push_back(tx); - mTexels.push_back(ty); - } - else if ( strcmp(argv[0],"vn") == 0 && argc == 4 ) - { - double normalx = (double) atof(argv[1]); - double normaly = (double) atof(argv[2]); - double normalz = (double) atof(argv[3]); - mNormals.push_back(normalx); - mNormals.push_back(normaly); - mNormals.push_back(normalz); - } - else if ( strcmp(argv[0],"f") == 0 && argc >= 4 ) - { - GeometryVertex v[32]; - - int vcount = argc-1; - - for (int i=1; i p1( v[0].mPos ); - Vector3d p2( v[1].mPos ); - Vector3d p3( v[2].mPos ); - - Vector3d n; - n.ComputeNormal(p3,p2,p1); - - for (int i=0; iNodeTriangle(&v[0],&v[1],&v[2]); - - if ( vcount >=3 ) // do the fan - { - for (int i=2; i<(vcount-1); i++) - { - mCallback->NodeTriangle(&v[0],&v[i],&v[i+1]); - } - } - - } - } - } - - return ret; -} - - - - -class BuildMesh : public GeometryInterface -{ -public: - - int GetIndex(const double *p) - { - - int vcount = mVertices.size()/3; - - if(vcount>0) - { - //New MS STL library checks indices in debug build, so zero causes an assert if it is empty. - const double *v = &mVertices[0]; - - for (int i=0; imPos) ); - mIndices.push_back( GetIndex(v2->mPos) ); - mIndices.push_back( GetIndex(v3->mPos) ); - } - - const FloatVector& GetVertices(void) const { return mVertices; }; - const IntVector& GetIndices(void) const { return mIndices; }; - -private: - FloatVector mVertices; - IntVector mIndices; -}; - - -WavefrontObj::WavefrontObj(void) -{ - mVertexCount = 0; - mTriCount = 0; - mIndices = 0; - mVertices = 0; -} - -WavefrontObj::~WavefrontObj(void) -{ - delete mIndices; - delete mVertices; -} - -unsigned int WavefrontObj::loadObj(const char *fname) // load a wavefront obj returns number of triangles that were loaded. Data is persists until the class is destructed. -{ - - unsigned int ret = 0; - - delete mVertices; - mVertices = 0; - delete mIndices; - mIndices = 0; - mVertexCount = 0; - mTriCount = 0; - - - BuildMesh bm; - - OBJ obj; - - obj.LoadMesh(fname,&bm); - - - const FloatVector &vlist = bm.GetVertices(); - const IntVector &indices = bm.GetIndices(); - if ( vlist.size() ) - { - mVertexCount = vlist.size()/3; - mVertices = new double[mVertexCount*3]; - memcpy( mVertices, &vlist[0], sizeof(double)*mVertexCount*3 ); - mTriCount = indices.size()/3; - mIndices = new int[mTriCount*3*sizeof(int)]; - memcpy(mIndices, &indices[0], sizeof(int)*mTriCount*3); - ret = mTriCount; - } - else if( obj.mVerts.size() > 0 ) { - // take consecutive vertices - mVertexCount = obj.mVerts.size()/3; - mVertices = new double[mVertexCount*3]; - memcpy( mVertices, &obj.mVerts[0], sizeof(double)*mVertexCount*3 ); - mTriCount = mVertexCount/3; - mIndices = new int[mTriCount*3*sizeof(int)]; - for(int i = 0; i < mVertexCount; ++i) - mIndices[i] = i; - ret = mTriCount; - } - - return ret; -} - -}; diff --git a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/cd_wavefront.h b/convex_decomposition/ConvexDecomposition/ConvexDecomposition/cd_wavefront.h deleted file mode 100644 index 4eff55c..0000000 --- a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/cd_wavefront.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef CD_WAVEFRONT_OBJ_H - - -#define CD_WAVEFRONT_OBJ_H - -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - - - -namespace ConvexDecomposition -{ - -class WavefrontObj -{ -public: - - WavefrontObj(void); - ~WavefrontObj(void); - - unsigned int loadObj(const char *fname); // load a wavefront obj returns number of triangles that were loaded. Data is persists until the class is destructed. - - int mVertexCount; - int mTriCount; - int *mIndices; - double *mVertices; -}; - -}; - -#endif diff --git a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/concavity.cpp b/convex_decomposition/ConvexDecomposition/ConvexDecomposition/concavity.cpp deleted file mode 100644 index 77cbd7b..0000000 --- a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/concavity.cpp +++ /dev/null @@ -1,821 +0,0 @@ -#include -#include -#include -#include - -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - - - -#include - -#include "concavity.h" -#include "raytri.h" -#include "bestfit.h" -#include "cd_hull.h" -#include "meshvolume.h" -#include "cd_vector.h" -#include "splitplane.h" -#include "ConvexDecomposition.h" - - -#define WSCALE 4 -#define CONCAVE_THRESH 0.05f - -namespace ConvexDecomposition -{ - -unsigned int getDebugColor(void) -{ - static unsigned int colors[8] = - { - 0xFF0000, - 0x00FF00, - 0x0000FF, - 0xFFFF00, - 0x00FFFF, - 0xFF00FF, - 0xFFFFFF, - 0xFF8040 - }; - - static int count = 0; - - count++; - - if ( count == 8 ) count = 0; - - assert( count >= 0 && count < 8 ); - - unsigned int color = colors[count]; - - return color; - -} - -class Wpoint -{ -public: - Wpoint(const Vector3d &p,double w) - { - mPoint = p; - mWeight = w; - } - - Vector3d mPoint; - double mWeight; -}; - -typedef std::vector< Wpoint > WpointVector; - - -static inline double DistToPt(const double *p,const double *plane) -{ - double x = p[0]; - double y = p[1]; - double z = p[2]; - double d = x*plane[0] + y*plane[1] + z*plane[2] + plane[3]; - return d; -} - - -static void intersect(const double *p1,const double *p2,double *split,const double *plane) -{ - - double dp1 = DistToPt(p1,plane); - double dp2 = DistToPt(p2,plane); - - double dir[3]; - - dir[0] = p2[0] - p1[0]; - dir[1] = p2[1] - p1[1]; - dir[2] = p2[2] - p1[2]; - - double dot1 = dir[0]*plane[0] + dir[1]*plane[1] + dir[2]*plane[2]; - double dot2 = dp1 - plane[3]; - - double t = -(plane[3] + dot2 ) / dot1; - - split[0] = (dir[0]*t)+p1[0]; - split[1] = (dir[1]*t)+p1[1]; - split[2] = (dir[2]*t)+p1[2]; - -} - - -class CTri -{ -public: - CTri(void) { }; - - CTri(const double *p1,const double *p2,const double *p3,unsigned int i1,unsigned int i2,unsigned int i3) - { - mProcessed = 0; - mI1 = i1; - mI2 = i2; - mI3 = i3; - - mP1.Set(p1); - mP2.Set(p2); - mP3.Set(p3); - - mPlaneD = mNormal.ComputePlane(mP1,mP2,mP3); - } - - double Facing(const CTri &t) - { - double d = mNormal.Dot(t.mNormal); - return d; - } - - // clip this line segment against this triangle. - bool clip(const Vector3d &start,Vector3d &end) const - { - Vector3d sect; - - bool hit = lineIntersectsTriangle(start.Ptr(), end.Ptr(), mP1.Ptr(), mP2.Ptr(), mP3.Ptr(), sect.Ptr() ); - - if ( hit ) - { - end = sect; - } - return hit; - } - - bool Concave(const Vector3d &p,double &distance,Vector3d &n) const - { - n.NearestPointInTriangle(p,mP1,mP2,mP3); - distance = p.Distance(n); - return true; - } - - void addTri(unsigned int *indices,unsigned int i1,unsigned int i2,unsigned int i3,unsigned int &tcount) const - { - indices[tcount*3+0] = i1; - indices[tcount*3+1] = i2; - indices[tcount*3+2] = i3; - tcount++; - } - - double getVolume(ConvexDecompInterface *callback) const - { - unsigned int indices[8*3]; - - - unsigned int tcount = 0; - - addTri(indices,0,1,2,tcount); - addTri(indices,3,4,5,tcount); - - addTri(indices,0,3,4,tcount); - addTri(indices,0,4,1,tcount); - - addTri(indices,1,4,5,tcount); - addTri(indices,1,5,2,tcount); - - addTri(indices,0,3,5,tcount); - addTri(indices,0,5,2,tcount); - - const double *vertices = mP1.Ptr(); - - if ( callback ) - { - unsigned int color = getDebugColor(); - -#if 0 - Vector3d d1 = mNear1; - Vector3d d2 = mNear2; - Vector3d d3 = mNear3; - - callback->ConvexDebugPoint(mP1.Ptr(),0.01f,0x00FF00); - callback->ConvexDebugPoint(mP2.Ptr(),0.01f,0x00FF00); - callback->ConvexDebugPoint(mP3.Ptr(),0.01f,0x00FF00); - callback->ConvexDebugPoint(d1.Ptr(),0.01f,0xFF0000); - callback->ConvexDebugPoint(d2.Ptr(),0.01f,0xFF0000); - callback->ConvexDebugPoint(d3.Ptr(),0.01f,0xFF0000); - - callback->ConvexDebugTri(mP1.Ptr(), d1.Ptr(), d1.Ptr(),0x00FF00); - callback->ConvexDebugTri(mP2.Ptr(), d2.Ptr(), d2.Ptr(),0x00FF00); - callback->ConvexDebugTri(mP3.Ptr(), d3.Ptr(), d3.Ptr(),0x00FF00); - -#else - for (unsigned int i=0; iConvexDebugTri(p1,p2,p3,color); - - } -#endif - } - - double v = computeMeshVolume(mP1.Ptr(), tcount, indices ); - - return v; - - } - - double raySect(const Vector3d &p,const Vector3d &dir,Vector3d §) const - { - double plane[4]; - - plane[0] = mNormal.x; - plane[1] = mNormal.y; - plane[2] = mNormal.z; - plane[3] = mPlaneD; - - Vector3d dest = p+dir*100000; - - intersect( p.Ptr(), dest.Ptr(), sect.Ptr(), plane ); - - return sect.Distance(p); // return the intersection distance. - - } - - double planeDistance(const Vector3d &p) const - { - double plane[4]; - - plane[0] = mNormal.x; - plane[1] = mNormal.y; - plane[2] = mNormal.z; - plane[3] = mPlaneD; - - return DistToPt( p.Ptr(), plane ); - - } - - bool samePlane(const CTri &t) const - { - const double THRESH = 0.001f; - double dd = fabs( t.mPlaneD - mPlaneD ); - if ( dd > THRESH ) return false; - dd = fabs( t.mNormal.x - mNormal.x ); - if ( dd > THRESH ) return false; - dd = fabs( t.mNormal.y - mNormal.y ); - if ( dd > THRESH ) return false; - dd = fabs( t.mNormal.z - mNormal.z ); - if ( dd > THRESH ) return false; - return true; - } - - bool hasIndex(unsigned int i) const - { - if ( i == mI1 || i == mI2 || i == mI3 ) return true; - return false; - } - - bool sharesEdge(const CTri &t) const - { - bool ret = false; - unsigned int count = 0; - - if ( t.hasIndex(mI1) ) count++; - if ( t.hasIndex(mI2) ) count++; - if ( t.hasIndex(mI3) ) count++; - - if ( count >= 2 ) ret = true; - - return ret; - } - - void debug(unsigned int color,ConvexDecompInterface *callback) - { - callback->ConvexDebugTri( mP1.Ptr(), mP2.Ptr(), mP3.Ptr(), color ); - callback->ConvexDebugTri( mP1.Ptr(), mP1.Ptr(), mNear1.Ptr(), 0xFF0000 ); - callback->ConvexDebugTri( mP2.Ptr(), mP2.Ptr(), mNear2.Ptr(), 0xFF0000 ); - callback->ConvexDebugTri( mP2.Ptr(), mP3.Ptr(), mNear3.Ptr(), 0xFF0000 ); - callback->ConvexDebugPoint( mNear1.Ptr(), 0.01f, 0xFF0000 ); - callback->ConvexDebugPoint( mNear2.Ptr(), 0.01f, 0xFF0000 ); - callback->ConvexDebugPoint( mNear3.Ptr(), 0.01f, 0xFF0000 ); - } - - double area(void) - { - double a = mConcavity*mP1.Area(mP2,mP3); - return a; - } - - void addWeighted(WpointVector &list,ConvexDecompInterface *callback) - { - - Wpoint p1(mP1,mC1); - Wpoint p2(mP2,mC2); - Wpoint p3(mP3,mC3); - - Vector3d d1 = mNear1 - mP1; - Vector3d d2 = mNear2 - mP2; - Vector3d d3 = mNear3 - mP3; - - d1*=WSCALE; - d2*=WSCALE; - d3*=WSCALE; - - d1 = d1 + mP1; - d2 = d2 + mP2; - d3 = d3 + mP3; - - Wpoint p4(d1,mC1); - Wpoint p5(d2,mC2); - Wpoint p6(d3,mC3); - - list.push_back(p1); - list.push_back(p2); - list.push_back(p3); - - list.push_back(p4); - list.push_back(p5); - list.push_back(p6); - -#if 0 - callback->ConvexDebugPoint(mP1.Ptr(),0.01f,0x00FF00); - callback->ConvexDebugPoint(mP2.Ptr(),0.01f,0x00FF00); - callback->ConvexDebugPoint(mP3.Ptr(),0.01f,0x00FF00); - callback->ConvexDebugPoint(d1.Ptr(),0.01f,0xFF0000); - callback->ConvexDebugPoint(d2.Ptr(),0.01f,0xFF0000); - callback->ConvexDebugPoint(d3.Ptr(),0.01f,0xFF0000); - - callback->ConvexDebugTri(mP1.Ptr(), d1.Ptr(), d1.Ptr(),0x00FF00); - callback->ConvexDebugTri(mP2.Ptr(), d2.Ptr(), d2.Ptr(),0x00FF00); - callback->ConvexDebugTri(mP3.Ptr(), d3.Ptr(), d3.Ptr(),0x00FF00); - - Vector3d np1 = mP1 + mNormal*0.05f; - Vector3d np2 = mP2 + mNormal*0.05f; - Vector3d np3 = mP3 + mNormal*0.05f; - - callback->ConvexDebugTri(mP1.Ptr(), np1.Ptr(), np1.Ptr(), 0xFF00FF ); - callback->ConvexDebugTri(mP2.Ptr(), np2.Ptr(), np2.Ptr(), 0xFF00FF ); - callback->ConvexDebugTri(mP3.Ptr(), np3.Ptr(), np3.Ptr(), 0xFF00FF ); - - callback->ConvexDebugPoint( np1.Ptr(), 0.01F, 0XFF00FF ); - callback->ConvexDebugPoint( np2.Ptr(), 0.01F, 0XFF00FF ); - callback->ConvexDebugPoint( np3.Ptr(), 0.01F, 0XFF00FF ); - -#endif - - - - } - - Vector3d mP1; - Vector3d mP2; - Vector3d mP3; - Vector3d mNear1; - Vector3d mNear2; - Vector3d mNear3; - Vector3d mNormal; - double mPlaneD; - double mConcavity; - double mC1; - double mC2; - double mC3; - unsigned int mI1; - unsigned int mI2; - unsigned int mI3; - int mProcessed; // already been added... -}; - -typedef std::vector< CTri > CTriVector; - -bool featureMatch(CTri &m,const CTriVector &tris,ConvexDecompInterface *callback,const CTriVector &input_mesh) -{ - - bool ret = false; - - double neardot = 0.707f; - - m.mConcavity = 0; - - //gLog->Display("*********** FEATURE MATCH *************\r\n"); - //gLog->Display("Plane: %0.4f,%0.4f,%0.4f %0.4f\r\n", m.mNormal.x, m.mNormal.y, m.mNormal.z, m.mPlaneD ); - //gLog->Display("*********************************************\r\n"); - - CTriVector::const_iterator i; - - CTri nearest; - - double near[3] = { 1e9, 1e9, 1e9 }; - - for (i=tris.begin(); i!=tris.end(); ++i) - { - const CTri &t = (*i); - - - //gLog->Display(" HullPlane: %0.4f,%0.4f,%0.4f %0.4f\r\n", t.mNormal.x, t.mNormal.y, t.mNormal.z, t.mPlaneD ); - - if ( t.samePlane(m) ) - { - //gLog->Display("*** PLANE MATCH!!!\r\n"); - ret = false; - break; - } - - double dot = t.mNormal.Dot(m.mNormal); - - if ( dot > neardot ) - { - - double d1 = t.planeDistance( m.mP1 ); - double d2 = t.planeDistance( m.mP2 ); - double d3 = t.planeDistance( m.mP3 ); - - if ( d1 > 0.001f || d2 > 0.001f || d3 > 0.001f ) // can't be near coplaner! - { - - neardot = dot; - - Vector3d n1,n2,n3; - - t.raySect( m.mP1, m.mNormal, m.mNear1 ); - t.raySect( m.mP2, m.mNormal, m.mNear2 ); - t.raySect( m.mP3, m.mNormal, m.mNear3 ); - - nearest = t; - - ret = true; - } - - } - } - - if ( ret ) - { - if ( 0 ) - { - CTriVector::const_iterator i; - for (i=input_mesh.begin(); i!=input_mesh.end(); ++i) - { - const CTri &c = (*i); - if ( c.mI1 != m.mI1 && c.mI2 != m.mI2 && c.mI3 != m.mI3 ) - { - c.clip( m.mP1, m.mNear1 ); - c.clip( m.mP2, m.mNear2 ); - c.clip( m.mP3, m.mNear3 ); - } - } - } - - //gLog->Display("*********************************************\r\n"); - //gLog->Display(" HullPlaneNearest: %0.4f,%0.4f,%0.4f %0.4f\r\n", nearest.mNormal.x, nearest.mNormal.y, nearest.mNormal.z, nearest.mPlaneD ); - - m.mC1 = m.mP1.Distance( m.mNear1 ); - m.mC2 = m.mP2.Distance( m.mNear2 ); - m.mC3 = m.mP3.Distance( m.mNear3 ); - - m.mConcavity = m.mC1; - - if ( m.mC2 > m.mConcavity ) m.mConcavity = m.mC2; - if ( m.mC3 > m.mConcavity ) m.mConcavity = m.mC3; - - #if 0 - callback->ConvexDebugTri( m.mP1.Ptr(), m.mP2.Ptr(), m.mP3.Ptr(), 0x00FF00 ); - callback->ConvexDebugTri( m.mNear1.Ptr(), m.mNear2.Ptr(), m.mNear3.Ptr(), 0xFF0000 ); - - callback->ConvexDebugTri( m.mP1.Ptr(), m.mP1.Ptr(), m.mNear1.Ptr(), 0xFFFF00 ); - callback->ConvexDebugTri( m.mP2.Ptr(), m.mP2.Ptr(), m.mNear2.Ptr(), 0xFFFF00 ); - callback->ConvexDebugTri( m.mP3.Ptr(), m.mP3.Ptr(), m.mNear3.Ptr(), 0xFFFF00 ); - #endif - - } - else - { - //gLog->Display("No match\r\n"); - } - - //gLog->Display("*********************************************\r\n"); - return ret; -} - -bool isFeatureTri(CTri &t,CTriVector &flist,double fc,ConvexDecompInterface *callback,unsigned int color) -{ - bool ret = false; - - if ( t.mProcessed == 0 ) // if not already processed - { - - double c = t.mConcavity / fc; // must be within 80% of the concavity of the parent. - - if ( c > 0.85f ) - { - // see if this triangle is a 'feature' triangle. Meaning it shares an - // edge with any existing feature triangle and is within roughly the same - // concavity of the parent. - if ( flist.size() ) - { - CTriVector::iterator i; - for (i=flist.begin(); i!=flist.end(); ++i) - { - CTri &ftri = (*i); - if ( ftri.sharesEdge(t) ) - { - t.mProcessed = 2; // it is now part of a feature. - flist.push_back(t); // add it to the feature list. -// callback->ConvexDebugTri( t.mP1.Ptr(), t.mP2.Ptr(),t.mP3.Ptr(), color ); - ret = true; - break; - } - } - } - else - { - t.mProcessed = 2; - flist.push_back(t); // add it to the feature list. -// callback->ConvexDebugTri( t.mP1.Ptr(), t.mP2.Ptr(),t.mP3.Ptr(), color ); - ret = true; - } - } - else - { - t.mProcessed = 1; // eliminated for this feature, but might be valid for the next one.. - } - - } - return ret; -} - -double computeConcavity(unsigned int vcount, - const double *vertices, - unsigned int tcount, - const unsigned int *indices, - ConvexDecompInterface *callback, - double *plane, // plane equation to split on - double &volume) -{ - - - double cret = 0; - volume = 1; - - HullResult result; - HullLibrary hl; - HullDesc desc; - - desc.mMaxVertices = 256; - desc.SetHullFlag(QF_TRIANGLES); - - - desc.mVcount = vcount; - desc.mVertices = vertices; - desc.mVertexStride = sizeof(double)*3; - - HullError ret = hl.CreateConvexHull(desc,result); - - if ( ret == QE_OK ) - { - - double bmin[3]; - double bmax[3]; - - double diagonal = getBoundingRegion( result.mNumOutputVertices, result.mOutputVertices, sizeof(double)*3, bmin, bmax ); - - double dx = bmax[0] - bmin[0]; - double dy = bmax[1] - bmin[1]; - double dz = bmax[2] - bmin[2]; - - Vector3d center; - - center.x = bmin[0] + dx*0.5f; - center.y = bmin[1] + dy*0.5f; - center.z = bmin[2] + dz*0.5f; - - double boundVolume = dx*dy*dz; - - volume = computeMeshVolume2( result.mOutputVertices, result.mNumFaces, result.mIndices ); - -#if 1 - // ok..now..for each triangle on the original mesh.. - // we extrude the points to the nearest point on the hull. - const unsigned int *source = result.mIndices; - - CTriVector tris; - - for (unsigned int i=0; iConvexDebugTri(p1,p2,p3,0xFFFFFF); - - CTri t(p1,p2,p3,i1,i2,i3); // - tris.push_back(t); - } - - // we have not pre-computed the plane equation for each triangle in the convex hull.. - - double totalVolume = 0; - - CTriVector ftris; // 'feature' triangles. - - const unsigned int *src = indices; - - - double maxc=0; - - - if ( 1 ) - { - CTriVector input_mesh; - if ( 1 ) - { - const unsigned int *src = indices; - for (unsigned int i=0; i CONCAVE_THRESH ) - { - - if ( t.mConcavity > maxc ) - { - maxc = t.mConcavity; - maxctri = t; - } - - double v = t.getVolume(0); - totalVolume+=v; - ftris.push_back(t); - } - - } - } - - if ( ftris.size() && 0 ) - { - - // ok..now we extract the triangles which form the maximum concavity. - CTriVector major_feature; - double maxarea = 0; - - while ( maxc > CONCAVE_THRESH ) - { - - unsigned int color = getDebugColor(); // - - CTriVector flist; - - bool found; - - double totalarea = 0; - - do - { - found = false; - CTriVector::iterator i; - for (i=ftris.begin(); i!=ftris.end(); ++i) - { - CTri &t = (*i); - if ( isFeatureTri(t,flist,maxc,callback,color) ) - { - found = true; - totalarea+=t.area(); - } - } - } while ( found ); - - - if ( totalarea > maxarea ) - { - major_feature = flist; - maxarea = totalarea; - } - - maxc = 0; - - for (unsigned int i=0; i maxc ) - { - maxc = t.mConcavity; - } - } - } - } - - unsigned int color = getDebugColor(); - - WpointVector list; - for (unsigned int i=0; i -#include -#include -#include -#include - -#include "fitsphere.h" - - -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - - - - -/* -An Efficient Bounding Sphere -by Jack Ritter -from "Graphics Gems", Academic Press, 1990 -*/ - -/* Routine to calculate tight bounding sphere over */ -/* a set of points in 3D */ -/* This contains the routine find_bounding_sphere(), */ -/* the struct definition, and the globals used for parameters. */ -/* The abs() of all coordinates must be < BIGNUMBER */ -/* Code written by Jack Ritter and Lyle Rains. */ - -namespace ConvexDecomposition -{ - -#define BIGNUMBER 100000000.0 /* hundred million */ - -static inline void Set(double *n,double x,double y,double z) -{ - n[0] = x; - n[1] = y; - n[2] = z; -}; - -static inline void Copy(double *dest,const double *source) -{ - dest[0] = source[0]; - dest[1] = source[1]; - dest[2] = source[2]; -} - -double computeBoundingSphere(unsigned int vcount,const double *points,double *center) -{ - - double mRadius; - double mRadius2; - - double xmin[3]; - double xmax[3]; - double ymin[3]; - double ymax[3]; - double zmin[3]; - double zmax[3]; - double dia1[3]; - double dia2[3]; - - /* FIRST PASS: find 6 minima/maxima points */ - Set(xmin,BIGNUMBER,BIGNUMBER,BIGNUMBER); - Set(xmax,-BIGNUMBER,-BIGNUMBER,-BIGNUMBER); - Set(ymin,BIGNUMBER,BIGNUMBER,BIGNUMBER); - Set(ymax,-BIGNUMBER,-BIGNUMBER,-BIGNUMBER); - Set(zmin,BIGNUMBER,BIGNUMBER,BIGNUMBER); - Set(zmax,-BIGNUMBER,-BIGNUMBER,-BIGNUMBER); - - for (unsigned i=0; ixmax[0]) - Copy(xmax,caller_p); - if (caller_p[1]ymax[1]) - Copy(ymax,caller_p); - if (caller_p[2]zmax[2]) - Copy(zmax,caller_p); - } - - /* Set xspan = distance between the 2 points xmin & xmax (squared) */ - double dx = xmax[0] - xmin[0]; - double dy = xmax[1] - xmin[1]; - double dz = xmax[2] - xmin[2]; - double xspan = dx*dx + dy*dy + dz*dz; - - /* Same for y & z spans */ - dx = ymax[0] - ymin[0]; - dy = ymax[1] - ymin[1]; - dz = ymax[2] - ymin[2]; - double yspan = dx*dx + dy*dy + dz*dz; - - dx = zmax[0] - zmin[0]; - dy = zmax[1] - zmin[1]; - dz = zmax[2] - zmin[2]; - double zspan = dx*dx + dy*dy + dz*dz; - - /* Set points dia1 & dia2 to the maximally separated pair */ - Copy(dia1,xmin); - Copy(dia2,xmax); /* assume xspan biggest */ - double maxspan = xspan; - - if (yspan>maxspan) - { - maxspan = yspan; - Copy(dia1,ymin); - Copy(dia2,ymax); - } - - if (zspan>maxspan) - { - Copy(dia1,zmin); - Copy(dia2,zmax); - } - - - /* dia1,dia2 is a diameter of initial sphere */ - /* calc initial center */ - center[0] = (dia1[0]+dia2[0])*0.5f; - center[1] = (dia1[1]+dia2[1])*0.5f; - center[2] = (dia1[2]+dia2[2])*0.5f; - - /* calculate initial radius**2 and radius */ - - dx = dia2[0]-center[0]; /* x component of radius vector */ - dy = dia2[1]-center[1]; /* y component of radius vector */ - dz = dia2[2]-center[2]; /* z component of radius vector */ - - mRadius2 = dx*dx + dy*dy + dz*dz; - mRadius = double(sqrt(mRadius2)); - - /* SECOND PASS: increment current sphere */ - if ( 1 ) - { - for (unsigned i=0; i mRadius2) /* do r**2 test first */ - { /* this point is outside of current sphere */ - double old_to_p = double(sqrt(old_to_p_sq)); - /* calc radius of new sphere */ - mRadius = (mRadius + old_to_p) * 0.5f; - mRadius2 = mRadius*mRadius; /* for next r**2 compare */ - double old_to_new = old_to_p - mRadius; - - /* calc center of new sphere */ - - double recip = 1.0f /old_to_p; - - double cx = (mRadius*center[0] + old_to_new*caller_p[0]) * recip; - double cy = (mRadius*center[1] + old_to_new*caller_p[1]) * recip; - double cz = (mRadius*center[2] + old_to_new*caller_p[2]) * recip; - - Set(center,cx,cy,cz); - } - } - } - - return mRadius; -} - -static inline void Set(float *n,float x,float y,float z) -{ - n[0] = x; - n[1] = y; - n[2] = z; -}; - -static inline void Copy(float *dest,const float *source) -{ - dest[0] = source[0]; - dest[1] = source[1]; - dest[2] = source[2]; -} - - - -float computeBoundingSphere(unsigned int vcount,const float *points,float *center) -{ - float mRadius; - float mRadius2; - - float xmin[3]; - float xmax[3]; - float ymin[3]; - float ymax[3]; - float zmin[3]; - float zmax[3]; - float dia1[3]; - float dia2[3]; - - /* FIRST PASS: find 6 minima/maxima points */ - Set(xmin,BIGNUMBER,BIGNUMBER,BIGNUMBER); - Set(xmax,-BIGNUMBER,-BIGNUMBER,-BIGNUMBER); - Set(ymin,BIGNUMBER,BIGNUMBER,BIGNUMBER); - Set(ymax,-BIGNUMBER,-BIGNUMBER,-BIGNUMBER); - Set(zmin,BIGNUMBER,BIGNUMBER,BIGNUMBER); - Set(zmax,-BIGNUMBER,-BIGNUMBER,-BIGNUMBER); - - for (unsigned i=0; ixmax[0]) - Copy(xmax,caller_p); - if (caller_p[1]ymax[1]) - Copy(ymax,caller_p); - if (caller_p[2]zmax[2]) - Copy(zmax,caller_p); - } - - /* Set xspan = distance between the 2 points xmin & xmax (squared) */ - float dx = xmax[0] - xmin[0]; - float dy = xmax[1] - xmin[1]; - float dz = xmax[2] - xmin[2]; - float xspan = dx*dx + dy*dy + dz*dz; - - /* Same for y & z spans */ - dx = ymax[0] - ymin[0]; - dy = ymax[1] - ymin[1]; - dz = ymax[2] - ymin[2]; - float yspan = dx*dx + dy*dy + dz*dz; - - dx = zmax[0] - zmin[0]; - dy = zmax[1] - zmin[1]; - dz = zmax[2] - zmin[2]; - float zspan = dx*dx + dy*dy + dz*dz; - - /* Set points dia1 & dia2 to the maximally separated pair */ - Copy(dia1,xmin); - Copy(dia2,xmax); /* assume xspan biggest */ - float maxspan = xspan; - - if (yspan>maxspan) - { - maxspan = yspan; - Copy(dia1,ymin); - Copy(dia2,ymax); - } - - if (zspan>maxspan) - { - Copy(dia1,zmin); - Copy(dia2,zmax); - } - - - /* dia1,dia2 is a diameter of initial sphere */ - /* calc initial center */ - center[0] = (dia1[0]+dia2[0])*0.5f; - center[1] = (dia1[1]+dia2[1])*0.5f; - center[2] = (dia1[2]+dia2[2])*0.5f; - - /* calculate initial radius**2 and radius */ - - dx = dia2[0]-center[0]; /* x component of radius vector */ - dy = dia2[1]-center[1]; /* y component of radius vector */ - dz = dia2[2]-center[2]; /* z component of radius vector */ - - mRadius2 = dx*dx + dy*dy + dz*dz; - mRadius = float(sqrt(mRadius2)); - - /* SECOND PASS: increment current sphere */ - if ( 1 ) - { - for (unsigned i=0; i mRadius2) /* do r**2 test first */ - { /* this point is outside of current sphere */ - float old_to_p = float(sqrt(old_to_p_sq)); - /* calc radius of new sphere */ - mRadius = (mRadius + old_to_p) * 0.5f; - mRadius2 = mRadius*mRadius; /* for next r**2 compare */ - float old_to_new = old_to_p - mRadius; - - /* calc center of new sphere */ - - float recip = 1.0f /old_to_p; - - float cx = (mRadius*center[0] + old_to_new*caller_p[0]) * recip; - float cy = (mRadius*center[1] + old_to_new*caller_p[1]) * recip; - float cz = (mRadius*center[2] + old_to_new*caller_p[2]) * recip; - - Set(center,cx,cy,cz); - } - } - } - - return mRadius; -} - - -double computeSphereVolume(double r) -{ - return (4.0f*3.141592654f*r*r*r)/3.0f; // 4/3 PI R cubed -} - -}; diff --git a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/fitsphere.h b/convex_decomposition/ConvexDecomposition/ConvexDecomposition/fitsphere.h deleted file mode 100644 index 200310f..0000000 --- a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/fitsphere.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef FIT_SPHERE_H - -#define FIT_SPHERE_H - -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - - -namespace ConvexDecomposition -{ - -double computeBoundingSphere(unsigned int vcount,const double *points,double *center); -float computeBoundingSphere(unsigned int vcount,const float *points,float *center); - -double computeSphereVolume(double r); - -}; - -#endif diff --git a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/float_math.cpp b/convex_decomposition/ConvexDecomposition/ConvexDecomposition/float_math.cpp deleted file mode 100644 index 8c106fe..0000000 --- a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/float_math.cpp +++ /dev/null @@ -1,463 +0,0 @@ -#include -#include -#include -#include -#include - -#include "float_math.h" - -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - - - -// a set of routines that let you do common 3d math -// operations without any vector, matrix, or quaternion -// classes or templates. -// -// a vector (or point) is a 'double *' to 3 doubleing point numbers. -// a matrix is a 'double *' to an array of 16 doubleing point numbers representing a 4x4 transformation matrix compatible with D3D or OGL -// a quaternion is a 'double *' to 4 doubles representing a quaternion x,y,z,w -// -// -// -// Please email bug fixes or improvements to John W. Ratcliff at mailto:jratcliff@infiniplex.net -// -// If you find this source code useful donate a couple of bucks to my kid's fund raising website at -// www.amillionpixels.us -// -// More snippets at: www.codesuppository.com -// - -namespace ConvexDecomposition -{ - -void fm_inverseRT(const double *matrix,const double *pos,double *t) // inverse rotate translate the point. -{ - - double _x = pos[0] - matrix[3*4+0]; - double _y = pos[1] - matrix[3*4+1]; - double _z = pos[2] - matrix[3*4+2]; - - // Multiply inverse-translated source vector by inverted rotation transform - - t[0] = (matrix[0*4+0] * _x) + (matrix[0*4+1] * _y) + (matrix[0*4+2] * _z); - t[1] = (matrix[1*4+0] * _x) + (matrix[1*4+1] * _y) + (matrix[1*4+2] * _z); - t[2] = (matrix[2*4+0] * _x) + (matrix[2*4+1] * _y) + (matrix[2*4+2] * _z); - -} - - -void fm_identity(double *matrix) // set 4x4 matrix to identity. -{ - matrix[0*4+0] = 1; - matrix[1*4+1] = 1; - matrix[2*4+2] = 1; - matrix[3*4+3] = 1; - - matrix[1*4+0] = 0; - matrix[2*4+0] = 0; - matrix[3*4+0] = 0; - - matrix[0*4+1] = 0; - matrix[2*4+1] = 0; - matrix[3*4+1] = 0; - - matrix[0*4+2] = 0; - matrix[1*4+2] = 0; - matrix[3*4+2] = 0; - - matrix[0*4+3] = 0; - matrix[1*4+3] = 0; - matrix[2*4+3] = 0; - -} - -void fm_eulerMatrix(double ax,double ay,double az,double *matrix) // convert euler (in radians) to a dest 4x4 matrix (translation set to zero) -{ - double quat[4]; - fm_eulerToQuat(ax,ay,az,quat); - fm_quatToMatrix(quat,matrix); -} - -void fm_getAABB(unsigned int vcount,const double *points,unsigned int pstride,double *bmin,double *bmax) -{ - - const unsigned char *source = (const unsigned char *) points; - - bmin[0] = points[0]; - bmin[1] = points[1]; - bmin[2] = points[2]; - - bmax[0] = points[0]; - bmax[1] = points[1]; - bmax[2] = points[2]; - - - for (unsigned int i=1; i bmax[0] ) bmax[0] = p[0]; - if ( p[1] > bmax[1] ) bmax[1] = p[1]; - if ( p[2] > bmax[2] ) bmax[2] = p[2]; - - } -} - - -void fm_eulerToQuat(double roll,double pitch,double yaw,double *quat) // convert euler angles to quaternion. -{ - roll *= 0.5f; - pitch *= 0.5f; - yaw *= 0.5f; - - double cr = cos(roll); - double cp = cos(pitch); - double cy = cos(yaw); - - double sr = sin(roll); - double sp = sin(pitch); - double sy = sin(yaw); - - double cpcy = cp * cy; - double spsy = sp * sy; - double spcy = sp * cy; - double cpsy = cp * sy; - - quat[0] = ( sr * cpcy - cr * spsy); - quat[1] = ( cr * spcy + sr * cpsy); - quat[2] = ( cr * cpsy - sr * spcy); - quat[3] = cr * cpcy + sr * spsy; -} - -void fm_quatToMatrix(const double *quat,double *matrix) // convert quaterinion rotation to matrix, zeros out the translation component. -{ - - double xx = quat[0]*quat[0]; - double yy = quat[1]*quat[1]; - double zz = quat[2]*quat[2]; - double xy = quat[0]*quat[1]; - double xz = quat[0]*quat[2]; - double yz = quat[1]*quat[2]; - double wx = quat[3]*quat[0]; - double wy = quat[3]*quat[1]; - double wz = quat[3]*quat[2]; - - matrix[0*4+0] = 1 - 2 * ( yy + zz ); - matrix[1*4+0] = 2 * ( xy - wz ); - matrix[2*4+0] = 2 * ( xz + wy ); - - matrix[0*4+1] = 2 * ( xy + wz ); - matrix[1*4+1] = 1 - 2 * ( xx + zz ); - matrix[2*4+1] = 2 * ( yz - wx ); - - matrix[0*4+2] = 2 * ( xz - wy ); - matrix[1*4+2] = 2 * ( yz + wx ); - matrix[2*4+2] = 1 - 2 * ( xx + yy ); - - matrix[3*4+0] = 0.0f; - matrix[3*4+1] = 0.0f; - matrix[3*4+2] = 0.0f; - - matrix[0*4+3] = 0.0f; - matrix[1*4+3] = 0.0f; - matrix[2*4+3] = 0.0f; - - matrix[3*4+3] =(double) 1.0f; - -} - - -void fm_quatRotate(const double *quat,const double *v,double *r) // rotate a vector directly by a quaternion. -{ - double left[4]; - - left[0] = quat[3]*v[0] + quat[1]*v[2] - v[1]*quat[2]; - left[1] = quat[3]*v[1] + quat[2]*v[0] - v[2]*quat[0]; - left[2] = quat[3]*v[2] + quat[0]*v[1] - v[0]*quat[1]; - left[3] = - quat[0]*v[0] - quat[1]*v[1] - quat[2]*v[2]; - - r[0] = (left[3]*-quat[0]) + (quat[3]*left[0]) + (left[1]*-quat[2]) - (-quat[1]*left[2]); - r[1] = (left[3]*-quat[1]) + (quat[3]*left[1]) + (left[2]*-quat[0]) - (-quat[2]*left[0]); - r[2] = (left[3]*-quat[2]) + (quat[3]*left[2]) + (left[0]*-quat[1]) - (-quat[0]*left[1]); - -} - - -void fm_getTranslation(const double *matrix,double *t) -{ - t[0] = matrix[3*4+0]; - t[1] = matrix[3*4+1]; - t[2] = matrix[3*4+2]; -} - -void fm_matrixToQuat(const double *matrix,double *quat) // convert the 3x3 portion of a 4x4 matrix into a quaterion as x,y,z,w -{ - - double tr = matrix[0*4+0] + matrix[1*4+1] + matrix[2*4+2]; - - // check the diagonal - - if (tr > 0.0f ) - { - double s = (double) sqrt ( (double) (tr + 1.0f) ); - quat[3] = s * 0.5f; - s = 0.5f / s; - quat[0] = (matrix[1*4+2] - matrix[2*4+1]) * s; - quat[1] = (matrix[2*4+0] - matrix[0*4+2]) * s; - quat[2] = (matrix[0*4+1] - matrix[1*4+0]) * s; - - } - else - { - // diagonal is negative - int nxt[3] = {1, 2, 0}; - double qa[4]; - - int i = 0; - - if (matrix[1*4+1] > matrix[0*4+0]) i = 1; - if (matrix[2*4+2] > matrix[i*4+i]) i = 2; - - int j = nxt[i]; - int k = nxt[j]; - - double s = sqrt ( ((matrix[i*4+i] - (matrix[j*4+j] + matrix[k*4+k])) + 1.0f) ); - - qa[i] = s * 0.5f; - - if (s != 0.0f ) s = 0.5f / s; - - qa[3] = (matrix[j*4+k] - matrix[k*4+j]) * s; - qa[j] = (matrix[i*4+j] + matrix[j*4+i]) * s; - qa[k] = (matrix[i*4+k] + matrix[k*4+i]) * s; - - quat[0] = qa[0]; - quat[1] = qa[1]; - quat[2] = qa[2]; - quat[3] = qa[3]; - } - - -} - - -double fm_sphereVolume(double radius) // return's the volume of a sphere of this radius (4/3 PI * R cubed ) -{ - return (4.0f / 3.0f ) * FM_PI * radius * radius * radius; -} - - -double fm_cylinderVolume(double radius,double h) -{ - return FM_PI * radius * radius *h; -} - -double fm_capsuleVolume(double radius,double h) -{ - double volume = fm_sphereVolume(radius); // volume of the sphere portion. - double ch = h-radius*2; // this is the cylinder length - if ( ch > 0 ) - { - volume+=fm_cylinderVolume(radius,ch); - } - return volume; -} - -void fm_transform(const double *matrix,const double *v,double *t) // rotate and translate this point -{ - t[0] = (matrix[0*4+0] * v[0]) + (matrix[1*4+0] * v[1]) + (matrix[2*4+0] * v[2]) + matrix[3*4+0]; - t[1] = (matrix[0*4+1] * v[0]) + (matrix[1*4+1] * v[1]) + (matrix[2*4+1] * v[2]) + matrix[3*4+1]; - t[2] = (matrix[0*4+2] * v[0]) + (matrix[1*4+2] * v[1]) + (matrix[2*4+2] * v[2]) + matrix[3*4+2]; -} - -void fm_rotate(const double *matrix,const double *v,double *t) // rotate and translate this point -{ - t[0] = (matrix[0*4+0] * v[0]) + (matrix[1*4+0] * v[1]) + (matrix[2*4+0] * v[2]); - t[1] = (matrix[0*4+1] * v[0]) + (matrix[1*4+1] * v[1]) + (matrix[2*4+1] * v[2]); - t[2] = (matrix[0*4+2] * v[0]) + (matrix[1*4+2] * v[1]) + (matrix[2*4+2] * v[2]); -} - - -double fm_distance(const double *p1,const double *p2) -{ - double dx = p1[0] - p2[0]; - double dy = p1[1] - p2[1]; - double dz = p1[2] - p2[2]; - - return sqrt( dx*dx + dy*dy + dz *dz ); -} - -double fm_distanceSquared(const double *p1,const double *p2) -{ - double dx = p1[0] - p2[0]; - double dy = p1[1] - p2[1]; - double dz = p1[2] - p2[2]; - - return dx*dx + dy*dy + dz *dz; -} - - -double fm_computePlane(const double *A,const double *B,const double *C,double *n) // returns D -{ - double vx = (B[0] - C[0]); - double vy = (B[1] - C[1]); - double vz = (B[2] - C[2]); - - double wx = (A[0] - B[0]); - double wy = (A[1] - B[1]); - double wz = (A[2] - B[2]); - - double vw_x = vy * wz - vz * wy; - double vw_y = vz * wx - vx * wz; - double vw_z = vx * wy - vy * wx; - - double mag = sqrt((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z)); - - if ( mag < 0.000001f ) - { - mag = 0; - } - else - { - mag = 1.0f/mag; - } - - double x = vw_x * mag; - double y = vw_y * mag; - double z = vw_z * mag; - - - double D = 0.0f - ((x*A[0])+(y*A[1])+(z*A[2])); - - n[0] = x; - n[1] = y; - n[2] = z; - - return D; -} - -double fm_distToPlane(const double *plane,const double *p) // computes the distance of this point from the plane. -{ - return p[0]*plane[0]+p[1]*plane[1]+p[2]*plane[2]+plane[3]; -} - -double fm_dot(const double *p1,const double *p2) -{ - return p1[0]*p2[0]+p1[1]*p2[2]+p1[2]*p2[2]; -} - -void fm_cross(double *cross,const double *a,const double *b) -{ - cross[0] = a[1]*b[2] - a[2]*b[1]; - cross[1] = a[2]*b[0] - a[0]*b[2]; - cross[2] = a[0]*b[1] - a[1]*b[0]; -} - -void fm_computeNormalVector(double *n,const double *p1,const double *p2) -{ - n[0] = p2[0] - p1[0]; - n[1] = p2[1] - p1[1]; - n[2] = p2[2] - p1[2]; - fm_normalize(n); -} - -bool fm_computeWindingOrder(const double *p1,const double *p2,const double *p3) // returns true if the triangle is clockwise. -{ - bool ret = false; - - double v1[3]; - double v2[3]; - - fm_computeNormalVector(v1,p1,p2); // p2-p1 (as vector) and then normalized - fm_computeNormalVector(v2,p1,p3); // p3-p1 (as vector) and then normalized - - double cross[3]; - - fm_cross(cross, v1, v2 ); - double ref[3] = { 1, 0, 0 }; - - double d = fm_dot( cross, ref ); - - - if ( d <= 0 ) - ret = false; - else - ret = true; - - return ret; -} - -void fm_normalize(double *n) // normalize this vector -{ - - double dist = n[0]*n[0] + n[1]*n[1] + n[2]*n[2]; - double mag = 0; - - if ( dist > 0.0000001f ) - mag = 1.0f / sqrt(dist); - - n[0]*=mag; - n[1]*=mag; - n[2]*=mag; - -} - -}; // end of namespace diff --git a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/float_math.h b/convex_decomposition/ConvexDecomposition/ConvexDecomposition/float_math.h deleted file mode 100644 index b819b8d..0000000 --- a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/float_math.h +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef FLOAT_MATH_H - -#define FLOAT_MATH_H - -namespace ConvexDecomposition -{ - - /*! - ** - ** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net - ** - ** Portions of this source has been released with the PhysXViewer application, as well as - ** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. - ** - ** If you find this code useful or you are feeling particularily generous I would - ** ask that you please go to http://www.amillionpixels.us and make a donation - ** to Troy DeMolay. - ** - ** DeMolay is a youth group for young men between the ages of 12 and 21. - ** It teaches strong moral principles, as well as leadership skills and - ** public speaking. The donations page uses the 'pay for pixels' paradigm - ** where, in this case, a pixel is only a single penny. Donations can be - ** made for as small as $4 or as high as a $100 block. Each person who donates - ** will get a link to their own site as well as acknowledgement on the - ** donations blog located here http://www.amillionpixels.blogspot.com/ - ** - ** If you wish to contact me you can use the following methods: - ** - ** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) - ** Skype ID: jratcliff63367 - ** Yahoo: jratcliff63367 - ** AOL: jratcliff1961 - ** email: jratcliff@infiniplex.net - ** Personal website: http://jratcliffscarab.blogspot.com - ** Coding Website: http://codesuppository.blogspot.com - ** FundRaising Blog: http://amillionpixels.blogspot.com - ** Fundraising site: http://www.amillionpixels.us - ** New Temple Site: http://newtemple.blogspot.com - ** - ** - ** The MIT license: - ** - ** Permission is hereby granted, free of charge, to any person obtaining a copy - ** of this software and associated documentation files (the "Software"), to deal - ** in the Software without restriction, including without limitation the rights - ** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - ** copies of the Software, and to permit persons to whom the Software is furnished - ** to do so, subject to the following conditions: - ** - ** The above copyright notice and this permission notice shall be included in all - ** copies or substantial portions of the Software. - - ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - ** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - ** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - */ - - - -// a set of routines that let you do common 3d math -// operations without any vector, matrix, or quaternion -// classes or templates. -// -// a vector (or point) is a 'double *' to 3 doubleing point numbers. -// a matrix is a 'double *' to an array of 16 doubleing point numbers representing a 4x4 transformation matrix compatible with D3D or OGL -// a quaternion is a 'double *' to 4 doubles representing a quaternion x,y,z,w -// -// -// -// Please email bug fixes or improvements to John W. Ratcliff at mailto:jratcliff@infiniplex.net -// -// If you find this source code useful donate a couple of bucks to my kid's fund raising website at -// www.amillionpixels.us -// -// More snippets at: www.codesuppository.com -// - -const double FM_PI = 3.141592654f; -const double FM_DEG_TO_RAD = ((2.0f * FM_PI) / 360.0f); -const double FM_RAD_TO_DEG = (360.0f / (2.0f * FM_PI)); - -void fm_identity(double *matrix); // set 4x4 matrix to identity. -void fm_inverseRT(const double *matrix,const double *pos,double *t); // inverse rotate translate the point. -void fm_transform(const double *matrix,const double *pos,double *t); // rotate and translate this point. -void fm_rotate(const double *matrix,const double *pos,double *t); // only rotate the point by a 4x4 matrix, don't translate. -void fm_eulerMatrix(double ax,double ay,double az,double *matrix); // convert euler (in radians) to a dest 4x4 matrix (translation set to zero) -void fm_getAABB(unsigned int vcount,const double *points,unsigned int pstride,double *bmin,double *bmax); -void fm_eulerToQuat(double roll,double pitch,double yaw,double *quat); // convert euler angles to quaternion. -void fm_quatToMatrix(const double *quat,double *matrix); // convert quaterinion rotation to matrix, translation set to zero. -void fm_quatRotate(const double *quat,const double *v,double *r); // rotate a vector directly by a quaternion. -void fm_getTranslation(const double *matrix,double *t); -void fm_matrixToQuat(const double *matrix,double *quat); // convert the 3x3 portion of a 4x4 matrix into a quaterion as x,y,z,w -double fm_sphereVolume(double radius); // return's the volume of a sphere of this radius (4/3 PI * R cubed ) -double fm_cylinderVolume(double radius,double h); -double fm_capsuleVolume(double radius,double h); -double fm_distance(const double *p1,const double *p2); -double fm_distanceSquared(const double *p1,const double *p2); -double fm_computePlane(const double *p1,const double *p2,const double *p3,double *n); // return D -double fm_distToPlane(const double *plane,const double *pos); // computes the distance of this point from the plane. -double fm_dot(const double *p1,const double *p2); -void fm_cross(double *cross,const double *a,const double *b); -void fm_computeNormalVector(double *n,const double *p1,const double *p2); // as P2-P1 normalized. -bool fm_computeWindingOrder(const double *p1,const double *p2,const double *p3); // returns true if the triangle is clockwise. -void fm_normalize(double *n); // normalize this vector - -}; // end of nsamepace - -#endif diff --git a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/meshvolume.cpp b/convex_decomposition/ConvexDecomposition/ConvexDecomposition/meshvolume.cpp deleted file mode 100644 index 453dada..0000000 --- a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/meshvolume.cpp +++ /dev/null @@ -1,251 +0,0 @@ -#include "meshvolume.h" - -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - - -namespace ConvexDecomposition -{ - - -inline double det(const double *p1,const double *p2,const double *p3) -{ - return p1[0]*p2[1]*p3[2] + p2[0]*p3[1]*p1[2] + p3[0]*p1[1]*p2[2] -p1[0]*p3[1]*p2[2] - p2[0]*p1[1]*p3[2] - p3[0]*p2[1]*p1[2]; -} - -double computeMeshVolume(const double *vertices,unsigned int tcount,const unsigned int *indices) -{ - double volume = 0; - - const double *p0 = vertices; - for (unsigned int i=0; i -#include -#include -#include - -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - - - -#include "planetri.h" - -namespace ConvexDecomposition -{ - - -static inline double DistToPt(const double *p,const double *plane) -{ - double x = p[0]; - double y = p[1]; - double z = p[2]; - double d = x*plane[0] + y*plane[1] + z*plane[2] + plane[3]; - return d; -} - - -static PlaneTriResult getSidePlane(const double *p,const double *plane,double epsilon) -{ - - double d = DistToPt(p,plane); - - if ( (d+epsilon) > 0 ) - return PTR_FRONT; // it is 'in front' within the provided epsilon value. - - return PTR_BACK; -} - -static void add(const double *p,double *dest,unsigned int tstride,unsigned int &pcount) -{ - char *d = (char *) dest; - d = d + pcount*tstride; - dest = (double *) d; - dest[0] = p[0]; - dest[1] = p[1]; - dest[2] = p[2]; - pcount++; - assert( pcount <= 4 ); -} - - -// assumes that the points are on opposite sides of the plane! -static void intersect(const double *p1,const double *p2,double *split,const double *plane) -{ - - double dp1 = DistToPt(p1,plane); - double dp2 = DistToPt(p2,plane); - - double dir[3]; - - dir[0] = p2[0] - p1[0]; - dir[1] = p2[1] - p1[1]; - dir[2] = p2[2] - p1[2]; - - double dot1 = dir[0]*plane[0] + dir[1]*plane[1] + dir[2]*plane[2]; - double dot2 = dp1 - plane[3]; - - double t = -(plane[3] + dot2 ) / dot1; - - split[0] = (dir[0]*t)+p1[0]; - split[1] = (dir[1]*t)+p1[1]; - split[2] = (dir[2]*t)+p1[2]; - -} - -#define MAXPTS 256 - -class point -{ -public: - - void set(const double *p) - { - x = p[0]; - y = p[1]; - z = p[2]; - } - - double x; - double y; - double z; -}; -class polygon -{ -public: - polygon(void) - { - mVcount = 0; - } - - polygon(const double *p1,const double *p2,const double *p3) - { - mVcount = 3; - mVertices[0].set(p1); - mVertices[1].set(p2); - mVertices[2].set(p3); - } - - - int NumVertices(void) const { return mVcount; }; - - const point& Vertex(int index) - { - if ( index < 0 ) index+=mVcount; - return mVertices[index]; - }; - - - void set(const point *pts,int count) - { - for (int i=0; iNumVertices (); - int out_c = 0, in_c = 0; - point ptA, ptB,outpts[MAXPTS],inpts[MAXPTS]; - double sideA, sideB; - ptA = poly->Vertex (count - 1); - sideA = part->Classify_Point (ptA); - for (int i = -1; ++i < count;) - { - ptB = poly->Vertex(i); - sideB = part->Classify_Point(ptB); - if (sideB > 0) - { - if (sideA < 0) - { - point v; - intersect(&ptB.x, &ptA.x, &v.x, &part->normal.x ); - outpts[out_c++] = inpts[in_c++] = v; - } - outpts[out_c++] = ptB; - } - else if (sideB < 0) - { - if (sideA > 0) - { - point v; - intersect(&ptB.x, &ptA.x, &v.x, &part->normal.x ); - outpts[out_c++] = inpts[in_c++] = v; - } - inpts[in_c++] = ptB; - } - else - outpts[out_c++] = inpts[in_c++] = ptB; - ptA = ptB; - sideA = sideB; - } - - front.set(&outpts[0], out_c); - back.set(&inpts[0], in_c); -} - -PlaneTriResult planeTriIntersection(const double *_plane, // the plane equation in Ax+By+Cz+D format - const double *triangle, // the source triangle. - unsigned int tstride, // stride in bytes of the input and output *vertices* - double epsilon, // the co-planer epsilon value. - double *front, // the triangle in front of the - unsigned int &fcount, // number of vertices in the 'front' triangle - double *back, // the triangle in back of the plane - unsigned int &bcount) // the number of vertices in the 'back' triangle. -{ - - fcount = 0; - bcount = 0; - - const char *tsource = (const char *) triangle; - - // get the three vertices of the triangle. - const double *p1 = (const double *) (tsource); - const double *p2 = (const double *) (tsource+tstride); - const double *p3 = (const double *) (tsource+tstride*2); - - - PlaneTriResult r1 = getSidePlane(p1,_plane,epsilon); // compute the side of the plane each vertex is on - PlaneTriResult r2 = getSidePlane(p2,_plane,epsilon); - PlaneTriResult r3 = getSidePlane(p3,_plane,epsilon); - - if ( r1 == r2 && r1 == r3 ) // if all three vertices are on the same side of the plane. - { - if ( r1 == PTR_FRONT ) // if all three are in front of the plane, then copy to the 'front' output triangle. - { - add(p1,front,tstride,fcount); - add(p2,front,tstride,fcount); - add(p3,front,tstride,fcount); - } - else - { - add(p1,back,tstride,bcount); // if all three are in 'back' then copy to the 'back' output triangle. - add(p2,back,tstride,bcount); - add(p3,back,tstride,bcount); - } - return r1; // if all three points are on the same side of the plane return result - } - - - polygon pi(p1,p2,p3); - polygon pfront,pback; - - plane part(_plane); - Split_Polygon(&pi,&part,pfront,pback); - - for (int i=0; i -#include -#include -#include -#include - -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - - - -#include "raytri.h" - -namespace ConvexDecomposition -{ - - -/* a = b - c */ -#define vector(a,b,c) \ - (a)[0] = (b)[0] - (c)[0]; \ - (a)[1] = (b)[1] - (c)[1]; \ - (a)[2] = (b)[2] - (c)[2]; - - - -#define innerProduct(v,q) \ - ((v)[0] * (q)[0] + \ - (v)[1] * (q)[1] + \ - (v)[2] * (q)[2]) - -#define crossProduct(a,b,c) \ - (a)[0] = (b)[1] * (c)[2] - (c)[1] * (b)[2]; \ - (a)[1] = (b)[2] * (c)[0] - (c)[2] * (b)[0]; \ - (a)[2] = (b)[0] * (c)[1] - (c)[0] * (b)[1]; - -bool rayIntersectsTriangle(const double *p,const double *d,const double *v0,const double *v1,const double *v2,double &t) -{ - - double e1[3],e2[3],h[3],s[3],q[3]; - double a,f,u,v; - - vector(e1,v1,v0); - vector(e2,v2,v0); - crossProduct(h,d,e2); - a = innerProduct(e1,h); - - if (a > -0.00001 && a < 0.00001) - return(false); - - f = 1/a; - vector(s,p,v0); - u = f * (innerProduct(s,h)); - - if (u < 0.0 || u > 1.0) - return(false); - - crossProduct(q,s,e1); - v = f * innerProduct(d,q); - if (v < 0.0 || u + v > 1.0) - return(false); - // at this stage we can compute t to find out where - // the intersection point is on the line - t = f * innerProduct(e2,q); - if (t > 0) // ray intersection - return(true); - else // this means that there is a line intersection - // but not a ray intersection - return (false); -} - - -bool lineIntersectsTriangle(const double *rayStart,const double *rayEnd,const double *p1,const double *p2,const double *p3,double *sect) -{ - double dir[3]; - - dir[0] = rayEnd[0] - rayStart[0]; - dir[1] = rayEnd[1] - rayStart[1]; - dir[2] = rayEnd[2] - rayStart[2]; - - double d = sqrt(dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]); - double r = 1.0f / d; - - dir[0]*=r; - dir[1]*=r; - dir[2]*=r; - - - double t; - - bool ret = rayIntersectsTriangle(rayStart, dir, p1, p2, p3, t ); - - if ( ret ) - { - if ( t > d ) - { - sect[0] = rayStart[0] + dir[0]*t; - sect[1] = rayStart[1] + dir[1]*t; - sect[2] = rayStart[2] + dir[2]*t; - } - else - { - ret = false; - } - } - - return ret; -} - -}; // end of namespace diff --git a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/raytri.h b/convex_decomposition/ConvexDecomposition/ConvexDecomposition/raytri.h deleted file mode 100644 index 647a658..0000000 --- a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/raytri.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef RAY_TRI_H - -#define RAY_TRI_H - -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - - -namespace ConvexDecomposition -{ - -// returns true if the ray intersects the triangle. -bool lineIntersectsTriangle(const double *rayStart,const double *rayEnd,const double *p1,const double *p2,const double *p3,double *sect); -bool rayIntersectsTriangle(const double *p,const double *d,const double *v0,const double *v1,const double *v2,double &t); - -}; - -#endif diff --git a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/splitplane.cpp b/convex_decomposition/ConvexDecomposition/ConvexDecomposition/splitplane.cpp deleted file mode 100644 index 154cead..0000000 --- a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/splitplane.cpp +++ /dev/null @@ -1,339 +0,0 @@ -#include -#include -#include -#include -#include -#include - -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - - - -#include "splitplane.h" -#include "ConvexDecomposition.h" -#include "cd_vector.h" -#include "cd_hull.h" -#include "cd_wavefront.h" -#include "bestfit.h" -#include "planetri.h" -#include "vlookup.h" -#include "meshvolume.h" -#include "bestfitobb.h" -#include "float_math.h" - -namespace ConvexDecomposition -{ - -static void computePlane(const double *A,const double *B,const double *C,double *plane) -{ - - double vx = (B[0] - C[0]); - double vy = (B[1] - C[1]); - double vz = (B[2] - C[2]); - - double wx = (A[0] - B[0]); - double wy = (A[1] - B[1]); - double wz = (A[2] - B[2]); - - double vw_x = vy * wz - vz * wy; - double vw_y = vz * wx - vx * wz; - double vw_z = vx * wy - vy * wx; - - double mag = sqrt((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z)); - - if ( mag < 0.000001f ) - { - mag = 0; - } - else - { - mag = 1.0f/mag; - } - - double x = vw_x * mag; - double y = vw_y * mag; - double z = vw_z * mag; - - - double D = 0.0f - ((x*A[0])+(y*A[1])+(z*A[2])); - - plane[0] = x; - plane[1] = y; - plane[2] = z; - plane[3] = D; - -} - -class Rect3d -{ -public: - Rect3d(void) { }; - - Rect3d(const double *bmin,const double *bmax) - { - - mMin[0] = bmin[0]; - mMin[1] = bmin[1]; - mMin[2] = bmin[2]; - - mMax[0] = bmax[0]; - mMax[1] = bmax[1]; - mMax[2] = bmax[2]; - - } - - void SetMin(const double *bmin) - { - mMin[0] = bmin[0]; - mMin[1] = bmin[1]; - mMin[2] = bmin[2]; - } - - void SetMax(const double *bmax) - { - mMax[0] = bmax[0]; - mMax[1] = bmax[1]; - mMax[2] = bmax[2]; - } - - void SetMin(double x,double y,double z) - { - mMin[0] = x; - mMin[1] = y; - mMin[2] = z; - } - - void SetMax(double x,double y,double z) - { - mMax[0] = x; - mMax[1] = y; - mMax[2] = z; - } - - double mMin[3]; - double mMax[3]; -}; - -void splitRect(unsigned int axis, - const Rect3d &source, - Rect3d &b1, - Rect3d &b2, - const double *midpoint) -{ - switch ( axis ) - { - case 0: - b1.SetMin(source.mMin); - b1.SetMax( midpoint[0], source.mMax[1], source.mMax[2] ); - - b2.SetMin( midpoint[0], source.mMin[1], source.mMin[2] ); - b2.SetMax(source.mMax); - - break; - case 1: - b1.SetMin(source.mMin); - b1.SetMax( source.mMax[0], midpoint[1], source.mMax[2] ); - - b2.SetMin( source.mMin[0], midpoint[1], source.mMin[2] ); - b2.SetMax(source.mMax); - - break; - case 2: - b1.SetMin(source.mMin); - b1.SetMax( source.mMax[0], source.mMax[1], midpoint[2] ); - - b2.SetMin( source.mMin[0], source.mMin[1], midpoint[2] ); - b2.SetMax(source.mMax); - - break; - } -} - -bool computeSplitPlane(unsigned int vcount, - const double *vertices, - unsigned int tcount, - const unsigned int *indices, - ConvexDecompInterface *callback, - double *plane) -{ - bool cret = false; - - - double sides[3]; - double matrix[16]; - - computeBestFitOBB( vcount, vertices, sizeof(double)*3, sides, matrix ); - - double bmax[3]; - double bmin[3]; - - bmax[0] = sides[0]*0.5f; - bmax[1] = sides[1]*0.5f; - bmax[2] = sides[2]*0.5f; - - bmin[0] = -bmax[0]; - bmin[1] = -bmax[1]; - bmin[2] = -bmax[2]; - - - double dx = sides[0]; - double dy = sides[1]; - double dz = sides[2]; - - - double laxis = dx; - - unsigned int axis = 0; - - if ( dy > dx ) - { - axis = 1; - laxis = dy; - } - - if ( dz > dx && dz > dy ) - { - axis = 2; - laxis = dz; - } - - double p1[3]; - double p2[3]; - double p3[3]; - - p3[0] = p2[0] = p1[0] = bmin[0] + dx*0.5f; - p3[1] = p2[1] = p1[1] = bmin[1] + dy*0.5f; - p3[2] = p2[2] = p1[2] = bmin[2] + dz*0.5f; - - Rect3d b(bmin,bmax); - - Rect3d b1,b2; - - splitRect(axis,b,b1,b2,p1); - - -// callback->ConvexDebugBound(b1.mMin,b1.mMax,0x00FF00); -// callback->ConvexDebugBound(b2.mMin,b2.mMax,0xFFFF00); - - switch ( axis ) - { - case 0: - p2[1] = bmin[1]; - p2[2] = bmin[2]; - - if ( dz > dy ) - { - p3[1] = bmax[1]; - p3[2] = bmin[2]; - } - else - { - p3[1] = bmin[1]; - p3[2] = bmax[2]; - } - - break; - case 1: - p2[0] = bmin[0]; - p2[2] = bmin[2]; - - if ( dx > dz ) - { - p3[0] = bmax[0]; - p3[2] = bmin[2]; - } - else - { - p3[0] = bmin[0]; - p3[2] = bmax[2]; - } - - break; - case 2: - p2[0] = bmin[0]; - p2[1] = bmin[1]; - - if ( dx > dy ) - { - p3[0] = bmax[0]; - p3[1] = bmin[1]; - } - else - { - p3[0] = bmin[0]; - p3[1] = bmax[1]; - } - - break; - } - - double tp1[3]; - double tp2[3]; - double tp3[3]; - - fm_transform(matrix,p1,tp1); - fm_transform(matrix,p2,tp2); - fm_transform(matrix,p3,tp3); - -// callback->ConvexDebugTri(p1,p2,p3,0xFF0000); - - computePlane(tp1,tp2,tp3,plane); - - return true; - -} - - -}; diff --git a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/splitplane.h b/convex_decomposition/ConvexDecomposition/ConvexDecomposition/splitplane.h deleted file mode 100644 index e7869dd..0000000 --- a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/splitplane.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef SPLIT_PLANE_H - -#define SPLIT_PLANE_H - -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - - - -namespace ConvexDecomposition -{ - -class ConvexDecompInterface; - -bool computeSplitPlane(unsigned int vcount, - const double *vertices, - unsigned int tcount, - const unsigned int *indices, - ConvexDecompInterface *callback, - double *plane); - - -}; - -#endif diff --git a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/triangulate.cpp b/convex_decomposition/ConvexDecomposition/ConvexDecomposition/triangulate.cpp deleted file mode 100644 index 03b517b..0000000 --- a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/triangulate.cpp +++ /dev/null @@ -1,410 +0,0 @@ -#include -#include -#include -#include -#include - -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - - - -#include // Include STL vector class. - -#include "triangulate.h" - - -namespace ConvexDecomposition -{ - - -class Vec2d -{ -public: - Vec2d(const double *v) - { - mX = v[0]; - mY = v[1]; - } - Vec2d(double x,double y) - { - Set(x,y); - }; - double GetX(void) const { return mX; }; - double GetY(void) const { return mY; }; - - void Set(double x,double y) - { - mX = x; - mY = y; - }; - -private: - double mX; - double mY; -};// Typedef an STL vector of vertices which are used to represent -// a polygon/contour and a series of triangles. - -typedef std::vector< Vec2d > Vec2dVector; - -static bool Process(const Vec2dVector &contour,Vec2dVector &result); // compute area of a contour/polygon -static double Area(const Vec2dVector &contour); // decide if point Px/Py is inside triangle defined by (Ax,Ay) (Bx,By) (Cx,Cy) -static bool InsideTriangle(double Ax, double Ay,double Bx, double By,double Cx, double Cy,double Px, double Py); -static bool Snip(const Vec2dVector &contour,int u,int v,int w,int n,int *V); - -static const double EPSILON=0.0000000001f; - -double Area(const Vec2dVector &contour) -{ - int n = contour.size(); - double A=0.0f; - for(int p=n-1,q=0; q= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f)); -}; - -bool Snip(const Vec2dVector &contour,int u,int v,int w,int n,int *V) -{ - int p; - double Ax, Ay, Bx, By, Cx, Cy, Px, Py; - Ax = contour[V[u]].GetX(); - Ay = contour[V[u]].GetY(); - Bx = contour[V[v]].GetX(); - By = contour[V[v]].GetY(); - Cx = contour[V[w]].GetX(); - Cy = contour[V[w]].GetY(); - if ( EPSILON > (((Bx-Ax)*(Cy-Ay)) - ((By-Ay)*(Cx-Ax))) ) return false; for (p=0;p2; ) - { - /* if we loop, it is probably a non-simple polygon */ - if (0 >= (count--)) - { - //** Triangulate: ERROR - probable bad polygon! - return false; - } /* three consecutive vertices in current polygon, */ - - int u = v ; - if (nv <= u) u = 0; /* previous */ - v = u+1; if (nv <= v) v = 0; /* new v */ - int w = v+1; - if (nv <= w) w = 0; /* next */ - - if ( Snip(contour,u,v,w,nv,V) ) - { - int a,b,c,s,t; /* true names of the vertices */ - - a = V[u]; - b = V[v]; - c = V[w]; /* output Triangle */ - - result.push_back( contour[a] ); - result.push_back( contour[b] ); - result.push_back( contour[c] ); - - m++; /* remove v from remaining polygon */ - for(s=v,t=v+1;t= 3 ) - { - double normal[3]; - - normal[0] = plane[0]; - normal[1] = plane[1]; - normal[2] = plane[2]; - double D = plane[3]; - - unsigned int i0 = 0; - unsigned int i1 = 1; - unsigned int i2 = 2; - unsigned int axis = 0; - - - // find the dominant axis. - double dx = fabs(normal[0]); - double dy = fabs(normal[1]); - double dz = fabs(normal[2]); - - if ( dx > dy && dx > dz ) - { - axis = 0; - i0 = 1; - i1 = 2; - i2 = 0; - } - else if ( dy > dx && dy > dz ) - { - i0 = 0; - i1 = 2; - i2 = 1; - axis = 1; - } - else if ( dz > dx && dz > dy ) - { - i0 = 0; - i1 = 1; - i2 = 2; - axis = 2; - } - - double *ptemp = new double[pcount*2]; - double *ptri = new double[maxTri*2*3]; - const double *source = vertices; - double *dest = ptemp; - - for (unsigned int i=0; i -#include -#include -#include - -#pragma warning(disable:4786) - -#include -#include -#include -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - - - - -// CodeSnippet provided by John W. Ratcliff -// on March 23, 2006. -// -// mailto: jratcliff@infiniplex.net -// -// Personal website: http://jratcliffscarab.blogspot.com -// Coding Website: http://codesuppository.blogspot.com -// FundRaising Blog: http://amillionpixels.blogspot.com -// Fundraising site: http://www.amillionpixels.us -// New Temple Site: http://newtemple.blogspot.com -// -// This snippet shows how to 'hide' the complexity of -// the STL by wrapping some useful piece of functionality -// around a handful of discrete API calls. -// -// This API allows you to create an indexed triangle list -// from a collection of raw input triangles. Internally -// it uses an STL set to build the lookup table very rapidly. -// -// Here is how you would use it to build an indexed triangle -// list from a raw list of triangles. -// -// (1) create a 'VertexLookup' interface by calling -// -// VertexLook vl = Vl_createVertexLookup(); -// -// (2) For each vertice in each triangle call: -// -// unsigned int i1 = Vl_getIndex(vl,p1); -// unsigned int i2 = Vl_getIndex(vl,p2); -// unsigned int i3 = Vl_getIndex(vl,p3); -// -// save the 3 indices into your triangle list array. -// -// (3) Get the vertex array by calling: -// -// const double *vertices = Vl_getVertices(vl); -// -// (4) Get the number of vertices so you can copy them into -// your own buffer. -// unsigned int vcount = Vl_getVcount(vl); -// -// (5) Release the VertexLookup interface when you are done with it. -// Vl_releaseVertexLookup(vl); -// -// Teaches the following lessons: -// -// How to wrap the complexity of STL and C++ classes around a -// simple API interface. -// -// How to use an STL set and custom comparator operator for -// a complex data type. -// -// How to create a template class. -// -// How to achieve significant performance improvements by -// taking advantage of built in STL containers in just -// a few lines of code. -// -// You could easily modify this code to support other vertex -// formats with any number of interpolants. - - - - -#include "vlookup.h" - -namespace ConvexDecomposition -{ - -class VertexPosition -{ -public: - VertexPosition(void) { }; - VertexPosition(const double *p) - { - mPos[0] = p[0]; - mPos[1] = p[1]; - mPos[2] = p[2]; - }; - - void Set(int index,const double *pos) - { - const double * p = &pos[index*3]; - - mPos[0] = p[0]; - mPos[1] = p[1]; - mPos[2] = p[2]; - - }; - - double GetX(void) const { return mPos[0]; }; - double GetY(void) const { return mPos[1]; }; - double GetZ(void) const { return mPos[2]; }; - - double mPos[3]; -}; - - -template class VertexLess -{ -public: - typedef std::vector< Type > VertexVector; - - bool operator()(int v1,int v2) const; - - static void SetSearch(const Type& match,VertexVector *list) - { - mFind = match; - mList = list; - }; - -private: - const Type& Get(int index) const - { - if ( index == -1 ) return mFind; - VertexVector &vlist = *mList; - return vlist[index]; - } - static Type mFind; // vertice to locate. - static VertexVector *mList; -}; - -template class VertexPool -{ -public: - typedef std::set > VertexSet; - typedef std::vector< Type > VertexVector; - - int GetVertex(const Type& vtx) - { - VertexLess::SetSearch(vtx,&mVtxs); - typename VertexSet::iterator found; - found = mVertSet.find( -1 ); - if ( found != mVertSet.end() ) - { - return *found; - } - int idx = (int)mVtxs.size(); - mVtxs.push_back( vtx ); - mVertSet.insert( idx ); - return idx; - }; - - const double * GetPos(int idx) const - { - return mVtxs[idx].mPos; - } - - const Type& Get(int idx) const - { - return mVtxs[idx]; - }; - - unsigned int GetSize(void) const - { - return mVtxs.size(); - }; - - void Clear(int reservesize) // clear the vertice pool. - { - mVertSet.clear(); - mVtxs.clear(); - mVtxs.reserve(reservesize); - }; - - const VertexVector& GetVertexList(void) const { return mVtxs; }; - - void Set(const Type& vtx) - { - mVtxs.push_back(vtx); - } - - unsigned int GetVertexCount(void) const - { - return mVtxs.size(); - }; - - - Type * GetBuffer(void) - { - return &mVtxs[0]; - }; - -private: - VertexSet mVertSet; // ordered list. - VertexVector mVtxs; // set of vertices. -}; - -double tmpp[3] = {0,0,0}; -template<> VertexPosition VertexLess::mFind = tmpp; -template<> std::vector *VertexLess::mList =0; - -enum RDIFF -{ - RD_EQUAL, - RD_LESS, - RD_GREATER -}; - -static RDIFF relativeDiff(const double *a,const double *b,double magnitude) -{ - RDIFF ret = RD_EQUAL; - - double m2 = magnitude*magnitude; - double dx = a[0]-b[0]; - double dy = a[1]-b[1]; - double dz = a[2]-b[2]; - double d2 = (dx*dx)+(dy*dy)+(dz*dz); - - if ( d2 > m2 ) - { - if ( a[0] < b[0] ) ret = RD_LESS; - else if ( a[0] > b[0] ) ret = RD_GREATER; - else if ( a[1] < b[1] ) ret = RD_LESS; - else if ( a[1] > b[1] ) ret = RD_GREATER; - else if ( a[2] < b[2] ) ret = RD_LESS; - else if ( a[2] > b[2] ) ret = RD_GREATER; - } - return ret; -} - - -template<> -bool VertexLess::operator()(int v1,int v2) const -{ - bool ret = false; - - const VertexPosition& a = Get(v1); - const VertexPosition& b = Get(v2); - - RDIFF d = relativeDiff(a.mPos,b.mPos,0.0001f); - if ( d == RD_LESS ) ret = true; - - return ret; - -}; - - - -VertexLookup Vl_createVertexLookup(void) -{ - VertexLookup ret = new VertexPool< VertexPosition >; - return ret; -} - -void Vl_releaseVertexLookup(VertexLookup vlook) -{ - VertexPool< VertexPosition > *vp = (VertexPool< VertexPosition > *) vlook; - delete vp; -} - -unsigned int Vl_getIndex(VertexLookup vlook,const double *pos) // get index. -{ - VertexPool< VertexPosition > *vp = (VertexPool< VertexPosition > *) vlook; - VertexPosition p(pos); - return vp->GetVertex(p); -} - -const double * Vl_getVertices(VertexLookup vlook) -{ - VertexPool< VertexPosition > *vp = (VertexPool< VertexPosition > *) vlook; - return vp->GetPos(0); -} - - -unsigned int Vl_getVcount(VertexLookup vlook) -{ - VertexPool< VertexPosition > *vp = (VertexPool< VertexPosition > *) vlook; - return vp->GetVertexCount(); -} - -}; // end of namespace diff --git a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/vlookup.h b/convex_decomposition/ConvexDecomposition/ConvexDecomposition/vlookup.h deleted file mode 100644 index 28d4808..0000000 --- a/convex_decomposition/ConvexDecomposition/ConvexDecomposition/vlookup.h +++ /dev/null @@ -1,143 +0,0 @@ -#ifndef VLOOKUP_H - -#define VLOOKUP_H - -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ - - -// CodeSnippet provided by John W. Ratcliff -// on March 23, 2006. -// -// mailto: jratcliff@infiniplex.net -// -// Personal website: http://jratcliffscarab.blogspot.com -// Coding Website: http://codesuppository.blogspot.com -// FundRaising Blog: http://amillionpixels.blogspot.com -// Fundraising site: http://www.amillionpixels.us -// New Temple Site: http://newtemple.blogspot.com -// -// This snippet shows how to 'hide' the complexity of -// the STL by wrapping some useful piece of functionality -// around a handful of discrete API calls. -// -// This API allows you to create an indexed triangle list -// from a collection of raw input triangles. Internally -// it uses an STL set to build the lookup table very rapidly. -// -// Here is how you would use it to build an indexed triangle -// list from a raw list of triangles. -// -// (1) create a 'VertexLookup' interface by calling -// -// VertexLook vl = Vl_createVertexLookup(); -// -// (2) For each vertice in each triangle call: -// -// unsigned int i1 = Vl_getIndex(vl,p1); -// unsigned int i2 = Vl_getIndex(vl,p2); -// unsigned int i3 = Vl_getIndex(vl,p3); -// -// save the 3 indices into your triangle list array. -// -// (3) Get the vertex array by calling: -// -// const double *vertices = Vl_getVertices(vl); -// -// (4) Get the number of vertices so you can copy them into -// your own buffer. -// unsigned int vcount = Vl_getVcount(vl); -// -// (5) Release the VertexLookup interface when you are done with it. -// Vl_releaseVertexLookup(vl); -// -// Teaches the following lessons: -// -// How to wrap the complexity of STL and C++ classes around a -// simple API interface. -// -// How to use an STL set and custom comparator operator for -// a complex data type. -// -// How to create a template class. -// -// How to achieve significant performance improvements by -// taking advantage of built in STL containers in just -// a few lines of code. -// -// You could easily modify this code to support other vertex -// formats with any number of interpolants. -// -// Hide C++ classes from the rest of your application by -// keeping them in the CPP and wrapping them in a namespace -// Uses an STL set to create an index table for a bunch of vertex positions -// used typically to re-index a collection of raw triangle data. - -namespace ConvexDecomposition -{ - -typedef void * VertexLookup; - -VertexLookup Vl_createVertexLookup(void); -void Vl_releaseVertexLookup(VertexLookup vlook); - -unsigned int Vl_getIndex(VertexLookup vlook,const double *pos); // get index. -const double * Vl_getVertices(VertexLookup vlook); - -unsigned int Vl_getVcount(VertexLookup vlook); - -}; - - -#endif diff --git a/convex_decomposition/ConvexDecomposition/DecomposeSample.cpp b/convex_decomposition/ConvexDecomposition/DecomposeSample.cpp deleted file mode 100644 index 35a1316..0000000 --- a/convex_decomposition/ConvexDecomposition/DecomposeSample.cpp +++ /dev/null @@ -1,668 +0,0 @@ -#include -#include -#include -#include -#include - -#include - -#include "./ConvexDecomposition/ConvexDecomposition.h" -#include "./ConvexDecomposition/cd_wavefront.h" - -using namespace ConvexDecomposition; - -// Test application to demonstrate how to use the ConvexDecomposition system. - -typedef std::vector< ConvexResult * > ConvexResultVector; - -static const char * fstring(float v) -{ - static char data[64*16]; - static int index=0; - - char *ret = &data[index*64]; - index++; - if (index == 16 ) index = 0; - - if ( v == FLT_MIN ) return "-INF"; // collada notation for FLT_MIN and FLT_MAX - if ( v == FLT_MAX ) return "INF"; - - if ( v == 1 ) - { - strcpy(ret,"1"); - } - else if ( v == 0 ) - { - strcpy(ret,"0"); - } - else if ( v == - 1 ) - { - strcpy(ret,"-1"); - } - else - { - sprintf(ret,"%.9f", v ); - const char *dot = strstr(ret,"."); - if ( dot ) - { - int len = (int)strlen(ret); - char *foo = &ret[len-1]; - while ( *foo == '0' ) foo--; - if ( *foo == '.' ) - *foo = 0; - else - foo[1] = 0; - } - } - - return ret; -} - -class CBuilder : public ConvexDecompInterface -{ -public: - - CBuilder(const char *fname,const DecompDesc &d) - { - - strcpy(mBaseName,fname); - char *dot = strstr(mBaseName,"."); - if ( dot ) *dot = 0; - - sprintf(mObjName,"%s_convex.obj", mBaseName ); - - mBaseCount = 0; - mHullCount = 0; - mSkinWidth = (float)d.mSkinWidth; - - mFph = fopen(mObjName,"wb"); - - - printf("########################################################################\r\n"); - printf("# Perfomring approximate convex decomposition for triangle mesh %s\r\n", fname ); - printf("# Input Mesh has %d vertices and %d triangles.\r\n", d.mVcount, d.mTcount ); - printf("# Recursion depth: %d\r\n", d.mDepth ); - printf("# Concavity Threshold Percentage: %0.2f\r\n", d.mCpercent ); - printf("# Hull Merge Volume Percentage: %0.2f\r\n", d.mPpercent ); - printf("# Maximum output vertices per hull: %d\r\n", d.mMaxVertices ); - printf("# Hull Skin Width: %0.2f\r\n", d.mSkinWidth ); - printf("########################################################################\r\n"); - - - if ( mFph ) - { - fprintf(mFph,"########################################################################\r\n"); - fprintf(mFph,"# Approximate convex decomposition for triangle mesh %s\r\n", fname ); - fprintf(mFph,"# Input Mesh has %d vertices and %d triangles.\r\n", d.mVcount, d.mTcount ); - fprintf(mFph,"# Recursion depth: %d\r\n", d.mDepth ); - fprintf(mFph,"# Concavity Threshold Percentage: %0.2f\r\n", d.mCpercent ); - fprintf(mFph,"# Hull Merge Volume Percentage: %0.2f\r\n", d.mPpercent ); - fprintf(mFph,"# Maximum output vertices per hull: %d\r\n", d.mMaxVertices ); - fprintf(mFph,"# Hull Skin Width: %0.2f\r\n", d.mSkinWidth ); - fprintf(mFph,"########################################################################\r\n"); - - printf("Opened Wavefront file %s for output.\r\n", mObjName ); - } - else - { - printf("Failed to open output file %s\r\n", mObjName ); - } - } - - ~CBuilder(void) - { - if ( mFph ) - { - fclose(mFph); - } - for (unsigned int i=0; i\r\n", mBaseName, index, mBaseName, index); - fprintf(fph," \r\n"); - fprintf(fph," \r\n", mBaseName, index); - fprintf(fph," \r\n", cr->mHullVcount*3, mBaseName, index); - fprintf(fph," "); - for (unsigned int i=0; imHullVcount; i++) - { - const double *p = &cr->mHullVertices[i*3]; - fprintf(fph,"%s %s %s ", fstring((float)p[0]), fstring((float)p[1]), fstring((float)p[2]) ); - if ( ((i+1)&3) == 0 && (i+1) < cr->mHullVcount ) - { - fprintf(fph,"\r\n"); - fprintf(fph," "); - } - } - fprintf(fph,"\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n", cr->mHullVcount, mBaseName, index ); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n", mBaseName, index); - fprintf(fph," \r\n", mBaseName, index); - fprintf(fph," \r\n"); - fprintf(fph," \r\n", cr->mHullTcount ); - fprintf(fph," \r\n", mBaseName, index); - fprintf(fph,"

\r\n"); - fprintf(fph," "); - for (unsigned int i=0; imHullTcount; i++) - { - unsigned int *tri = &cr->mHullIndices[i*3]; - fprintf(fph,"%d %d %d ", tri[0], tri[1], tri[2] ); - if ( ((i+1)&3) == 0 && (i+1) < cr->mHullTcount ) - { - fprintf(fph,"\r\n"); - fprintf(fph," "); - } - } - fprintf(fph,"\r\n"); - fprintf(fph,"

\r\n"); - fprintf(fph,"
\r\n"); - fprintf(fph,"
\r\n"); - fprintf(fph," \r\n"); - - } - - void saveCOLLADA(void) - { - char scratch[512]; - sprintf(scratch,"%s.dae", mBaseName ); - FILE *fph = fopen(scratch,"wb"); - - if ( fph ) - { - printf("Saving convex decomposition of %d hulls to COLLADA file '%s'\r\n", (int)mHulls.size(), scratch ); - - fprintf(fph,"\r\n"); - fprintf(fph,"\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," NxuStream2 converter - http://www.ageia.com\r\n"); - fprintf(fph," PhysX Rocket, PhysX Viewer, or CreateDynamics\r\n"); - fprintf(fph," questions to: jratcliff@ageia.com\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," chair_gothic_tilted\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," Y_UP\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," 0.803922 0.588235 0.92549 1\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," 0.803922 0.588235 0.92549 1\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," 0.631373 0.631373 0.631373 1\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," 1\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," 0 0 0 1\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," 1 1 1 1\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," 0\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - - for (unsigned int i=0; i\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n", mBaseName, mBaseName ); - fprintf(fph," 0 0 0\r\n"); - fprintf(fph," 1 0 0 0\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," 0.5\r\n"); - fprintf(fph," 0\r\n"); - fprintf(fph," 0.5\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n", mBaseName, mBaseName); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - - for (unsigned int i=0; i\r\n"); - fprintf(fph," 0 0 0\r\n"); - fprintf(fph," 1 0 0 0\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," 1\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," %s\r\n", fstring( mSkinWidth ) ); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n", mBaseName, i); - fprintf(fph," \r\n"); - } - - fprintf(fph," true\r\n"); - fprintf(fph," 1\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," 0\r\n"); - fprintf(fph," 0\r\n"); - fprintf(fph," 32\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," false\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n", mBaseName, mBaseName ); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," 0 -9.800000191 0\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph,"\r\n"); - - - fclose(fph); - } - else - { - printf("Failed to open file '%s' for write access.\r\n", scratch ); - } - } - - void saveXML(FILE *fph,unsigned int index,ConvexResult *cr) - { - - fprintf(fph," \r\n", mBaseName, index); - fprintf(fph," \r\n"); - fprintf(fph," "); - for (unsigned int i=0; imHullVcount; i++) - { - const double *p = &cr->mHullVertices[i*3]; - fprintf(fph,"%s %s %s ", fstring((float)p[0]), fstring((float)p[1]), fstring((float)p[2]) ); - if ( ((i+1)&3) == 0 && (i+1) < cr->mHullVcount ) - { - fprintf(fph,"\r\n"); - fprintf(fph," "); - } - } - fprintf(fph,"\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," "); - for (unsigned int i=0; imHullTcount; i++) - { - unsigned int *tri = &cr->mHullIndices[i*3]; - fprintf(fph,"%d %d %d ", tri[0], tri[1], tri[2] ); - if ( ((i+1)&3) == 0 && (i+1) < cr->mHullTcount ) - { - fprintf(fph,"\r\n"); - fprintf(fph," "); - } - } - fprintf(fph,"\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - - } - - void saveNxuStream(void) - { - char scratch[512]; - sprintf(scratch,"%s.xml", mBaseName ); - FILE *fph = fopen(scratch,"wb"); - - if ( fph ) - { - printf("Saving convex decomposition of %d hulls to NxuStream file '%s'\r\n", mHulls.size(), scratch ); - - fprintf(fph,"\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," 65536\r\n"); - fprintf(fph," 256\r\n"); - fprintf(fph," 2048\r\n"); - fprintf(fph," \r\n"); - - for (unsigned int i=0; i\r\n", mBaseName); - fprintf(fph," false\r\n"); - fprintf(fph," NX_FILTEROP_AND\r\n"); - fprintf(fph," NX_FILTEROP_AND\r\n"); - fprintf(fph," NX_FILTEROP_AND\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," 0 -9.800000191 0\r\n"); - fprintf(fph," 0.016666668\r\n"); - fprintf(fph," 8\r\n"); - fprintf(fph," NX_TIMESTEP_FIXED\r\n"); - fprintf(fph," FLT_MIN FLT_MIN FLT_MIN FLT_MAX FLT_MAX FLT_MAX\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," 0\r\n"); - fprintf(fph," 0\r\n"); - fprintf(fph," 0\r\n"); - fprintf(fph," 0\r\n"); - fprintf(fph," 0\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," NX_SIMULATION_SW\r\n"); - fprintf(fph," true\r\n"); - fprintf(fph," false\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," false\r\n"); - fprintf(fph," false\r\n"); - fprintf(fph," true\r\n"); - fprintf(fph," false\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," 0\r\n"); - fprintf(fph," 0\r\n"); - fprintf(fph," 1431655764\r\n"); - fprintf(fph," 1431655764\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," 0.5\r\n"); - fprintf(fph," 0.5\r\n"); - fprintf(fph," 0\r\n"); - fprintf(fph," 0\r\n"); - fprintf(fph," 0\r\n"); - fprintf(fph," NX_CM_AVERAGE\r\n"); - fprintf(fph," NX_CM_AVERAGE\r\n"); - fprintf(fph," 1 0 0\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," false\r\n"); - fprintf(fph," false\r\n"); - fprintf(fph," false\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n", mBaseName, mBaseName); - fprintf(fph," 1 0 0 0 1 0 0 0 1 0 0 0 \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," 1\r\n"); - fprintf(fph," 0\r\n"); - fprintf(fph," 0\r\n"); - fprintf(fph," 32\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," true\r\n"); - fprintf(fph," false\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph," Bip01 Pelvis\r\n"); - for (unsigned int i=0; i\r\n", i, mBaseName, i); - fprintf(fph," \r\n"); - fprintf(fph," 1 0 0 0 1 0 0 0 1 0 0 0 \r\n"); - fprintf(fph," 0\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - } - fprintf(fph," \r\n"); - - fprintf(fph," \r\n"); - fprintf(fph," \r\n", mBaseName); - fprintf(fph," beshon\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," 1 0 0 0 1 0 0 0 1 0 0 0\r\n"); - fprintf(fph," false\r\n"); - fprintf(fph," true\r\n"); - fprintf(fph," 0\r\n"); - fprintf(fph," \r\n"); - fprintf(fph," \r\n"); - fprintf(fph,"\r\n"); - - } - else - { - printf("Failed to open file '%s' for write access.\r\n", scratch ); - } - } - - float mSkinWidth; - unsigned int mHullCount; - FILE *mFph; - unsigned int mBaseCount; - char mObjName[512]; - char mBaseName[512]; - ConvexResultVector mHulls; - -}; - - -int main(int argc,const char **argv) -{ - if ( argc < 2 ) - { - printf("Usage: Test (options)\r\n"); - printf("\r\n"); - printf("Options:\r\n"); - printf("\r\n"); - printf(" -d : How deep to recursively split. Values of 3-7 are reasonable.\r\n"); - printf(" -c : Percentage of concavity to keep splitting. 0-20% is reasonable.\r\n"); - printf(" -p : Percentage of volume delta to collapse hulls. 0-30% is reasonable.\r\n"); - printf(" -v : Maximum number of vertices in the output hull. Default is 32.\r\n"); - printf(" -s : Skin Width inflation. Default is 0.\r\n"); - } - else - { - unsigned int depth = 5; - float cpercent = 5; - float ppercent = 5; - unsigned int maxv = 32; - float skinWidth = 0; - - // process command line switches. - for (int i=2; i 10 ) - { - depth = 5; - printf("Invalid depth value in switch, defaulting to 5.\r\n"); - } - } - - if ( strncmp(o,"-c",2) == 0 ) - { - cpercent = (float) atof( &o[2] ); - if ( cpercent < 0 || cpercent > 100 ) - { - cpercent = 5; - printf("Invalid concavity percentage in switch, defaulting to 5.\r\n"); - } - } - - if ( strncmp(o,"-p",2) == 0 ) - { - ppercent = (float) atof( &o[2] ); - if ( ppercent < 0 || ppercent > 100 ) - { - ppercent = 5; - printf("Invalid hull merge percentage in switch, defaulting to 5.\r\n"); - } - } - - if ( strncmp(o,"-v",2) == 0 ) - { - maxv = (unsigned int) atoi( &o[2] ); - if ( maxv < 8 || maxv > 256 ) - { - maxv = 32; - printf("Invalid max vertices in switch, defaulting to 32.\r\n"); - } - } - - if ( strncmp(o,"-s",2) == 0 ) - { - skinWidth = (float) atof( &o[2] ); - if ( skinWidth < 0 || skinWidth > 0.1f ) - { - skinWidth = 0; - printf("Invalid skinWidth in switch, defaulting to 0.\r\n"); - } - } - - } - - WavefrontObj wo; - - unsigned int tcount = wo.loadObj(argv[1]); - - if ( tcount ) - { - - - DecompDesc d; - - d.mVcount = wo.mVertexCount; - d.mVertices = wo.mVertices; - d.mTcount = wo.mTriCount; - d.mIndices = (unsigned int *)wo.mIndices; - d.mDepth = depth; - d.mCpercent = cpercent; - d.mPpercent = ppercent; - d.mMaxVertices = maxv; - d.mSkinWidth = skinWidth; - - - CBuilder cb(argv[1],d); // receives the answers and writes out a wavefront OBJ file. - - d.mCallback = &cb; - - unsigned int count = performConvexDecomposition(d); - - if ( count ) - { - printf("Input triangle mesh with %d triangles produced %d output hulls.\r\n", d.mTcount, count ); - - cb.saveNxuStream(); // save results in NxuStream format. - cb.saveCOLLADA(); // save results in COLLADA physics 1.4.1 format. - - } - else - { - printf("Failed to produce any convex hulls.\r\n"); - } - - } - else - { - // sorry..no - printf("Sorry unable to load file '%s'\r\n", argv[1] ); - } - - } - -} diff --git a/convex_decomposition/ConvexDecomposition/DecomposeSample.exe b/convex_decomposition/ConvexDecomposition/DecomposeSample.exe deleted file mode 100644 index f90888f..0000000 Binary files a/convex_decomposition/ConvexDecomposition/DecomposeSample.exe and /dev/null differ diff --git a/convex_decomposition/ConvexDecomposition/DecomposeSample.sln b/convex_decomposition/ConvexDecomposition/DecomposeSample.sln deleted file mode 100644 index fd17eea..0000000 --- a/convex_decomposition/ConvexDecomposition/DecomposeSample.sln +++ /dev/null @@ -1,21 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DecomposeSample", "DecomposeSample.vcproj", "{0282D4E2-DA97-437D-9BDE-1C9F5E56F6F8}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - Release = Release - EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {0282D4E2-DA97-437D-9BDE-1C9F5E56F6F8}.Debug.ActiveCfg = Debug|Win32 - {0282D4E2-DA97-437D-9BDE-1C9F5E56F6F8}.Debug.Build.0 = Debug|Win32 - {0282D4E2-DA97-437D-9BDE-1C9F5E56F6F8}.Release.ActiveCfg = Release|Win32 - {0282D4E2-DA97-437D-9BDE-1C9F5E56F6F8}.Release.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution - EndGlobalSection -EndGlobal diff --git a/convex_decomposition/ConvexDecomposition/DecomposeSample.suo b/convex_decomposition/ConvexDecomposition/DecomposeSample.suo deleted file mode 100644 index 9ec8d93..0000000 Binary files a/convex_decomposition/ConvexDecomposition/DecomposeSample.suo and /dev/null differ diff --git a/convex_decomposition/ConvexDecomposition/DecomposeSample.vcproj b/convex_decomposition/ConvexDecomposition/DecomposeSample.vcproj deleted file mode 100644 index 72ecf9b..0000000 --- a/convex_decomposition/ConvexDecomposition/DecomposeSample.vcproj +++ /dev/null @@ -1,240 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/convex_decomposition/ConvexDecomposition/Makefile b/convex_decomposition/ConvexDecomposition/Makefile deleted file mode 100644 index e92b84c..0000000 --- a/convex_decomposition/ConvexDecomposition/Makefile +++ /dev/null @@ -1,93 +0,0 @@ - - -OBJS = DecomposeSample.o \ - ConvexDecomposition/bestfit.o ConvexDecomposition/float_math.o \ - ConvexDecomposition/bestfitobb.o ConvexDecomposition/meshvolume.o \ - ConvexDecomposition/cd_hull.o ConvexDecomposition/planetri.o \ - ConvexDecomposition/cd_wavefront.o ConvexDecomposition/raytri.o \ - ConvexDecomposition/concavity.o ConvexDecomposition/splitplane.o \ - ConvexDecomposition/ConvexDecomposition.o ConvexDecomposition/triangulate.o \ - ConvexDecomposition/fitsphere.o ConvexDecomposition/vlookup.o - -HEADERS = \ - ConvexDecomposition/bestfit.h \ - ConvexDecomposition/bestfitobb.h \ - ConvexDecomposition/cd_hull.h \ - ConvexDecomposition/cd_vector.h \ - ConvexDecomposition/cd_wavefront.h \ - ConvexDecomposition/concavity.h \ - ConvexDecomposition/ConvexDecomposition.h \ - ConvexDecomposition/fitsphere.h \ - ConvexDecomposition/float_math.h \ - ConvexDecomposition/meshvolume.h \ - ConvexDecomposition/planetri.h \ - ConvexDecomposition/raytri.h \ - ConvexDecomposition/splitplane.h \ - ConvexDecomposition/triangulate.h \ - ConvexDecomposition/vlookup.h - -CC = g++ - -DEBUG = -ggdb - -CFLAGS = -IConvexDecomposition -Wall -c $(DEBUG) - -LFLAGS = $(DEBUG) - -convex_decomposition: $(OBJS) - $(CC) $(LFLAGS) $(OBJS) -o convex_decomposition - -DecomposeSample.o: DecomposeSample.cpp - $(CC) $(CFLAGS) DecomposeSample.cpp -o $@ - -ConvexDecomposition/bestfit.o: ConvexDecomposition/bestfit.cpp - $(CC) $(CFLAGS) ConvexDecomposition/bestfit.cpp -o $@ - -ConvexDecomposition/bestfitobb.o: ConvexDecomposition/bestfitobb.cpp - $(CC) $(CFLAGS) ConvexDecomposition/bestfitobb.cpp -o $@ - -ConvexDecomposition/cd_hull.o: ConvexDecomposition/cd_hull.cpp - $(CC) $(CFLAGS) ConvexDecomposition/cd_hull.cpp -o $@ - -ConvexDecomposition/cd_wavefront.o: ConvexDecomposition/cd_wavefront.cpp - $(CC) $(CFLAGS) ConvexDecomposition/cd_wavefront.cpp -o $@ - -ConvexDecomposition/concavity.o: ConvexDecomposition/concavity.cpp - $(CC) $(CFLAGS) ConvexDecomposition/concavity.cpp -o $@ - -ConvexDecomposition/ConvexDecomposition.o: ConvexDecomposition/ConvexDecomposition.cpp - $(CC) $(CFLAGS) ConvexDecomposition/ConvexDecomposition.cpp -o $@ - -ConvexDecomposition/fitsphere.o: ConvexDecomposition/fitsphere.cpp - $(CC) $(CFLAGS) ConvexDecomposition/fitsphere.cpp -o $@ - -ConvexDecomposition/float_math.o: ConvexDecomposition/float_math.cpp - $(CC) $(CFLAGS) ConvexDecomposition/float_math.cpp -o $@ - -ConvexDecomposition/meshvolume.o: ConvexDecomposition/meshvolume.cpp - $(CC) $(CFLAGS) ConvexDecomposition/meshvolume.cpp -o $@ - -ConvexDecomposition/planetri.o: ConvexDecomposition/planetri.cpp - $(CC) $(CFLAGS) ConvexDecomposition/planetri.cpp -o $@ - -ConvexDecomposition/raytri.o: ConvexDecomposition/raytri.cpp - $(CC) $(CFLAGS) ConvexDecomposition/raytri.cpp -o $@ - -ConvexDecomposition/splitplane.o: ConvexDecomposition/splitplane.cpp - $(CC) $(CFLAGS) ConvexDecomposition/splitplane.cpp -o $@ - -ConvexDecomposition/triangulate.o: ConvexDecomposition/triangulate.cpp - $(CC) $(CFLAGS) ConvexDecomposition/triangulate.cpp -o $@ - -ConvexDecomposition/vlookup.o: ConvexDecomposition/vlookup.cpp ConvexDecomposition/vlookup.cpp - $(CC) $(CFLAGS) ConvexDecomposition/vlookup.cpp -o $@ - -install: - cp convex_decomposition ../../convex_decomposition/bin/ - -clean: - \rm *.o */*.o convex_decomposition - -tar: - tar cfv ConvexDecomposition.tar DecomposeSample.cpp convex_decomposition Makefile \ - ConvexDecomposition diff --git a/convex_decomposition/ConvexDecomposition/chair.obj b/convex_decomposition/ConvexDecomposition/chair.obj deleted file mode 100644 index eddbcf4..0000000 --- a/convex_decomposition/ConvexDecomposition/chair.obj +++ /dev/null @@ -1,3083 +0,0 @@ -v -0.203961 0.754510 0.211019 -v -0.199603 1.785488 -0.001498 -v -0.199163 0.754510 -0.001498 -v -0.199603 1.785488 -0.001498 -v -0.203961 0.754510 0.211019 -v -0.199830 1.524172 0.214066 -v -0.214032 1.655104 0.216193 -v -0.199830 1.524172 0.214066 -v -0.214032 0.738577 0.216193 -v -0.203961 0.754510 0.211019 -v -0.214032 0.738577 0.216193 -v -0.199830 1.524172 0.214066 -v -0.214032 0.738577 0.216193 -v -0.203961 0.754510 0.211019 -v -0.209234 0.738577 -0.001498 -v -0.199163 0.754510 -0.001498 -v -0.209234 0.738577 -0.001498 -v -0.203961 0.754510 0.211019 -v 0.056176 0.210912 -0.001498 -v -0.011230 0.210913 0.215059 -v -0.012112 0.210912 -0.001498 -v 0.057057 0.210913 0.214728 -v -0.012112 0.210912 -0.001498 -v -0.011230 0.275571 0.215059 -v -0.012112 0.275571 -0.001498 -v -0.011230 0.210913 0.215059 -v -0.012112 0.275571 -0.001498 -v 0.057057 0.275571 0.214728 -v 0.056176 0.275571 -0.001498 -v -0.011230 0.275571 0.215059 -v 0.056176 0.275571 -0.001498 -v 0.057057 0.210913 0.214728 -v 0.056176 0.210912 -0.001498 -v 0.057057 0.275571 0.214728 -v 0.057057 0.210913 0.214728 -v -0.146260 0.206221 0.217801 -v -0.011230 0.210913 0.215059 -v -0.146260 0.206221 0.217801 -v 0.057057 0.210913 0.214728 -v 0.182828 0.206221 0.216341 -v -0.011230 0.275571 0.215059 -v 0.182828 0.280263 0.216341 -v 0.057057 0.275571 0.214728 -v 0.182828 0.280263 0.216341 -v -0.011230 0.275571 0.215059 -v -0.146260 0.280263 0.217801 -v -0.011230 0.210913 0.215059 -v -0.146260 0.280263 0.217801 -v -0.011230 0.275571 0.215059 -v -0.146260 0.206221 0.217801 -v 0.057057 0.275571 0.214728 -v 0.182828 0.206221 0.216341 -v 0.057057 0.210913 0.214728 -v 0.182828 0.280263 0.216341 -v -0.146260 0.206221 0.217801 -v 0.181545 0.206221 0.286352 -v -0.147543 0.206221 0.287812 -v 0.182828 0.206221 0.216341 -v -0.147543 0.206221 0.287812 -v 0.181545 0.280263 0.286352 -v -0.147543 0.280263 0.287812 -v 0.181545 0.206221 0.286352 -v -0.147543 0.280263 0.287812 -v 0.182828 0.280263 0.216341 -v -0.146260 0.280263 0.217801 -v 0.181545 0.280263 0.286352 -v -0.208590 -0.001787 0.279676 -v -0.214032 0.243242 0.216341 -v -0.207557 -0.001787 0.223301 -v -0.215315 0.243242 0.286352 -v -0.207557 -0.001787 0.223301 -v -0.146260 0.206221 0.217801 -v -0.152985 -0.001787 0.224477 -v -0.146260 0.206221 0.217801 -v -0.207557 -0.001787 0.223301 -v -0.214032 0.243242 0.216341 -v -0.152985 -0.001787 0.224477 -v -0.147543 0.206221 0.287812 -v -0.154018 -0.001787 0.280852 -v -0.146260 0.206221 0.217801 -v -0.154018 -0.001787 0.280852 -v -0.215315 0.243242 0.286352 -v -0.208590 -0.001787 0.279676 -v -0.215315 0.243242 0.286352 -v -0.154018 -0.001787 0.280852 -v -0.147543 0.206221 0.287812 -v 0.188270 -0.001787 0.279676 -v 0.182828 0.206221 0.216341 -v 0.189303 -0.001787 0.223301 -v 0.181545 0.206221 0.286352 -v 0.189303 -0.001787 0.223301 -v 0.250600 0.243242 0.217801 -v 0.243875 -0.001787 0.224477 -v 0.250600 0.243242 0.217801 -v 0.189303 -0.001787 0.223301 -v 0.182828 0.206221 0.216341 -v 0.243875 -0.001787 0.224477 -v 0.249317 0.243242 0.287812 -v 0.242842 -0.001787 0.280852 -v 0.250600 0.243242 0.217801 -v 0.242842 -0.001787 0.280852 -v 0.181545 0.206221 0.286352 -v 0.188270 -0.001787 0.279676 -v 0.181545 0.206221 0.286352 -v 0.242842 -0.001787 0.280852 -v 0.249317 0.243242 0.287812 -v -0.214032 0.243242 0.216341 -v -0.146260 0.280263 0.217801 -v -0.146260 0.206221 0.217801 -v -0.215315 0.243242 0.286352 -v -0.147543 0.206221 0.287812 -v -0.147543 0.280263 0.287812 -v 0.250600 0.243242 0.217801 -v 0.182828 0.206221 0.216341 -v 0.182828 0.280263 0.216341 -v 0.249317 0.243242 0.287812 -v 0.181545 0.280263 0.286352 -v 0.181545 0.206221 0.286352 -v -0.215315 0.243242 0.286352 -v -0.214032 0.377162 0.216341 -v -0.214032 0.243242 0.216341 -v -0.147543 0.280263 0.287812 -v -0.146260 0.280263 0.217801 -v -0.146260 0.377162 0.217801 -v 0.181545 0.280263 0.286352 -v 0.182828 0.377162 0.216341 -v 0.182828 0.280263 0.216341 -v 0.249317 0.243242 0.287812 -v 0.250600 0.243242 0.217801 -v 0.250600 0.377162 0.217801 -v 0.250600 0.377162 0.217801 -v 0.182828 0.377162 0.216341 -v -0.146260 0.377162 0.217801 -v -0.214032 0.377162 0.216341 -v -0.128461 1.675364 -0.001498 -v -0.146260 1.508024 0.217653 -v -0.132386 1.472782 0.176497 -v -0.146260 1.508024 0.217653 -v -0.128461 1.675364 -0.001498 -v -0.141462 1.768750 -0.001498 -v -0.132386 0.781150 0.176497 -v -0.141462 0.738577 -0.001498 -v -0.128461 0.781150 -0.001498 -v -0.146260 0.738577 0.217653 -v -0.132386 1.472782 0.176497 -v -0.146260 0.738577 0.217653 -v -0.132386 0.781150 0.176497 -v -0.146260 1.508024 0.217653 -v -0.160112 1.524172 0.214922 -v -0.141462 1.768750 -0.001498 -v -0.159884 1.785488 -0.001498 -v -0.141462 1.768750 -0.001498 -v -0.160112 1.524172 0.214922 -v -0.146260 1.508024 0.217653 -v -0.128461 0.781150 -0.001498 -v -0.128461 1.675364 -0.001498 -v -0.132386 0.781150 0.176497 -v -0.132386 1.472782 0.176497 -v -0.174244 1.836233 0.258962 -v -0.187331 1.836233 0.244894 -v -0.187584 1.836233 0.258675 -v -0.173991 1.836233 0.245182 -v -0.160446 1.785009 0.231735 -v -0.174244 1.836233 0.258962 -v -0.161202 1.785009 0.272981 -v -0.173991 1.836233 0.245182 -v -0.200373 1.785009 0.230875 -v -0.173991 1.836233 0.245182 -v -0.160446 1.785009 0.231735 -v -0.187331 1.836233 0.244894 -v -0.201129 1.785009 0.272121 -v -0.187331 1.836233 0.244894 -v -0.200373 1.785009 0.230875 -v -0.187584 1.836233 0.258675 -v -0.161202 1.785009 0.272981 -v -0.187584 1.836233 0.258675 -v -0.201129 1.785009 0.272121 -v -0.174244 1.836233 0.258962 -v -0.137050 1.756645 0.235571 -v -0.195826 1.756645 0.206731 -v -0.224525 1.756645 0.268286 -v -0.165749 1.756645 0.297125 -v -0.137050 1.756645 0.235571 -v -0.137050 1.715855 0.235571 -v -0.164105 1.756645 0.207415 -v -0.164105 1.715855 0.207415 -v -0.195826 1.756645 0.206731 -v -0.195826 1.715855 0.206731 -v -0.223891 1.756645 0.233700 -v -0.223891 1.715855 0.233700 -v -0.165749 1.756645 0.297125 -v -0.165749 1.715855 0.297125 -v -0.137684 1.756645 0.270157 -v -0.137684 1.715855 0.270157 -v -0.224525 1.756645 0.268286 -v -0.224525 1.715855 0.268286 -v -0.197470 1.756645 0.296441 -v -0.197470 1.715855 0.296441 -v -0.161841 1.691613 0.233120 -v -0.137684 1.715855 0.270157 -v -0.162545 1.691613 0.271537 -v -0.199030 1.691613 0.232319 -v -0.164105 1.715855 0.207415 -v -0.161841 1.691613 0.233120 -v -0.199734 1.691613 0.270736 -v -0.223891 1.715855 0.233700 -v -0.199030 1.691613 0.232319 -v -0.162545 1.691613 0.271537 -v -0.197470 1.715855 0.296441 -v -0.199734 1.691613 0.270736 -v -0.137684 1.756645 0.270157 -v -0.164105 1.756645 0.207415 -v -0.223891 1.756645 0.233700 -v -0.197470 1.756645 0.296441 -v -0.137050 1.715855 0.235571 -v -0.195826 1.715855 0.206731 -v -0.224525 1.715855 0.268286 -v -0.165749 1.715855 0.297125 -v -0.161202 1.785009 0.272981 -v -0.160446 1.785009 0.231735 -v -0.201129 1.785009 0.272121 -v -0.200373 1.785009 0.230875 -v -0.162545 1.691613 0.271537 -v -0.161841 1.691613 0.233120 -v -0.199734 1.691613 0.270736 -v -0.199030 1.691613 0.232319 -v -0.162545 1.691613 0.271537 -v -0.161841 1.668882 0.233120 -v -0.161841 1.691613 0.233120 -v -0.162545 1.668882 0.271537 -v -0.161841 1.691613 0.233120 -v -0.199030 1.668882 0.232319 -v -0.199030 1.691613 0.232319 -v -0.161841 1.668882 0.233120 -v -0.199030 1.691613 0.232319 -v -0.199734 1.668882 0.270736 -v -0.199734 1.691613 0.270736 -v -0.199030 1.668882 0.232319 -v -0.199734 1.691613 0.270736 -v -0.162545 1.668882 0.271537 -v -0.162545 1.691613 0.271537 -v -0.199734 1.668882 0.270736 -v -0.161841 1.668882 0.233120 -v -0.214032 1.655104 0.216193 -v -0.199030 1.668882 0.232319 -v -0.146260 1.655104 0.217653 -v -0.162545 1.668882 0.271537 -v -0.146260 1.655104 0.217653 -v -0.161841 1.668882 0.233120 -v -0.147543 1.655104 0.287664 -v -0.199734 1.668882 0.270736 -v -0.147543 1.655104 0.287664 -v -0.162545 1.668882 0.271537 -v -0.215315 1.655104 0.286203 -v -0.199030 1.668882 0.232319 -v -0.215315 1.655104 0.286203 -v -0.199734 1.668882 0.270736 -v -0.214032 1.655104 0.216193 -v -0.159884 1.900273 -0.001498 -v -0.160112 1.524172 0.214922 -v -0.159884 1.785488 -0.001498 -v -0.160112 1.638956 0.214922 -v -0.199603 1.785488 -0.001498 -v -0.199830 1.638956 0.214066 -v -0.199603 1.900273 -0.001498 -v -0.199830 1.524172 0.214066 -v -0.199603 1.900273 -0.001498 -v -0.160112 1.638956 0.214922 -v -0.159884 1.900273 -0.001498 -v -0.160112 1.638956 0.214922 -v -0.199603 1.900273 -0.001498 -v -0.199830 1.638956 0.214066 -v -0.160112 1.638956 0.214922 -v -0.146260 1.508024 0.217653 -v -0.160112 1.524172 0.214922 -v -0.146260 1.655104 0.217653 -v -0.199830 1.638956 0.214066 -v -0.146260 1.655104 0.217653 -v -0.160112 1.638956 0.214922 -v -0.214032 1.655104 0.216193 -v -0.199830 1.638956 0.214066 -v -0.147543 1.655104 0.287664 -v -0.146260 1.508024 0.217653 -v -0.146260 1.655104 0.217653 -v -0.141462 0.738577 -0.001498 -v -0.146260 0.683386 0.217653 -v -0.141462 0.682417 -0.001498 -v -0.146260 0.738577 0.217653 -v -0.209234 0.682417 -0.001498 -v -0.214032 0.738577 0.216193 -v -0.209234 0.738577 -0.001498 -v -0.214032 0.683393 0.216193 -v -0.141462 0.682417 -0.001498 -v -0.214032 0.683393 0.216193 -v -0.209234 0.682417 -0.001498 -v -0.146260 0.683386 0.217653 -v -0.146260 0.738577 0.217653 -v -0.147543 0.738577 0.287664 -v -0.215315 1.655104 0.286203 -v -0.147543 0.738577 0.287664 -v -0.147543 1.655104 0.287664 -v -0.215315 0.710897 0.286203 -v -0.214032 1.655104 0.216193 -v -0.215315 0.710897 0.286203 -v -0.215315 1.655104 0.286203 -v -0.214032 0.738577 0.216193 -v -0.213681 0.377162 -0.001498 -v -0.214032 0.456870 0.216341 -v -0.213680 0.456870 -0.001498 -v -0.214032 0.377162 0.216341 -v -0.213680 0.456870 -0.001498 -v -0.231718 0.471319 0.172684 -v -0.231718 0.471319 -0.001498 -v -0.214032 0.456870 0.216341 -v 0.261861 0.726253 0.301147 -v -0.147543 0.738577 0.287664 -v -0.134999 0.726253 0.301147 -v 0.245288 0.738577 0.287664 -v -0.133232 0.726253 0.204720 -v 0.246571 0.738577 0.217653 -v 0.263628 0.726253 0.204720 -v -0.146260 0.738577 0.217653 -v -0.133232 0.690088 0.204720 -v -0.146260 0.683386 0.217653 -v -0.147543 0.683217 0.287664 -v -0.134999 0.690088 0.301147 -v -0.147543 0.683217 0.287664 -v -0.214032 0.683393 0.216193 -v 0.263628 0.690088 0.204720 -v 0.261861 0.690088 0.301147 -v 0.261861 0.690088 0.301147 -v 0.249317 0.683217 0.287664 -v 0.250600 0.683217 0.217653 -v 0.263628 0.690088 0.204720 -v 0.249317 0.683217 0.287664 -v -0.147543 0.609148 0.288033 -v 0.181545 0.609148 0.286573 -v -0.147543 0.609148 0.288033 -v 0.249317 0.683217 0.287664 -v -0.147543 0.683217 0.287664 -v 0.182828 0.608985 0.216563 -v -0.146260 0.683386 0.217653 -v 0.250600 0.683217 0.217653 -v -0.146260 0.683386 0.217653 -v 0.182828 0.608985 0.216563 -v -0.146260 0.608985 0.218023 -v 0.181545 0.609148 0.286573 -v -0.146260 0.608985 0.218023 -v 0.182828 0.608985 0.216563 -v -0.147543 0.609148 0.288033 -v 0.261861 0.726253 0.301147 -v -0.215315 0.710897 0.286203 -v -0.147543 0.609148 0.288033 -v -0.147543 0.683217 0.287664 -v -0.214032 0.683393 0.216193 -v -0.146260 0.683386 0.217653 -v -0.146260 0.608985 0.218023 -v -0.214032 0.456870 0.216341 -v -0.146260 0.456870 0.217801 -v -0.147543 0.609148 0.288033 -v -0.146260 0.608985 0.218023 -v -0.215315 0.710897 0.286203 -v -0.147543 0.280263 0.287812 -v -0.147543 0.609148 0.288033 -v -0.214032 0.456870 0.216341 -v -0.146260 0.608985 0.218023 -v -0.146260 0.456870 0.217801 -v -0.146260 0.608985 0.218023 -v -0.214032 0.456870 0.216341 -v -0.214032 0.683393 0.216193 -v -0.152985 -0.001787 0.224477 -v -0.208590 -0.001787 0.279676 -v -0.207557 -0.001787 0.223301 -v -0.154018 -0.001787 0.280852 -v 0.250600 0.683217 0.217653 -v 0.249317 0.683217 0.287664 -v 0.182828 0.608985 0.216563 -v 0.182828 0.456870 0.216341 -v 0.181545 0.609148 0.286573 -v 0.250600 0.456870 0.217801 -v 0.249317 0.683217 0.287664 -v 0.250600 0.683217 0.217653 -v 0.181545 0.609148 0.286573 -v 0.181545 0.609148 0.286573 -v 0.249317 0.243242 0.287812 -v 0.249317 0.683217 0.287664 -v 0.182828 0.456870 0.216341 -v 0.250600 0.683217 0.217653 -v 0.250600 0.456870 0.217801 -v 0.250600 0.683217 0.217653 -v 0.182828 0.456870 0.216341 -v 0.182828 0.608985 0.216563 -v 0.243875 -0.001787 0.224477 -v 0.188270 -0.001787 0.279676 -v 0.189303 -0.001787 0.223301 -v 0.242842 -0.001787 0.280852 -v 0.250600 0.377162 0.217801 -v 0.247841 0.456870 -0.001498 -v 0.250600 0.456870 0.217801 -v 0.247847 0.377162 -0.001498 -v -0.146260 0.456870 0.217801 -v 0.182828 0.377162 0.216341 -v 0.182828 0.456870 0.216341 -v -0.146260 0.377162 0.217801 -v 0.247841 0.456870 -0.001498 -v 0.262209 0.471319 0.172684 -v 0.250600 0.456870 0.217801 -v 0.262209 0.471319 -0.001498 -v -0.231718 0.520293 -0.001498 -v -0.231718 0.520293 0.172684 -v -0.223747 0.491776 0.204447 -v -0.163649 0.564918 -0.001498 -v -0.163649 0.564918 0.172684 -v 0.199481 0.564918 -0.001498 -v 0.199481 0.564918 0.172684 -v 0.262209 0.520293 -0.001498 -v 0.262209 0.520293 0.172684 -v -0.163649 0.522718 0.208096 -v 0.199480 0.522718 0.208096 -v 0.261171 0.491776 0.208368 -v 0.262209 0.520293 -0.001498 -v 0.261171 0.491776 0.208368 -v 0.247847 0.377162 -0.001498 -v 0.182828 0.377162 0.216341 -v 0.182828 0.377162 -0.001498 -v 0.250600 0.377162 0.217801 -v -0.147984 0.377162 -0.001498 -v 0.182828 0.377162 0.216341 -v -0.146260 0.377162 0.217801 -v 0.182828 0.377162 -0.001498 -v -0.147984 0.377162 -0.001498 -v -0.214032 0.377162 0.216341 -v -0.213681 0.377162 -0.001498 -v -0.146260 0.377162 0.217801 -v 0.182828 0.456870 0.216341 -v 0.250600 0.456870 0.217801 -v -0.146260 0.456870 0.217801 -v -0.214032 0.456870 0.216341 -v -0.203961 0.754510 -0.214016 -v -0.199163 0.754510 -0.001498 -v -0.199603 1.785488 -0.001498 -v -0.199603 1.785488 -0.001498 -v -0.199830 1.524172 -0.217063 -v -0.203961 0.754510 -0.214016 -v -0.214032 1.655105 -0.219189 -v -0.214032 0.738577 -0.219189 -v -0.199830 1.524172 -0.217063 -v -0.203961 0.754510 -0.214016 -v -0.199830 1.524172 -0.217063 -v -0.214032 0.738577 -0.219189 -v -0.214032 0.738577 -0.219189 -v -0.209234 0.738577 -0.001498 -v -0.203961 0.754510 -0.214016 -v -0.199163 0.754510 -0.001498 -v -0.203961 0.754510 -0.214016 -v -0.209234 0.738577 -0.001498 -v -0.011230 0.210913 -0.218055 -v 0.057057 0.210913 -0.217724 -v -0.012112 0.210912 -0.001498 -v -0.012112 0.275571 -0.001498 -v -0.011230 0.275571 -0.218055 -v -0.011230 0.210913 -0.218055 -v 0.057057 0.275571 -0.217724 -v -0.011230 0.275571 -0.218055 -v 0.056176 0.275571 -0.001498 -v 0.056176 0.210912 -0.001498 -v 0.057057 0.210913 -0.217724 -v 0.057057 0.275571 -0.217724 -v 0.057057 0.210913 -0.217724 -v -0.011230 0.210913 -0.218055 -v -0.146260 0.206221 -0.220798 -v -0.146260 0.206221 -0.220798 -v 0.182828 0.206221 -0.219337 -v 0.057057 0.210913 -0.217724 -v -0.011230 0.275571 -0.218055 -v 0.057057 0.275571 -0.217724 -v 0.182828 0.280263 -0.219337 -v 0.182828 0.280263 -0.219337 -v -0.146260 0.280263 -0.220798 -v -0.011230 0.275571 -0.218055 -v -0.011230 0.210913 -0.218055 -v -0.011230 0.275571 -0.218055 -v -0.146260 0.280263 -0.220798 -v -0.146260 0.206221 -0.220798 -v 0.057057 0.275571 -0.217724 -v 0.057057 0.210913 -0.217724 -v 0.182828 0.206221 -0.219337 -v 0.182828 0.280263 -0.219337 -v -0.146260 0.206221 -0.220798 -v -0.147543 0.206221 -0.290808 -v 0.181545 0.206221 -0.289348 -v 0.182828 0.206221 -0.219337 -v -0.147543 0.206221 -0.290808 -v -0.147543 0.280263 -0.290808 -v 0.181545 0.280263 -0.289348 -v 0.181545 0.206221 -0.289348 -v -0.147543 0.280263 -0.290808 -v -0.146260 0.280263 -0.220798 -v 0.182828 0.280263 -0.219337 -v 0.181545 0.280263 -0.289348 -v -0.208590 -0.001787 -0.282672 -v -0.207557 -0.001787 -0.226297 -v -0.214032 0.243242 -0.219337 -v -0.215315 0.243242 -0.289348 -v -0.207557 -0.001787 -0.226297 -v -0.152985 -0.001787 -0.227473 -v -0.146260 0.206221 -0.220798 -v -0.146260 0.206221 -0.220798 -v -0.214032 0.243242 -0.219337 -v -0.207557 -0.001787 -0.226297 -v -0.152985 -0.001787 -0.227473 -v -0.154018 -0.001787 -0.283848 -v -0.147543 0.206221 -0.290808 -v -0.146260 0.206221 -0.220798 -v -0.154018 -0.001787 -0.283848 -v -0.208590 -0.001787 -0.282672 -v -0.215315 0.243242 -0.289348 -v -0.215315 0.243242 -0.289348 -v -0.147543 0.206221 -0.290808 -v -0.154018 -0.001787 -0.283848 -v 0.188270 -0.001787 -0.282672 -v 0.189303 -0.001787 -0.226297 -v 0.182828 0.206221 -0.219337 -v 0.181545 0.206221 -0.289348 -v 0.189303 -0.001787 -0.226297 -v 0.243875 -0.001787 -0.227473 -v 0.250600 0.243242 -0.220798 -v 0.250600 0.243242 -0.220798 -v 0.182828 0.206221 -0.219337 -v 0.189303 -0.001787 -0.226297 -v 0.243875 -0.001787 -0.227473 -v 0.242842 -0.001787 -0.283848 -v 0.249317 0.243242 -0.290808 -v 0.250600 0.243242 -0.220798 -v 0.242842 -0.001787 -0.283848 -v 0.188270 -0.001787 -0.282672 -v 0.181545 0.206221 -0.289348 -v 0.181545 0.206221 -0.289348 -v 0.249317 0.243242 -0.290808 -v 0.242842 -0.001787 -0.283848 -v -0.214032 0.243242 -0.219337 -v -0.146260 0.206221 -0.220798 -v -0.146260 0.280263 -0.220798 -v -0.215315 0.243242 -0.289348 -v -0.147543 0.280263 -0.290808 -v -0.147543 0.206221 -0.290808 -v 0.250600 0.243242 -0.220798 -v 0.182828 0.280263 -0.219337 -v 0.182828 0.206221 -0.219337 -v 0.249317 0.243242 -0.290808 -v 0.181545 0.206221 -0.289348 -v 0.181545 0.280263 -0.289348 -v -0.215315 0.243242 -0.289348 -v -0.214032 0.243242 -0.219337 -v -0.214032 0.377162 -0.219337 -v -0.147543 0.280263 -0.290808 -v -0.146260 0.377162 -0.220798 -v -0.146260 0.280263 -0.220798 -v 0.181545 0.280263 -0.289348 -v 0.182828 0.280263 -0.219337 -v 0.182828 0.377162 -0.219337 -v 0.249317 0.243242 -0.290808 -v 0.250600 0.377162 -0.220798 -v 0.250600 0.243242 -0.220798 -v 0.250600 0.377162 -0.220798 -v 0.182828 0.377162 -0.219337 -v -0.146260 0.377162 -0.220798 -v -0.214032 0.377162 -0.219337 -v -0.128461 1.675364 -0.001498 -v -0.132386 1.472782 -0.179493 -v -0.146260 1.508024 -0.220649 -v -0.146260 1.508024 -0.220649 -v -0.141462 1.768750 -0.001498 -v -0.128461 1.675364 -0.001498 -v -0.132386 0.781150 -0.179493 -v -0.128461 0.781150 -0.001498 -v -0.141462 0.738577 -0.001498 -v -0.146260 0.738577 -0.220649 -v -0.132386 1.472782 -0.179493 -v -0.132386 0.781150 -0.179493 -v -0.146260 0.738577 -0.220649 -v -0.146260 1.508024 -0.220649 -v -0.160112 1.524172 -0.217918 -v -0.159884 1.785488 -0.001498 -v -0.141462 1.768750 -0.001498 -v -0.141462 1.768750 -0.001498 -v -0.146260 1.508024 -0.220649 -v -0.160112 1.524172 -0.217918 -v -0.128461 0.781150 -0.001498 -v -0.132386 0.781150 -0.179493 -v -0.128461 1.675364 -0.001498 -v -0.132386 1.472782 -0.179493 -v -0.174244 1.836233 -0.261959 -v -0.187584 1.836233 -0.261671 -v -0.187331 1.836233 -0.247891 -v -0.173991 1.836233 -0.248178 -v -0.160446 1.785009 -0.234732 -v -0.161202 1.785009 -0.275978 -v -0.174244 1.836233 -0.261959 -v -0.173991 1.836233 -0.248178 -v -0.200373 1.785009 -0.233871 -v -0.160446 1.785009 -0.234732 -v -0.173991 1.836233 -0.248178 -v -0.187331 1.836233 -0.247891 -v -0.201129 1.785009 -0.275117 -v -0.200373 1.785009 -0.233871 -v -0.187331 1.836233 -0.247891 -v -0.187584 1.836233 -0.261671 -v -0.161202 1.785009 -0.275978 -v -0.201129 1.785009 -0.275117 -v -0.187584 1.836233 -0.261671 -v -0.174244 1.836233 -0.261959 -v -0.137050 1.756645 -0.238567 -v -0.195826 1.756645 -0.209728 -v -0.224525 1.756645 -0.271282 -v -0.165749 1.756645 -0.300121 -v -0.137050 1.756645 -0.238567 -v -0.164105 1.756645 -0.210411 -v -0.137050 1.715855 -0.238567 -v -0.164105 1.715855 -0.210411 -v -0.195826 1.756645 -0.209728 -v -0.223891 1.756645 -0.236696 -v -0.195826 1.715855 -0.209728 -v -0.223891 1.715855 -0.236696 -v -0.165749 1.756645 -0.300121 -v -0.137684 1.756645 -0.273153 -v -0.165749 1.715855 -0.300121 -v -0.137684 1.715855 -0.273153 -v -0.224525 1.756645 -0.271282 -v -0.197470 1.756645 -0.299438 -v -0.224525 1.715855 -0.271282 -v -0.197470 1.715855 -0.299438 -v -0.161841 1.691613 -0.236117 -v -0.162545 1.691613 -0.274534 -v -0.137684 1.715855 -0.273153 -v -0.199030 1.691613 -0.235315 -v -0.161841 1.691613 -0.236117 -v -0.164105 1.715855 -0.210411 -v -0.199734 1.691613 -0.273733 -v -0.199030 1.691613 -0.235315 -v -0.223891 1.715855 -0.236696 -v -0.162545 1.691613 -0.274534 -v -0.199734 1.691613 -0.273733 -v -0.197470 1.715855 -0.299438 -v -0.137684 1.756645 -0.273153 -v -0.164105 1.756645 -0.210411 -v -0.223891 1.756645 -0.236696 -v -0.197470 1.756645 -0.299438 -v -0.137050 1.715855 -0.238567 -v -0.195826 1.715855 -0.209728 -v -0.224525 1.715855 -0.271282 -v -0.165749 1.715855 -0.300121 -v -0.161202 1.785009 -0.275978 -v -0.160446 1.785009 -0.234732 -v -0.201129 1.785009 -0.275117 -v -0.200373 1.785009 -0.233871 -v -0.162545 1.691613 -0.274534 -v -0.161841 1.691613 -0.236117 -v -0.199734 1.691613 -0.273733 -v -0.199030 1.691613 -0.235315 -v -0.162545 1.691613 -0.274534 -v -0.161841 1.691613 -0.236117 -v -0.161841 1.668882 -0.236117 -v -0.162545 1.668882 -0.274534 -v -0.161841 1.691613 -0.236117 -v -0.199030 1.691613 -0.235315 -v -0.199030 1.668882 -0.235315 -v -0.161841 1.668882 -0.236117 -v -0.199030 1.691613 -0.235315 -v -0.199734 1.691613 -0.273733 -v -0.199734 1.668882 -0.273733 -v -0.199030 1.668882 -0.235315 -v -0.199734 1.691613 -0.273733 -v -0.162545 1.691613 -0.274534 -v -0.162545 1.668882 -0.274534 -v -0.199734 1.668882 -0.273733 -v -0.161841 1.668882 -0.236117 -v -0.199030 1.668882 -0.235315 -v -0.214032 1.655105 -0.219189 -v -0.146260 1.655105 -0.220649 -v -0.162545 1.668882 -0.274534 -v -0.161841 1.668882 -0.236117 -v -0.146260 1.655105 -0.220649 -v -0.147543 1.655105 -0.290660 -v -0.199734 1.668882 -0.273733 -v -0.162545 1.668882 -0.274534 -v -0.147543 1.655105 -0.290660 -v -0.215315 1.655105 -0.289200 -v -0.199030 1.668882 -0.235315 -v -0.199734 1.668882 -0.273733 -v -0.215315 1.655105 -0.289200 -v -0.214032 1.655105 -0.219189 -v -0.159884 1.900273 -0.001498 -v -0.159884 1.785488 -0.001498 -v -0.160112 1.524172 -0.217918 -v -0.160112 1.638956 -0.217918 -v -0.199603 1.785488 -0.001498 -v -0.199603 1.900273 -0.001498 -v -0.199830 1.638956 -0.217063 -v -0.199830 1.524172 -0.217063 -v -0.199603 1.900273 -0.001498 -v -0.159884 1.900273 -0.001498 -v -0.160112 1.638956 -0.217918 -v -0.160112 1.638956 -0.217918 -v -0.199830 1.638956 -0.217063 -v -0.199603 1.900273 -0.001498 -v -0.160112 1.638956 -0.217918 -v -0.160112 1.524172 -0.217918 -v -0.146260 1.508024 -0.220649 -v -0.146260 1.655105 -0.220649 -v -0.199830 1.638956 -0.217063 -v -0.160112 1.638956 -0.217918 -v -0.146260 1.655105 -0.220649 -v -0.214032 1.655105 -0.219189 -v -0.199830 1.638956 -0.217063 -v -0.147543 1.655105 -0.290660 -v -0.146260 1.655105 -0.220649 -v -0.146260 1.508024 -0.220649 -v -0.141462 0.738577 -0.001498 -v -0.141462 0.682417 -0.001498 -v -0.146260 0.683386 -0.220649 -v -0.146260 0.738577 -0.220649 -v -0.209234 0.682417 -0.001498 -v -0.209234 0.738577 -0.001498 -v -0.214032 0.738577 -0.219189 -v -0.214032 0.683393 -0.219189 -v -0.141462 0.682417 -0.001498 -v -0.209234 0.682417 -0.001498 -v -0.214032 0.683393 -0.219189 -v -0.146260 0.683386 -0.220649 -v -0.146260 0.738577 -0.220649 -v -0.147543 0.738577 -0.290660 -v -0.215315 1.655105 -0.289200 -v -0.147543 1.655105 -0.290660 -v -0.147543 0.738577 -0.290660 -v -0.215315 0.710897 -0.289200 -v -0.214032 1.655105 -0.219189 -v -0.215315 1.655105 -0.289200 -v -0.215315 0.710897 -0.289200 -v -0.214032 0.738577 -0.219189 -v -0.213681 0.377162 -0.001498 -v -0.213680 0.456870 -0.001498 -v -0.214032 0.456870 -0.219337 -v -0.214032 0.377162 -0.219337 -v -0.231718 0.471319 -0.175680 -v -0.214032 0.456870 -0.219337 -v 0.261861 0.726253 -0.304144 -v -0.134999 0.726253 -0.304144 -v -0.147543 0.738577 -0.290660 -v 0.245288 0.738577 -0.290660 -v -0.133232 0.726253 -0.207717 -v 0.263628 0.726253 -0.207717 -v 0.246571 0.738577 -0.220649 -v -0.146260 0.738577 -0.220649 -v -0.133232 0.690088 -0.207717 -v -0.146260 0.683386 -0.220649 -v -0.134999 0.690088 -0.304144 -v -0.147543 0.683217 -0.290660 -v -0.147543 0.683217 -0.290660 -v -0.214032 0.683393 -0.219189 -v 0.263628 0.690088 -0.207717 -v 0.261861 0.690088 -0.304144 -v 0.261861 0.690088 -0.304144 -v 0.249317 0.683217 -0.290660 -v 0.250600 0.683217 -0.220649 -v 0.263628 0.690088 -0.207717 -v 0.249317 0.683217 -0.290660 -v 0.181545 0.609149 -0.289570 -v -0.147543 0.609149 -0.291030 -v -0.147543 0.609149 -0.291030 -v -0.147543 0.683217 -0.290660 -v 0.249317 0.683217 -0.290660 -v 0.182828 0.608985 -0.219559 -v 0.250600 0.683217 -0.220649 -v -0.146260 0.683386 -0.220649 -v -0.146260 0.683386 -0.220649 -v -0.146260 0.608985 -0.221019 -v 0.182828 0.608985 -0.219559 -v 0.181545 0.609149 -0.289570 -v 0.182828 0.608985 -0.219559 -v -0.146260 0.608985 -0.221019 -v -0.147543 0.609149 -0.291030 -v 0.261861 0.726253 -0.304144 -v -0.215315 0.710897 -0.289200 -v -0.147543 0.683217 -0.290660 -v -0.147543 0.609149 -0.291030 -v -0.214032 0.683393 -0.219189 -v -0.146260 0.608985 -0.221019 -v -0.146260 0.683386 -0.220649 -v -0.214032 0.456870 -0.219337 -v -0.146260 0.456870 -0.220798 -v -0.147543 0.609149 -0.291030 -v -0.146260 0.608985 -0.221019 -v -0.215315 0.710897 -0.289200 -v -0.147543 0.609149 -0.291030 -v -0.147543 0.280263 -0.290808 -v -0.214032 0.456870 -0.219337 -v -0.146260 0.456870 -0.220798 -v -0.146260 0.608985 -0.221019 -v -0.146260 0.608985 -0.221019 -v -0.214032 0.683393 -0.219189 -v -0.214032 0.456870 -0.219337 -v -0.152985 -0.001787 -0.227473 -v -0.207557 -0.001787 -0.226297 -v -0.208590 -0.001787 -0.282672 -v -0.154018 -0.001787 -0.283848 -v 0.250600 0.683217 -0.220649 -v 0.249317 0.683217 -0.290660 -v 0.182828 0.456870 -0.219337 -v 0.182828 0.608985 -0.219559 -v 0.181545 0.609149 -0.289570 -v 0.250600 0.456870 -0.220798 -v 0.249317 0.683217 -0.290660 -v 0.250600 0.683217 -0.220649 -v 0.181545 0.609149 -0.289570 -v 0.181545 0.609149 -0.289570 -v 0.249317 0.683217 -0.290660 -v 0.249317 0.243242 -0.290808 -v 0.182828 0.456870 -0.219337 -v 0.250600 0.456870 -0.220798 -v 0.250600 0.683217 -0.220649 -v 0.250600 0.683217 -0.220649 -v 0.182828 0.608985 -0.219559 -v 0.182828 0.456870 -0.219337 -v 0.243875 -0.001787 -0.227473 -v 0.189303 -0.001787 -0.226297 -v 0.188270 -0.001787 -0.282672 -v 0.242842 -0.001787 -0.283848 -v 0.250600 0.377162 -0.220798 -v 0.250600 0.456870 -0.220798 -v 0.247841 0.456870 -0.001498 -v 0.247847 0.377162 -0.001498 -v -0.146260 0.456870 -0.220798 -v 0.182828 0.456870 -0.219337 -v 0.182828 0.377162 -0.219337 -v -0.146260 0.377162 -0.220798 -v 0.250600 0.456870 -0.220798 -v 0.262209 0.471319 -0.175680 -v -0.231718 0.520293 -0.175680 -v -0.223747 0.491776 -0.207443 -v -0.163649 0.564918 -0.175680 -v 0.199481 0.564918 -0.175680 -v 0.262209 0.520293 -0.175680 -v -0.163649 0.522718 -0.211092 -v 0.199480 0.522718 -0.211092 -v 0.261171 0.491776 -0.211365 -v 0.261171 0.491776 -0.211365 -v 0.182828 0.377162 -0.219337 -v 0.250600 0.377162 -0.220798 -v -0.146260 0.377162 -0.220798 -v 0.182828 0.377162 -0.219337 -v -0.214032 0.377162 -0.219337 -v -0.146260 0.377162 -0.220798 -v 0.182828 0.456870 -0.219337 -v 0.250600 0.456870 -0.220798 -v -0.146260 0.456870 -0.220798 -v -0.214032 0.456870 -0.219337 -vt 0.674120 0.126945 -vt 0.132117 0.022442 -vt 0.673842 0.014528 -vt 0.132117 0.022442 -vt 0.674120 0.126945 -vt 0.269444 0.134379 -vt 0.201464 0.137566 -vt 0.269444 0.134379 -vt 0.683074 0.130257 -vt 0.674120 0.126945 -vt 0.683074 0.130257 -vt 0.269444 0.134379 -vt 0.683074 0.130257 -vt 0.674120 0.126945 -vt 0.682797 0.015131 -vt 0.673842 0.014528 -vt 0.682797 0.015131 -vt 0.674120 0.126945 -vt 0.448731 0.911043 -vt 0.647034 0.813468 -vt 0.498266 0.960933 -vt 0.597499 0.763578 -vt 0.448555 0.914611 -vt 0.640803 0.812643 -vt 0.492025 0.958847 -vt 0.597333 0.768407 -vt 0.448058 0.911847 -vt 0.647261 0.815930 -vt 0.497076 0.962245 -vt 0.598243 0.765532 -vt 0.450490 0.915256 -vt 0.641027 0.814195 -vt 0.493574 0.959098 -vt 0.597944 0.770354 -vt 0.597499 0.763578 -vt 0.747627 0.909508 -vt 0.647034 0.813468 -vt 0.747627 0.909508 -vt 0.597499 0.763578 -vt 0.509004 0.668989 -vt 0.598243 0.765532 -vt 0.740284 0.906069 -vt 0.647261 0.815930 -vt 0.740284 0.906069 -vt 0.598243 0.765532 -vt 0.503965 0.663285 -vt 0.537299 0.923005 -vt 0.592736 0.752811 -vt 0.483584 0.868868 -vt 0.654247 0.814805 -vt 0.483852 0.865836 -vt 0.647222 0.820979 -vt 0.537044 0.920488 -vt 0.586311 0.758396 -vt 0.747627 0.909508 -vt 0.558029 0.622664 -vt 0.796653 0.863183 -vt 0.509004 0.668989 -vt 0.539725 0.992216 -vt 0.648299 0.813382 -vt 0.505456 0.956870 -vt 0.682568 0.847951 -vt 0.551186 0.615030 -vt 0.740284 0.906069 -vt 0.503965 0.663285 -vt 0.787505 0.857813 -vt 0.952233 0.985260 -vt 0.851318 0.814006 -vt 0.984205 0.954259 -vt 0.811612 0.852504 -vt 0.870723 0.945112 -vt 0.646616 0.821792 -vt 0.825025 0.990459 -vt 0.646616 0.821792 -vt 0.870723 0.945112 -vt 0.672612 0.734479 -vt 0.829209 0.987755 -vt 0.705926 0.772152 -vt 0.869365 0.948108 -vt 0.655721 0.820941 -vt 0.955599 0.990783 -vt 0.853394 0.818481 -vt 0.986451 0.960183 -vt 0.853394 0.818481 -vt 0.955599 0.990783 -vt 0.835786 0.877370 -vt 0.869526 0.947996 -vt 0.655999 0.821124 -vt 0.829184 0.987657 -vt 0.706294 0.772244 -vt 0.823909 0.991444 -vt 0.674064 0.733928 -vt 0.870047 0.946545 -vt 0.674064 0.733928 -vt 0.823909 0.991444 -vt 0.647222 0.820979 -vt 0.828978 0.987744 -vt 0.701503 0.767118 -vt 0.869469 0.947964 -vt 0.651218 0.816520 -vt 0.807277 0.916486 -vt 0.682568 0.847951 -vt 0.781732 0.941795 -vt 0.682568 0.847951 -vt 0.807277 0.916486 -vt 0.697157 0.799236 -vt 0.672612 0.734479 -vt 0.585106 0.759798 -vt 0.646616 0.821792 -vt 0.853394 0.818481 -vt 0.835786 0.877370 -vt 0.794376 0.835595 -vt 0.674064 0.733928 -vt 0.647222 0.820979 -vt 0.586311 0.758396 -vt 0.697157 0.799236 -vt 0.648299 0.813382 -vt 0.682568 0.847951 -vt 0.811612 0.852504 -vt 0.776596 0.738943 -vt 0.851318 0.814006 -vt 0.647622 0.712276 -vt 0.597460 0.761549 -vt 0.521957 0.684769 -vt 0.647484 0.712183 -vt 0.521525 0.684603 -vt 0.597115 0.761577 -vt 0.701503 0.767118 -vt 0.651218 0.816520 -vt 0.556729 0.720353 -vt 0.563894 0.620733 -vt 0.506596 0.676492 -vt 0.504606 0.678666 -vt 0.561357 0.622350 -vt 0.357521 0.145897 -vt 0.464422 0.288567 -vt 0.487473 0.261159 -vt 0.464422 0.288567 -vt 0.357521 0.145897 -vt 0.296184 0.151459 -vt 0.928266 0.260636 -vt 0.952737 0.150680 -vt 0.926583 0.149422 -vt 0.954807 0.287985 -vt 0.487473 0.261159 -vt 0.954807 0.287985 -vt 0.928266 0.260636 -vt 0.464422 0.288567 -vt 0.453053 0.288049 -vt 0.296184 0.151459 -vt 0.284111 0.152277 -vt 0.296184 0.151459 -vt 0.453053 0.288049 -vt 0.464422 0.288567 -vt 0.926583 0.149422 -vt 0.357521 0.145897 -vt 0.928266 0.260636 -vt 0.487473 0.261159 -vt 0.642208 0.530008 -vt 0.598002 0.549292 -vt 0.611213 0.517318 -vt 0.628996 0.561982 -vt 0.735118 0.642581 -vt 0.645826 0.531772 -vt 0.774475 0.549811 -vt 0.632677 0.562768 -vt 0.733689 0.642190 -vt 0.641904 0.532149 -vt 0.771938 0.551867 -vt 0.629125 0.562327 -vt 0.773312 0.549431 -vt 0.631576 0.562175 -vt 0.733919 0.642186 -vt 0.644738 0.531184 -vt 0.733634 0.640719 -vt 0.641849 0.530678 -vt 0.771883 0.550396 -vt 0.629070 0.560856 -vt 0.802708 0.662256 -vt 0.804521 0.661447 -vt 0.834417 0.584385 -vt 0.804466 0.659976 -vt 0.802708 0.662256 -vt 0.894434 0.701168 -vt 0.775667 0.724124 -vt 0.867392 0.763037 -vt 0.774455 0.723697 -vt 0.866164 0.762648 -vt 0.801384 0.662163 -vt 0.893093 0.701113 -vt 0.861268 0.522348 -vt 0.952994 0.561261 -vt 0.835711 0.584464 -vt 0.927436 0.623377 -vt 0.834417 0.584385 -vt 0.926126 0.623335 -vt 0.860137 0.521956 -vt 0.951846 0.560906 -vt 0.946451 0.728491 -vt 0.927436 0.623377 -vt 0.983109 0.642083 -vt 0.945771 0.728335 -vt 0.927034 0.628700 -vt 0.981397 0.644206 -vt 0.981915 0.641773 -vt 0.893093 0.701113 -vt 0.945223 0.728167 -vt 0.945715 0.726865 -vt 0.926978 0.627229 -vt 0.981341 0.642736 -vt 0.835711 0.584464 -vt 0.834909 0.589688 -vt 0.801384 0.662163 -vt 0.834854 0.588217 -vt 0.894434 0.701168 -vt 0.896646 0.700459 -vt 0.926126 0.623335 -vt 0.896591 0.698988 -vt 0.774475 0.549811 -vt 0.735118 0.642581 -vt 0.773312 0.549431 -vt 0.733919 0.642186 -vt 0.983109 0.642083 -vt 0.946451 0.728491 -vt 0.981915 0.641773 -vt 0.945223 0.728167 -vt 0.035491 0.007166 -vt 0.025120 0.042034 -vt 0.012310 0.028503 -vt 0.048302 0.020698 -vt 0.011935 0.028441 -vt 0.048410 0.020382 -vt 0.035503 0.007264 -vt 0.025158 0.042143 -vt 0.034402 0.008856 -vt 0.025297 0.042722 -vt 0.012614 0.029981 -vt 0.047085 0.021597 -vt 0.034122 0.009316 -vt 0.025811 0.042994 -vt 0.013098 0.030169 -vt 0.046835 0.022141 -vt 0.025158 0.042143 -vt 0.065625 0.022318 -vt 0.048410 0.020382 -vt 0.023979 0.061449 -vt 0.048302 0.020698 -vt 0.023332 0.061083 -vt 0.025120 0.042034 -vt 0.065577 0.022200 -vt 0.046835 0.022141 -vt 0.025455 0.059905 -vt 0.025811 0.042994 -vt 0.063768 0.021904 -vt 0.047085 0.021597 -vt 0.023936 0.061066 -vt 0.025297 0.042722 -vt 0.063642 0.022568 -vt 0.210956 0.152364 -vt 0.453053 0.288049 -vt 0.284111 0.152277 -vt 0.379898 0.288135 -vt 0.132117 0.022442 -vt 0.209128 0.135294 -vt 0.071801 0.023357 -vt 0.269444 0.134379 -vt 0.745407 0.896583 -vt 0.549748 0.641825 -vt 0.771751 0.870306 -vt 0.549748 0.641825 -vt 0.745407 0.896583 -vt 0.523404 0.668103 -vt 0.041541 0.064563 -vt 0.110865 0.151096 -vt 0.110099 0.133097 -vt 0.023016 0.063279 -vt 0.065675 0.039862 -vt 0.023016 0.063279 -vt 0.041541 0.064563 -vt 0.063272 0.022717 -vt 0.209128 0.135294 -vt 0.063220 0.022601 -vt 0.108250 0.147543 -vt 0.022357 0.062935 -vt 0.952737 0.150680 -vt 0.989982 0.287944 -vt 0.988528 0.150637 -vt 0.954807 0.287985 -vt 0.712307 0.014683 -vt 0.683074 0.130257 -vt 0.682797 0.015131 -vt 0.712072 0.129816 -vt 0.447563 0.912220 -vt 0.646190 0.810714 -vt 0.493544 0.959395 -vt 0.600209 0.763539 -vt 0.553707 0.594408 -vt 0.594216 0.555842 -vt 0.063768 0.021904 -vt 0.538047 0.577009 -vt 0.025455 0.059905 -vt 0.591842 0.554624 -vt 0.063642 0.022568 -vt 0.550764 0.590300 -vt 0.023936 0.061066 -vt 0.575025 0.536287 -vt 0.540759 0.506256 -vt 0.605865 0.643604 -vt 0.504416 0.543946 -vt 0.641994 0.605704 -vt 0.028768 0.315878 -vt 0.202071 0.336757 -vt 0.027449 0.336516 -vt 0.249474 0.315834 -vt 0.553561 0.459581 -vt 0.987980 0.445430 -vt 0.972465 0.459546 -vt 0.573256 0.445350 -vt 0.970799 0.356369 -vt 0.573258 0.370185 -vt 0.553497 0.356383 -vt 0.986636 0.370386 -vt 0.970984 0.316621 -vt 0.986932 0.304422 -vt 0.987672 0.509975 -vt 0.972581 0.497394 -vt 0.569009 0.608243 -vt 0.605815 0.567217 -vt 0.519492 0.356419 -vt 0.518952 0.460602 -vt 0.553930 0.496673 -vt 0.566306 0.510951 -vt 0.570654 0.299299 -vt 0.553420 0.311936 -vt 0.493513 0.593817 -vt 0.359458 0.797109 -vt 0.496085 0.659837 -vt 0.359458 0.797109 -vt 0.493513 0.593817 -vt 0.322055 0.760188 -vt 0.663829 0.821617 -vt 0.504844 0.568774 -vt 0.752741 0.817728 -vt 0.504844 0.568774 -vt 0.663829 0.821617 -vt 0.458191 0.615277 -vt 0.566935 0.630141 -vt 0.741992 0.902941 -vt 0.517733 0.676750 -vt 0.791194 0.856332 -vt 0.554153 0.460522 -vt 0.591842 0.554624 -vt 0.610443 0.650049 -vt 0.569009 0.608243 -vt 0.462484 0.526262 -vt 0.504844 0.568774 -vt 0.458191 0.615277 -vt 0.732122 0.694266 -vt 0.457561 0.619544 -vt 0.390949 0.451227 -vt 0.340691 0.500669 -vt 0.591842 0.554624 -vt 0.794376 0.835595 -vt 0.610443 0.650049 -vt 0.320432 0.667837 -vt 0.458191 0.615277 -vt 0.362798 0.710345 -vt 0.458191 0.615277 -vt 0.320432 0.667837 -vt 0.462484 0.526262 -vt 0.497830 0.296368 -vt 0.427675 0.367237 -vt 0.428364 0.295478 -vt 0.497141 0.368128 -vt 0.505434 0.370200 -vt 0.505331 0.448202 -vt 0.340703 0.500655 -vt 0.457472 0.619530 -vt 0.390797 0.451331 -vt 0.500490 0.663115 -vt 0.390966 0.451281 -vt 0.340681 0.500683 -vt 0.496085 0.659837 -vt 0.496085 0.659837 -vt 0.697157 0.799236 -vt 0.493513 0.593817 -vt 0.568435 0.916685 -vt 0.752741 0.817728 -vt 0.610801 0.959193 -vt 0.752741 0.817728 -vt 0.568435 0.916685 -vt 0.663829 0.821617 -vt 0.497249 0.296187 -vt 0.427093 0.367056 -vt 0.427782 0.295297 -vt 0.496560 0.367946 -vt 0.556729 0.720353 -vt 0.343496 0.817418 -vt 0.500490 0.663115 -vt 0.400064 0.874333 -vt 0.522617 0.686211 -vt 0.772105 0.841392 -vt 0.722776 0.889872 -vt 0.571945 0.637731 -vt 0.029620 0.984657 -vt 0.208507 0.969157 -vt 0.252569 0.985593 -vt 0.029389 0.967030 -vt 0.028206 0.385955 -vt 0.204105 0.386185 -vt 0.253155 0.395067 -vt 0.025887 0.459502 -vt 0.188981 0.459844 -vt 0.027722 0.854258 -vt 0.190816 0.854600 -vt 0.029328 0.920986 -vt 0.210660 0.923674 -vt 0.242699 0.460218 -vt 0.245338 0.854227 -vt 0.252309 0.930891 -vt 0.028451 0.921573 -vt 0.252391 0.932079 -vt 0.598787 0.669597 -vt 0.703379 0.867938 -vt 0.552840 0.714749 -vt 0.752285 0.821907 -vt 0.736422 0.012871 -vt 0.916139 0.130638 -vt 0.737358 0.131432 -vt 0.916139 0.012871 -vt 0.598503 0.669876 -vt 0.702368 0.868932 -vt 0.552077 0.715498 -vt 0.751274 0.822901 -vt 0.319760 0.835283 -vt 0.300147 0.911197 -vt 0.317475 0.479551 -vt 0.294135 0.406099 -vt 0.674120 0.126945 -vt 0.673842 0.014528 -vt 0.132117 0.022442 -vt 0.132117 0.022442 -vt 0.269444 0.134379 -vt 0.674120 0.126945 -vt 0.201464 0.137566 -vt 0.683074 0.130257 -vt 0.269444 0.134379 -vt 0.674120 0.126945 -vt 0.269444 0.134379 -vt 0.683074 0.130257 -vt 0.683074 0.130257 -vt 0.682797 0.015131 -vt 0.674120 0.126945 -vt 0.673842 0.014528 -vt 0.674120 0.126945 -vt 0.682797 0.015131 -vt 0.647034 0.813468 -vt 0.597499 0.763578 -vt 0.448555 0.914611 -vt 0.492025 0.958847 -vt 0.640803 0.812643 -vt 0.597333 0.768407 -vt 0.647261 0.815930 -vt 0.598243 0.765532 -vt 0.450490 0.915256 -vt 0.493574 0.959098 -vt 0.641027 0.814195 -vt 0.597944 0.770354 -vt 0.597499 0.763578 -vt 0.647034 0.813468 -vt 0.747627 0.909508 -vt 0.747627 0.909508 -vt 0.509004 0.668989 -vt 0.597499 0.763578 -vt 0.598243 0.765532 -vt 0.647261 0.815930 -vt 0.740284 0.906069 -vt 0.740284 0.906069 -vt 0.503965 0.663285 -vt 0.598243 0.765532 -vt 0.537299 0.923005 -vt 0.483584 0.868868 -vt 0.592736 0.752811 -vt 0.654247 0.814805 -vt 0.483852 0.865836 -vt 0.537044 0.920488 -vt 0.647222 0.820979 -vt 0.586311 0.758396 -vt 0.747627 0.909508 -vt 0.796653 0.863183 -vt 0.558029 0.622664 -vt 0.509004 0.668989 -vt 0.539725 0.992216 -vt 0.505456 0.956870 -vt 0.648299 0.813382 -vt 0.682568 0.847951 -vt 0.551186 0.615030 -vt 0.503965 0.663285 -vt 0.740284 0.906069 -vt 0.787505 0.857813 -vt 0.952233 0.985260 -vt 0.984205 0.954259 -vt 0.851318 0.814006 -vt 0.811612 0.852504 -vt 0.870723 0.945112 -vt 0.825025 0.990459 -vt 0.646616 0.821792 -vt 0.646616 0.821792 -vt 0.672612 0.734479 -vt 0.870723 0.945112 -vt 0.829209 0.987755 -vt 0.869365 0.948108 -vt 0.705926 0.772152 -vt 0.655721 0.820941 -vt 0.955599 0.990783 -vt 0.986451 0.960183 -vt 0.853394 0.818481 -vt 0.853394 0.818481 -vt 0.835786 0.877370 -vt 0.955599 0.990783 -vt 0.869526 0.947996 -vt 0.829184 0.987657 -vt 0.655999 0.821124 -vt 0.706294 0.772244 -vt 0.823909 0.991444 -vt 0.870047 0.946545 -vt 0.674064 0.733928 -vt 0.674064 0.733928 -vt 0.647222 0.820979 -vt 0.823909 0.991444 -vt 0.828978 0.987744 -vt 0.869469 0.947964 -vt 0.701503 0.767118 -vt 0.651218 0.816520 -vt 0.807277 0.916486 -vt 0.781732 0.941795 -vt 0.682568 0.847951 -vt 0.682568 0.847951 -vt 0.697157 0.799236 -vt 0.807277 0.916486 -vt 0.672612 0.734479 -vt 0.646616 0.821792 -vt 0.585106 0.759798 -vt 0.853394 0.818481 -vt 0.794376 0.835595 -vt 0.835786 0.877370 -vt 0.674064 0.733928 -vt 0.586311 0.758396 -vt 0.647222 0.820979 -vt 0.697157 0.799236 -vt 0.682568 0.847951 -vt 0.648299 0.813382 -vt 0.811612 0.852504 -vt 0.851318 0.814006 -vt 0.776596 0.738943 -vt 0.647622 0.712276 -vt 0.521957 0.684769 -vt 0.597460 0.761549 -vt 0.647484 0.712183 -vt 0.597115 0.761577 -vt 0.521525 0.684603 -vt 0.701503 0.767118 -vt 0.556729 0.720353 -vt 0.651218 0.816520 -vt 0.563894 0.620733 -vt 0.506596 0.676492 -vt 0.504606 0.678666 -vt 0.561357 0.622350 -vt 0.357521 0.145897 -vt 0.487473 0.261159 -vt 0.464422 0.288567 -vt 0.464422 0.288567 -vt 0.296184 0.151459 -vt 0.357521 0.145897 -vt 0.928266 0.260636 -vt 0.926583 0.149422 -vt 0.952737 0.150680 -vt 0.954807 0.287985 -vt 0.487473 0.261159 -vt 0.928266 0.260636 -vt 0.954807 0.287985 -vt 0.464422 0.288567 -vt 0.453053 0.288049 -vt 0.284111 0.152277 -vt 0.296184 0.151459 -vt 0.296184 0.151459 -vt 0.464422 0.288567 -vt 0.453053 0.288049 -vt 0.926583 0.149422 -vt 0.928266 0.260636 -vt 0.357521 0.145897 -vt 0.487473 0.261159 -vt 0.642208 0.530008 -vt 0.611213 0.517318 -vt 0.598002 0.549292 -vt 0.628996 0.561982 -vt 0.735118 0.642581 -vt 0.774475 0.549811 -vt 0.645826 0.531772 -vt 0.632677 0.562768 -vt 0.733689 0.642190 -vt 0.771938 0.551867 -vt 0.641904 0.532149 -vt 0.629125 0.562327 -vt 0.773312 0.549431 -vt 0.733919 0.642186 -vt 0.631576 0.562175 -vt 0.644738 0.531184 -vt 0.733634 0.640719 -vt 0.771883 0.550396 -vt 0.641849 0.530678 -vt 0.629070 0.560856 -vt 0.802708 0.662256 -vt 0.804521 0.661447 -vt 0.834417 0.584385 -vt 0.804466 0.659976 -vt 0.802708 0.662256 -vt 0.775667 0.724124 -vt 0.894434 0.701168 -vt 0.867392 0.763037 -vt 0.774455 0.723697 -vt 0.801384 0.662163 -vt 0.866164 0.762648 -vt 0.893093 0.701113 -vt 0.861268 0.522348 -vt 0.835711 0.584464 -vt 0.952994 0.561261 -vt 0.927436 0.623377 -vt 0.834417 0.584385 -vt 0.860137 0.521956 -vt 0.926126 0.623335 -vt 0.951846 0.560906 -vt 0.946451 0.728491 -vt 0.983109 0.642083 -vt 0.927436 0.623377 -vt 0.945771 0.728335 -vt 0.981397 0.644206 -vt 0.927034 0.628700 -vt 0.981915 0.641773 -vt 0.945223 0.728167 -vt 0.893093 0.701113 -vt 0.945715 0.726865 -vt 0.981341 0.642736 -vt 0.926978 0.627229 -vt 0.835711 0.584464 -vt 0.834909 0.589688 -vt 0.801384 0.662163 -vt 0.834854 0.588217 -vt 0.894434 0.701168 -vt 0.896646 0.700459 -vt 0.926126 0.623335 -vt 0.896591 0.698988 -vt 0.774475 0.549811 -vt 0.735118 0.642581 -vt 0.773312 0.549431 -vt 0.733919 0.642186 -vt 0.983109 0.642083 -vt 0.946451 0.728491 -vt 0.981915 0.641773 -vt 0.945223 0.728167 -vt 0.035491 0.007166 -vt 0.012310 0.028503 -vt 0.025120 0.042034 -vt 0.048302 0.020698 -vt 0.011935 0.028441 -vt 0.035503 0.007264 -vt 0.048410 0.020382 -vt 0.025158 0.042143 -vt 0.034402 0.008856 -vt 0.012614 0.029981 -vt 0.025297 0.042722 -vt 0.047085 0.021597 -vt 0.034122 0.009316 -vt 0.013098 0.030169 -vt 0.025811 0.042994 -vt 0.046835 0.022141 -vt 0.025158 0.042143 -vt 0.048410 0.020382 -vt 0.065625 0.022318 -vt 0.023979 0.061449 -vt 0.048302 0.020698 -vt 0.025120 0.042034 -vt 0.023332 0.061083 -vt 0.065577 0.022200 -vt 0.046835 0.022141 -vt 0.025811 0.042994 -vt 0.025455 0.059905 -vt 0.063768 0.021904 -vt 0.047085 0.021597 -vt 0.025297 0.042722 -vt 0.023936 0.061066 -vt 0.063642 0.022568 -vt 0.210956 0.152364 -vt 0.284111 0.152277 -vt 0.453053 0.288049 -vt 0.379898 0.288135 -vt 0.132117 0.022442 -vt 0.071801 0.023357 -vt 0.209128 0.135294 -vt 0.269444 0.134379 -vt 0.745407 0.896583 -vt 0.771751 0.870306 -vt 0.549748 0.641825 -vt 0.549748 0.641825 -vt 0.523404 0.668103 -vt 0.745407 0.896583 -vt 0.041541 0.064563 -vt 0.110099 0.133097 -vt 0.110865 0.151096 -vt 0.023016 0.063279 -vt 0.065675 0.039862 -vt 0.041541 0.064563 -vt 0.023016 0.063279 -vt 0.063272 0.022717 -vt 0.209128 0.135294 -vt 0.063220 0.022601 -vt 0.022357 0.062935 -vt 0.108250 0.147543 -vt 0.952737 0.150680 -vt 0.988528 0.150637 -vt 0.989982 0.287944 -vt 0.954807 0.287985 -vt 0.712307 0.014683 -vt 0.682797 0.015131 -vt 0.683074 0.130257 -vt 0.712072 0.129816 -vt 0.447563 0.912220 -vt 0.493544 0.959395 -vt 0.646190 0.810714 -vt 0.600209 0.763539 -vt 0.553707 0.594408 -vt 0.594216 0.555842 -vt 0.063768 0.021904 -vt 0.025455 0.059905 -vt 0.538047 0.577009 -vt 0.591842 0.554624 -vt 0.063642 0.022568 -vt 0.023936 0.061066 -vt 0.550764 0.590300 -vt 0.575025 0.536287 -vt 0.540759 0.506256 -vt 0.504416 0.543946 -vt 0.605865 0.643604 -vt 0.641994 0.605704 -vt 0.202071 0.336757 -vt 0.249474 0.315834 -vt 0.553561 0.459581 -vt 0.972465 0.459546 -vt 0.987980 0.445430 -vt 0.573256 0.445350 -vt 0.970799 0.356369 -vt 0.553497 0.356383 -vt 0.573258 0.370185 -vt 0.986636 0.370386 -vt 0.970984 0.316621 -vt 0.986932 0.304422 -vt 0.972581 0.497394 -vt 0.987672 0.509975 -vt 0.569009 0.608243 -vt 0.605815 0.567217 -vt 0.519492 0.356419 -vt 0.518952 0.460602 -vt 0.553930 0.496673 -vt 0.566306 0.510951 -vt 0.570654 0.299299 -vt 0.553420 0.311936 -vt 0.493513 0.593817 -vt 0.496085 0.659837 -vt 0.359458 0.797109 -vt 0.359458 0.797109 -vt 0.322055 0.760188 -vt 0.493513 0.593817 -vt 0.663829 0.821617 -vt 0.752741 0.817728 -vt 0.504844 0.568774 -vt 0.504844 0.568774 -vt 0.458191 0.615277 -vt 0.663829 0.821617 -vt 0.566935 0.630141 -vt 0.517733 0.676750 -vt 0.741992 0.902941 -vt 0.791194 0.856332 -vt 0.554153 0.460522 -vt 0.591842 0.554624 -vt 0.569009 0.608243 -vt 0.610443 0.650049 -vt 0.462484 0.526262 -vt 0.458191 0.615277 -vt 0.504844 0.568774 -vt 0.732122 0.694266 -vt 0.457561 0.619544 -vt 0.390949 0.451227 -vt 0.340691 0.500669 -vt 0.591842 0.554624 -vt 0.610443 0.650049 -vt 0.794376 0.835595 -vt 0.320432 0.667837 -vt 0.362798 0.710345 -vt 0.458191 0.615277 -vt 0.458191 0.615277 -vt 0.462484 0.526262 -vt 0.320432 0.667837 -vt 0.497830 0.296368 -vt 0.428364 0.295478 -vt 0.427675 0.367237 -vt 0.497141 0.368128 -vt 0.505434 0.370200 -vt 0.505331 0.448202 -vt 0.457472 0.619530 -vt 0.340703 0.500655 -vt 0.390797 0.451331 -vt 0.500490 0.663115 -vt 0.390966 0.451281 -vt 0.340681 0.500683 -vt 0.496085 0.659837 -vt 0.496085 0.659837 -vt 0.493513 0.593817 -vt 0.697157 0.799236 -vt 0.568435 0.916685 -vt 0.610801 0.959193 -vt 0.752741 0.817728 -vt 0.752741 0.817728 -vt 0.663829 0.821617 -vt 0.568435 0.916685 -vt 0.497249 0.296187 -vt 0.427782 0.295297 -vt 0.427093 0.367056 -vt 0.496560 0.367946 -vt 0.556729 0.720353 -vt 0.500490 0.663115 -vt 0.343496 0.817418 -vt 0.400064 0.874333 -vt 0.522617 0.686211 -vt 0.722776 0.889872 -vt 0.772105 0.841392 -vt 0.571945 0.637731 -vt 0.252569 0.985593 -vt 0.208507 0.969157 -vt 0.204105 0.386185 -vt 0.253155 0.395067 -vt 0.188981 0.459844 -vt 0.190816 0.854600 -vt 0.210660 0.923674 -vt 0.242699 0.460218 -vt 0.245338 0.854227 -vt 0.252309 0.930891 -vt 0.252391 0.932079 -vt 0.703379 0.867938 -vt 0.752285 0.821907 -vt 0.737358 0.131432 -vt 0.916139 0.130638 -vt 0.702368 0.868932 -vt 0.751274 0.822901 -vt 0.319760 0.835283 -vt 0.300147 0.911197 -vt 0.317475 0.479551 -vt 0.294135 0.406099 -vn -0.999745 -0.022571 -0.000427 -vn -0.999745 -0.022571 -0.000427 -vn -0.999745 -0.022571 -0.000427 -vn -0.999971 0.005425 0.005345 -vn -0.999971 0.005425 0.005345 -vn -0.999971 0.005425 0.005345 -vn -0.148086 -0.988975 0.000000 -vn -0.148086 -0.988975 0.000000 -vn -0.148086 -0.988975 0.000000 -vn -0.464450 -0.885579 0.005999 -vn -0.464450 -0.885579 0.005999 -vn -0.464450 -0.885579 0.005999 -vn -0.847890 -0.018688 0.529842 -vn -0.847890 -0.018688 0.529842 -vn -0.847890 -0.018688 0.529842 -vn -0.845153 -0.019081 0.534183 -vn -0.845153 -0.019081 0.534183 -vn -0.845153 -0.019081 0.534183 -vn 0.000000 -0.000001 -1.000000 -vn 0.000000 0.000001 -1.000000 -vn 0.000000 -0.000001 -1.000000 -vn 0.000000 0.000001 -1.000000 -vn -0.999992 0.004070 0.000000 -vn -0.999992 0.004070 0.000000 -vn -0.999992 0.004070 0.000000 -vn -0.999992 0.004070 0.000000 -vn -0.000000 0.000000 1.000000 -vn -0.000000 -0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn -0.000000 -0.000000 1.000000 -vn 0.999992 -0.004076 -0.000000 -vn 0.999992 -0.004076 -0.000000 -vn 0.999992 -0.004076 0.000000 -vn 0.999992 -0.004076 -0.000000 -vn -0.004429 -0.913622 -0.406539 -vn -0.004429 -0.913622 -0.406539 -vn -0.004429 -0.913622 -0.406539 -vn -0.004027 -0.907532 -0.419964 -vn -0.004027 -0.907532 -0.419964 -vn -0.004027 -0.907532 -0.419964 -vn -0.004381 -0.903704 0.428136 -vn -0.004381 -0.903704 0.428136 -vn -0.004381 -0.903704 0.428136 -vn -0.004036 -0.909589 0.415489 -vn -0.004036 -0.909589 0.415489 -vn -0.004036 -0.909589 0.415489 -vn -0.020304 -0.999794 -0.000000 -vn -0.020304 -0.999794 -0.000000 -vn -0.020305 -0.999794 -0.000000 -vn -0.020304 -0.999794 -0.000000 -vn 0.012824 -0.999918 -0.000000 -vn 0.012824 -0.999918 -0.000000 -vn 0.012824 -0.999918 -0.000000 -vn 0.012824 -0.999918 -0.000000 -vn -0.000000 -0.000001 -1.000000 -vn -0.000000 -0.000001 -1.000000 -vn -0.000000 -0.000001 -1.000000 -vn -0.000000 -0.000001 -1.000000 -vn 0.004437 0.999990 -0.000000 -vn 0.004437 0.999990 -0.000000 -vn 0.004437 0.999990 0.000000 -vn 0.004437 0.999990 -0.000000 -vn -0.000000 -0.000001 1.000000 -vn -0.000000 -0.000001 1.000000 -vn -0.000000 -0.000001 1.000000 -vn -0.000000 -0.000001 1.000000 -vn -0.999469 -0.018316 -0.026931 -vn -0.999469 -0.018316 -0.026931 -vn -0.999469 -0.018316 -0.026931 -vn -0.999469 -0.018316 -0.026931 -vn 0.021530 -0.999231 -0.032765 -vn 0.021530 -0.999231 -0.032765 -vn 0.021530 -0.999231 -0.032765 -vn 0.006116 -0.999583 -0.028232 -vn 0.006116 -0.999583 -0.028232 -vn 0.006116 -0.999583 -0.028232 -vn 0.999329 0.018313 -0.031720 -vn 0.999329 0.018313 -0.031720 -vn 0.999329 0.018313 -0.031720 -vn 0.999329 0.018313 -0.031720 -vn -0.021533 0.999381 -0.027818 -vn -0.021533 0.999381 -0.027818 -vn -0.021533 0.999381 -0.027818 -vn -0.039109 0.998716 -0.032200 -vn -0.039109 0.998716 -0.032200 -vn -0.039109 0.998716 -0.032200 -vn -0.999329 -0.018313 -0.031720 -vn -0.999329 -0.018313 -0.031720 -vn -0.999329 -0.018313 -0.031720 -vn -0.999329 -0.018313 -0.031720 -vn 0.021533 -0.999381 -0.027818 -vn 0.021533 -0.999381 -0.027818 -vn 0.021533 -0.999381 -0.027818 -vn 0.039108 -0.998716 -0.032200 -vn 0.039108 -0.998716 -0.032200 -vn 0.039108 -0.998716 -0.032200 -vn 0.999469 0.018316 -0.026931 -vn 0.999469 0.018316 -0.026931 -vn 0.999469 0.018316 -0.026931 -vn 0.999469 0.018316 -0.026931 -vn -0.021530 0.999231 -0.032765 -vn -0.021530 0.999231 -0.032765 -vn -0.021530 0.999231 -0.032765 -vn -0.006116 0.999583 -0.028232 -vn -0.006116 0.999583 -0.028232 -vn -0.006116 0.999583 -0.028232 -vn 0.021541 -0.999768 -0.000000 -vn 0.021541 -0.999768 0.000000 -vn 0.021541 -0.999768 -0.000000 -vn -0.021714 0.999764 0.000317 -vn -0.021541 0.999768 0.000000 -vn -0.021714 0.999764 0.000317 -vn 0.021542 -0.999768 -0.000000 -vn 0.021542 -0.999768 -0.000000 -vn 0.021541 -0.999768 0.000000 -vn -0.021910 0.999760 -0.000674 -vn -0.021910 0.999760 -0.000674 -vn -0.021542 0.999768 -0.000000 -vn -0.999832 -0.018323 -0.000000 -vn -0.999832 -0.018323 -0.000000 -vn -0.999832 -0.018323 -0.000000 -vn 0.999832 0.018322 0.000000 -vn 0.999832 0.018322 -0.000000 -vn 0.999832 0.018322 0.000000 -vn -0.999832 -0.018322 -0.000000 -vn -0.999832 -0.018322 -0.000000 -vn -0.999832 -0.018322 0.000000 -vn 0.999832 0.018322 0.000000 -vn 0.999832 0.018322 0.000000 -vn 0.999832 0.018322 0.000000 -vn 0.021541 -0.999768 0.000000 -vn 0.021541 -0.999768 0.000000 -vn 0.021541 -0.999768 -0.000000 -vn 0.021541 -0.999768 -0.000000 -vn 0.968686 0.195526 0.153029 -vn 0.968686 0.195526 0.153029 -vn 0.968686 0.195526 0.153029 -vn 0.973794 0.182611 0.135571 -vn 0.973794 0.182611 0.135571 -vn 0.973794 0.182611 0.135571 -vn 0.956360 0.020938 -0.291439 -vn 0.956360 0.020938 -0.291439 -vn 0.956184 0.021083 -0.292008 -vn 0.956360 0.020938 -0.291439 -vn 0.947601 0.319455 -0.000000 -vn 0.947601 0.319455 -0.000000 -vn 0.947601 0.319455 -0.000000 -vn 0.947601 0.319455 -0.000000 -vn 0.501241 0.666644 0.551674 -vn 0.501241 0.666644 0.551674 -vn 0.501241 0.666644 0.551674 -vn 0.508597 0.663687 0.548496 -vn 0.508597 0.663687 0.548496 -vn 0.508597 0.663687 0.548496 -vn 0.999757 0.022044 0.000000 -vn 0.999757 0.022044 0.000000 -vn 0.999757 0.022044 0.000000 -vn 0.999757 0.022044 0.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.921437 0.016886 0.388160 -vn 0.967760 0.017734 0.251249 -vn 0.854236 0.015654 0.519649 -vn 0.967760 0.017734 0.251250 -vn 0.019763 -0.917212 0.397908 -vn 0.020806 -0.965657 0.258986 -vn 0.018253 -0.847154 0.531034 -vn 0.020806 -0.965657 0.258986 -vn -0.921438 -0.016886 0.388159 -vn -0.967760 -0.017734 0.251249 -vn -0.854236 -0.015654 0.519649 -vn -0.967760 -0.017734 0.251249 -vn -0.019762 0.917212 0.397908 -vn -0.020806 0.965657 0.258986 -vn -0.018253 0.847154 0.531034 -vn -0.020806 0.965657 0.258986 -vn 0.893681 0.016377 0.448404 -vn 0.019147 -0.888655 0.458176 -vn -0.893681 -0.016377 0.448404 -vn -0.019147 0.888655 0.458176 -vn 0.701700 -0.674268 0.230173 -vn 0.707594 -0.679932 -0.192362 -vn 0.712574 -0.684717 0.152974 -vn 0.690072 -0.663095 -0.290011 -vn -0.674165 -0.701592 0.230802 -vn -0.679869 -0.707528 -0.192829 -vn -0.684673 -0.712527 0.153389 -vn -0.662945 -0.689916 -0.290723 -vn 0.674165 0.701592 0.230802 -vn 0.679869 0.707528 -0.192829 -vn 0.684673 0.712527 0.153389 -vn 0.662945 0.689916 -0.290723 -vn -0.701700 0.674268 0.230174 -vn -0.707594 0.679932 -0.192362 -vn -0.712573 0.684717 0.152974 -vn -0.690071 0.663095 -0.290012 -vn 0.698442 0.012799 -0.715552 -vn 0.858479 0.015732 -0.512607 -vn 0.698442 0.012799 -0.715552 -vn 0.014796 -0.686712 -0.726779 -vn 0.018371 -0.852614 -0.522218 -vn 0.014796 -0.686712 -0.726779 -vn -0.698441 -0.012799 -0.715553 -vn -0.858479 -0.015732 -0.512607 -vn -0.698441 -0.012799 -0.715553 -vn -0.014796 0.686711 -0.726780 -vn -0.018371 0.852614 -0.522219 -vn -0.014796 0.686711 -0.726780 -vn 0.974379 0.017856 0.224202 -vn 0.020969 -0.973180 0.229088 -vn -0.974379 -0.017856 0.224202 -vn -0.020969 0.973180 0.229088 -vn 0.966434 0.017710 -0.256303 -vn 0.020794 -0.965085 -0.261109 -vn -0.966434 -0.017711 -0.256304 -vn -0.020794 0.965085 -0.261110 -vn 0.619054 0.644239 0.449141 -vn 0.644657 -0.619456 0.447987 -vn -0.644657 0.619456 0.447987 -vn -0.619055 -0.644239 0.449140 -vn 0.575750 0.599173 -0.556331 -vn 0.599769 -0.576323 -0.555094 -vn -0.599768 0.576322 -0.555095 -vn -0.575749 -0.599172 -0.556332 -vn 0.999832 0.018322 -0.000000 -vn 0.999832 0.018322 -0.000000 -vn 0.999832 0.018322 -0.000000 -vn 0.999832 0.018322 -0.000000 -vn 0.021541 -0.999768 0.000000 -vn 0.021541 -0.999768 0.000000 -vn 0.021541 -0.999768 0.000000 -vn 0.021541 -0.999768 0.000000 -vn -0.999832 -0.018322 0.000000 -vn -0.999832 -0.018322 0.000000 -vn -0.999832 -0.018322 0.000000 -vn -0.999832 -0.018322 0.000000 -vn -0.021541 0.999768 -0.000000 -vn -0.021541 0.999768 -0.000000 -vn -0.021541 0.999768 -0.000000 -vn -0.021541 0.999768 -0.000000 -vn 0.014158 -0.657083 0.753685 -vn 0.014158 -0.657083 0.753685 -vn 0.014158 -0.657083 0.753685 -vn 0.014158 -0.657083 0.753685 -vn 0.669174 0.012263 0.743005 -vn 0.669174 0.012263 0.743005 -vn 0.669174 0.012263 0.743005 -vn 0.669174 0.012263 0.743005 -vn -0.014158 0.657082 0.753686 -vn -0.014158 0.657082 0.753686 -vn -0.014158 0.657082 0.753686 -vn -0.014158 0.657082 0.753686 -vn -0.669173 -0.012263 0.743005 -vn -0.669173 -0.012263 0.743005 -vn -0.669173 -0.012263 0.743005 -vn -0.669173 -0.012263 0.743005 -vn 0.999999 0.001050 0.000000 -vn 0.999999 0.001050 0.000000 -vn 0.999999 0.001050 0.000000 -vn 0.999999 0.001050 0.000000 -vn -0.999999 -0.001055 0.000000 -vn -0.999999 -0.001055 0.000000 -vn -0.999999 -0.001055 0.000000 -vn -0.999999 -0.001055 0.000000 -vn 0.000000 0.770164 0.637845 -vn 0.000000 0.770164 0.637845 -vn 0.000000 0.770164 0.637845 -vn -0.016618 0.771290 0.636266 -vn -0.016618 0.771290 0.636266 -vn -0.016618 0.771290 0.636266 -vn 0.193431 -0.981114 0.000000 -vn 0.193431 -0.981114 0.000000 -vn 0.193431 -0.981114 0.000000 -vn 0.193431 -0.981114 0.000000 -vn 0.021301 -0.988620 0.148918 -vn 0.021301 -0.988620 0.148918 -vn 0.021301 -0.988620 0.148919 -vn 0.021301 -0.988620 0.148918 -vn -0.148086 -0.988975 0.000000 -vn 0.999832 0.018322 0.000000 -vn 0.999832 0.018322 0.000000 -vn 0.999832 0.018322 -0.000000 -vn 0.999760 0.021888 -0.000000 -vn 0.999760 0.021888 -0.000000 -vn 0.999760 0.021888 -0.000000 -vn 0.999760 0.021888 -0.000000 -vn -0.999757 -0.022035 0.000000 -vn -0.999757 -0.022035 0.000000 -vn -0.999757 -0.022035 0.000000 -vn -0.999757 -0.022035 0.000000 -vn -0.000211 0.004415 -0.999990 -vn -0.000211 0.004415 -0.999990 -vn 0.000000 0.004485 -0.999990 -vn -0.000211 0.004415 -0.999990 -vn 0.999832 0.018322 0.000000 -vn 0.999832 0.018322 0.000000 -vn -0.021542 0.999768 -0.000000 -vn -0.021542 0.999768 -0.000000 -vn -0.021542 0.999768 -0.000000 -vn -0.021714 0.999764 0.000317 -vn -0.999832 -0.018323 -0.000000 -vn -0.999832 -0.018320 -0.000006 -vn -0.999832 -0.018323 -0.000000 -vn -0.999832 -0.018322 0.000000 -vn -0.999999 -0.001611 0.000000 -vn -0.999999 -0.001611 0.000000 -vn -0.999999 -0.001614 0.000009 -vn -0.999999 -0.001611 0.000000 -vn -0.628164 -0.000000 -0.778081 -vn -0.944355 0.104600 -0.311853 -vn -0.901436 -0.000000 -0.432913 -vn -0.608806 0.773474 -0.176329 -vn 0.616344 0.570219 0.543112 -vn -0.178933 0.496218 0.849559 -vn -0.336067 0.926478 0.169402 -vn 0.326412 0.192288 0.925462 -vn -0.202222 -0.886786 0.415592 -vn 0.131097 -0.303651 0.943721 -vn 0.525411 -0.638120 0.562802 -vn -0.459420 -0.687735 0.562098 -vn -0.287476 -0.887075 -0.361187 -vn -0.432678 -0.718254 -0.544887 -vn -0.452460 0.701514 -0.550598 -vn -0.301712 0.879869 -0.367153 -vn -0.021542 0.999768 -0.000000 -vn -0.999832 -0.018320 -0.000006 -vn 0.737134 -0.424441 -0.525816 -vn 0.389168 0.588615 -0.708576 -vn 0.389168 0.588615 -0.708576 -vn 0.250198 0.244643 -0.936777 -vn 0.251011 -0.242045 -0.937234 -vn 0.737134 -0.424441 -0.525816 -vn 0.004436 0.999814 -0.018778 -vn 0.004436 0.999814 -0.018778 -vn 0.004436 0.999814 -0.018778 -vn 0.000000 0.999987 0.004994 -vn 0.000000 0.999987 0.004994 -vn 0.000000 0.999987 0.004994 -vn 0.000006 -0.999892 0.014681 -vn 0.000006 -0.999892 0.014681 -vn 0.000006 -0.999892 0.014681 -vn -0.004437 -0.999978 -0.004971 -vn -0.004437 -0.999978 -0.004971 -vn -0.004437 -0.999978 -0.004971 -vn 0.000010 0.002341 -0.999997 -vn 0.000010 0.002341 -0.999997 -vn 0.000010 0.002341 -0.999997 -vn 0.000010 0.002341 -0.999997 -vn 0.616344 0.570219 0.543112 -vn -0.019503 0.999797 0.004993 -vn -0.019503 0.999797 0.004993 -vn -0.019503 0.999797 0.004993 -vn 0.021541 -0.999756 -0.004970 -vn 0.021541 -0.999756 -0.004970 -vn 0.021541 -0.999756 -0.004970 -vn -0.999832 -0.018323 -0.000000 -vn 0.999832 0.018322 0.000000 -vn 0.999832 0.018322 -0.000027 -vn 0.999832 0.018322 -0.000027 -vn -0.028006 0.999607 -0.000674 -vn -0.028006 0.999607 -0.000674 -vn -0.028006 0.999607 -0.000674 -vn 0.021541 -0.999767 0.001458 -vn 0.021541 -0.999767 0.001458 -vn 0.021541 -0.999767 0.001458 -vn 0.026277 -0.999654 -0.000654 -vn 0.026277 -0.999654 -0.000654 -vn 0.026277 -0.999654 -0.000654 -vn 0.000000 -0.000001 -1.000000 -vn 0.000000 -0.000001 -1.000000 -vn 0.000000 -0.000001 -1.000000 -vn 0.000000 -0.000001 -1.000000 -vn 0.251011 -0.242045 -0.937234 -vn 0.250198 0.244643 -0.936777 -vn -0.999832 -0.018323 0.000012 -vn -0.999832 -0.018322 -0.000000 -vn -0.999832 -0.018323 0.000012 -vn 0.999832 0.018322 0.000000 -vn 0.999832 0.018322 0.000012 -vn 0.999832 0.018322 0.000012 -vn -0.021910 0.999760 -0.000674 -vn -0.016455 0.999865 0.000337 -vn -0.016455 0.999865 0.000337 -vn -0.016455 0.999865 0.000337 -vn 0.021541 -0.999768 -0.000654 -vn 0.021541 -0.999768 -0.000654 -vn 0.021541 -0.999768 -0.000654 -vn 0.014490 -0.999894 0.001458 -vn 0.014490 -0.999894 0.001458 -vn 0.014490 -0.999894 0.001458 -vn 0.000000 -0.000001 -1.000000 -vn 0.000000 -0.000001 -1.000000 -vn 0.000000 -0.000001 -1.000000 -vn 0.000000 -0.000001 -1.000000 -vn 0.999921 -0.012551 0.000071 -vn 0.999921 -0.012551 0.000071 -vn 0.999921 -0.012577 -0.000000 -vn 0.999921 -0.012551 0.000071 -vn 0.004437 0.999990 0.000000 -vn 0.004437 0.999990 0.000000 -vn 0.004437 0.999990 0.000000 -vn 0.004437 0.999990 0.000000 -vn 0.737493 -0.000000 -0.675355 -vn 0.929055 0.064665 -0.364246 -vn 0.909553 0.332232 -0.249671 -vn 0.967756 -0.000000 -0.251889 -vn -0.950141 0.000000 0.311822 -vn -0.754521 0.319338 0.573342 -vn -0.729449 0.645891 0.225231 -vn -0.379580 0.000000 0.925159 -vn -0.176656 0.422102 0.889169 -vn 0.201703 0.000000 0.979447 -vn 0.362436 0.382183 0.850045 -vn 0.798191 0.000000 0.602404 -vn 0.968028 0.109472 0.225694 -vn -0.171179 0.888219 0.426338 -vn 0.062881 0.915143 0.398194 -vn 0.465687 0.809125 0.358403 -vn 0.798191 0.000000 0.602404 -vn 0.465687 0.809125 0.358403 -vn -0.000000 -0.000000 -1.000000 -vn 0.000000 -0.000000 -1.000000 -vn 0.000000 -0.000000 -1.000000 -vn 0.000000 -0.000000 -1.000000 -vn 0.000000 -0.000000 -1.000000 -vn 0.000000 -0.000000 -1.000000 -vn 0.000000 -0.000000 -1.000000 -vn 0.000000 -0.000000 -1.000000 -vn 0.000000 -0.000000 -1.000000 -vn 0.000000 -0.000000 -1.000000 -vn 0.000000 -0.000000 -1.000000 -vn 0.000000 -0.000000 -1.000000 -vn 0.011725 0.985795 0.167542 -vn 0.909553 0.332232 -0.249671 -vn -0.005642 0.990634 0.136425 -vn -0.608806 0.773474 -0.176329 -vn -0.999745 0.022571 -0.000427 -vn -0.999745 0.022571 -0.000427 -vn -0.999745 0.022571 -0.000427 -vn -0.999971 -0.005425 0.005345 -vn -0.999971 -0.005425 0.005345 -vn -0.999971 -0.005425 0.005345 -vn -0.148086 0.988975 -0.000000 -vn -0.148086 0.988975 -0.000000 -vn -0.148086 0.988975 -0.000000 -vn -0.464450 0.885579 0.005999 -vn -0.464450 0.885579 0.005999 -vn -0.464450 0.885579 0.005999 -vn -0.847890 0.018688 0.529842 -vn -0.847890 0.018688 0.529842 -vn -0.847890 0.018688 0.529842 -vn -0.845153 0.019082 0.534183 -vn -0.845153 0.019082 0.534183 -vn -0.845153 0.019082 0.534183 -vn 0.000000 -0.000001 -1.000000 -vn 0.000000 -0.000001 -1.000000 -vn -0.999992 -0.004070 0.000000 -vn -0.999992 -0.004070 0.000000 -vn -0.999992 -0.004070 0.000000 -vn -0.999992 -0.004070 0.000000 -vn -0.000000 0.000000 1.000000 -vn -0.000000 0.000000 1.000000 -vn 0.999992 0.004076 -0.000000 -vn 0.999992 0.004076 0.000000 -vn 0.999992 0.004076 -0.000000 -vn 0.999992 0.004076 -0.000000 -vn -0.004429 0.913622 -0.406539 -vn -0.004429 0.913622 -0.406539 -vn -0.004429 0.913622 -0.406539 -vn -0.004027 0.907531 -0.419964 -vn -0.004027 0.907531 -0.419964 -vn -0.004027 0.907531 -0.419964 -vn -0.004381 0.903704 0.428136 -vn -0.004381 0.903704 0.428136 -vn -0.004381 0.903704 0.428136 -vn -0.004036 0.909589 0.415488 -vn -0.004036 0.909589 0.415488 -vn -0.004036 0.909589 0.415488 -vn -0.020304 0.999794 -0.000000 -vn -0.020305 0.999794 -0.000000 -vn -0.020304 0.999794 -0.000000 -vn -0.020304 0.999794 -0.000000 -vn 0.012824 0.999918 -0.000000 -vn 0.012824 0.999918 -0.000000 -vn 0.012824 0.999918 -0.000000 -vn 0.012824 0.999918 -0.000000 -vn -0.000000 0.000001 -1.000000 -vn -0.000000 0.000001 -1.000000 -vn -0.000000 0.000001 -1.000000 -vn -0.000000 0.000001 -1.000000 -vn 0.004437 -0.999990 0.000000 -vn 0.004437 -0.999990 0.000000 -vn 0.004437 -0.999990 0.000000 -vn 0.004437 -0.999990 0.000000 -vn -0.000000 0.000001 1.000000 -vn -0.000000 0.000001 1.000000 -vn -0.000000 0.000001 1.000000 -vn -0.000000 0.000001 1.000000 -vn -0.999469 0.018316 -0.026931 -vn -0.999469 0.018316 -0.026931 -vn -0.999469 0.018316 -0.026931 -vn -0.999469 0.018316 -0.026931 -vn 0.021530 0.999231 -0.032765 -vn 0.021530 0.999231 -0.032765 -vn 0.021530 0.999231 -0.032765 -vn 0.006116 0.999583 -0.028232 -vn 0.006116 0.999583 -0.028232 -vn 0.006116 0.999583 -0.028232 -vn 0.999329 -0.018313 -0.031720 -vn 0.999329 -0.018313 -0.031720 -vn 0.999329 -0.018313 -0.031720 -vn 0.999329 -0.018313 -0.031720 -vn -0.021533 -0.999381 -0.027818 -vn -0.021533 -0.999381 -0.027818 -vn -0.021533 -0.999381 -0.027818 -vn -0.039109 -0.998716 -0.032200 -vn -0.039109 -0.998716 -0.032200 -vn -0.039109 -0.998716 -0.032200 -vn -0.999329 0.018313 -0.031720 -vn -0.999329 0.018313 -0.031720 -vn -0.999329 0.018313 -0.031720 -vn -0.999329 0.018313 -0.031720 -vn 0.021533 0.999381 -0.027818 -vn 0.021533 0.999381 -0.027818 -vn 0.021533 0.999381 -0.027818 -vn 0.039108 0.998716 -0.032200 -vn 0.039108 0.998716 -0.032200 -vn 0.039108 0.998716 -0.032200 -vn 0.999469 -0.018316 -0.026931 -vn 0.999469 -0.018316 -0.026931 -vn 0.999469 -0.018316 -0.026931 -vn 0.999469 -0.018316 -0.026931 -vn -0.021530 -0.999231 -0.032765 -vn -0.021530 -0.999231 -0.032765 -vn -0.021530 -0.999231 -0.032765 -vn -0.006116 -0.999583 -0.028231 -vn -0.006116 -0.999583 -0.028231 -vn -0.006116 -0.999583 -0.028231 -vn 0.021541 0.999768 -0.000000 -vn 0.021541 0.999768 -0.000000 -vn 0.021541 0.999768 -0.000000 -vn -0.021714 -0.999764 0.000317 -vn -0.021714 -0.999764 0.000317 -vn -0.021542 -0.999768 0.000000 -vn 0.021542 0.999768 -0.000000 -vn 0.021541 0.999768 -0.000000 -vn 0.021541 0.999768 -0.000000 -vn -0.021910 -0.999760 -0.000674 -vn -0.021542 -0.999768 0.000000 -vn -0.021910 -0.999760 -0.000674 -vn -0.999832 0.018323 -0.000000 -vn -0.999832 0.018323 -0.000000 -vn -0.999832 0.018323 -0.000000 -vn 0.999832 -0.018322 0.000000 -vn 0.999832 -0.018322 0.000000 -vn 0.999832 -0.018322 0.000000 -vn -0.999832 0.018322 -0.000000 -vn -0.999832 0.018322 -0.000000 -vn -0.999832 0.018322 -0.000000 -vn 0.999832 -0.018322 0.000000 -vn 0.999832 -0.018322 0.000000 -vn 0.999832 -0.018322 0.000000 -vn 0.021541 0.999768 -0.000000 -vn 0.021541 0.999768 -0.000000 -vn 0.021541 0.999768 -0.000000 -vn 0.021541 0.999768 -0.000000 -vn 0.968686 -0.195526 0.153029 -vn 0.968686 -0.195526 0.153029 -vn 0.968686 -0.195526 0.153029 -vn 0.973794 -0.182610 0.135571 -vn 0.973794 -0.182610 0.135571 -vn 0.973794 -0.182610 0.135571 -vn 0.956360 -0.020938 -0.291439 -vn 0.956184 -0.021083 -0.292008 -vn 0.956360 -0.020938 -0.291439 -vn 0.956360 -0.020938 -0.291439 -vn 0.947601 -0.319455 0.000000 -vn 0.947601 -0.319455 0.000000 -vn 0.947601 -0.319455 0.000000 -vn 0.947601 -0.319455 0.000000 -vn 0.501241 -0.666644 0.551674 -vn 0.501241 -0.666644 0.551674 -vn 0.501241 -0.666644 0.551674 -vn 0.508598 -0.663687 0.548496 -vn 0.508598 -0.663687 0.548496 -vn 0.508598 -0.663687 0.548496 -vn 0.999757 -0.022044 0.000000 -vn 0.999757 -0.022044 0.000000 -vn 0.999757 -0.022044 0.000000 -vn 0.999757 -0.022044 0.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.000000 0.000000 1.000000 -vn 0.921437 -0.016886 0.388160 -vn 0.854236 -0.015654 0.519649 -vn 0.967760 -0.017734 0.251249 -vn 0.967760 -0.017734 0.251250 -vn 0.019763 0.917212 0.397908 -vn 0.018253 0.847154 0.531034 -vn 0.020806 0.965657 0.258986 -vn 0.020806 0.965657 0.258986 -vn -0.921438 0.016886 0.388159 -vn -0.854236 0.015654 0.519649 -vn -0.967760 0.017734 0.251249 -vn -0.967760 0.017734 0.251249 -vn -0.019762 -0.917212 0.397908 -vn -0.018253 -0.847154 0.531034 -vn -0.020806 -0.965657 0.258986 -vn -0.020806 -0.965657 0.258986 -vn 0.893681 -0.016377 0.448404 -vn 0.019147 0.888655 0.458176 -vn -0.893681 0.016377 0.448404 -vn -0.019147 -0.888655 0.458176 -vn 0.701700 0.674268 0.230173 -vn 0.712574 0.684717 0.152974 -vn 0.707594 0.679932 -0.192362 -vn 0.690072 0.663095 -0.290011 -vn -0.674165 0.701592 0.230801 -vn -0.684673 0.712527 0.153389 -vn -0.679869 0.707528 -0.192829 -vn -0.662945 0.689916 -0.290723 -vn 0.674165 -0.701592 0.230802 -vn 0.684673 -0.712527 0.153389 -vn 0.679869 -0.707528 -0.192828 -vn 0.662945 -0.689916 -0.290722 -vn -0.701699 -0.674269 0.230174 -vn -0.712573 -0.684717 0.152974 -vn -0.707594 -0.679932 -0.192362 -vn -0.690071 -0.663095 -0.290011 -vn 0.698442 -0.012799 -0.715552 -vn 0.698442 -0.012799 -0.715552 -vn 0.858479 -0.015732 -0.512607 -vn 0.014796 0.686711 -0.726780 -vn 0.014796 0.686712 -0.726779 -vn 0.018371 0.852614 -0.522219 -vn -0.698441 0.012799 -0.715553 -vn -0.698441 0.012799 -0.715553 -vn -0.858479 0.015732 -0.512607 -vn -0.014796 -0.686711 -0.726780 -vn -0.014796 -0.686711 -0.726780 -vn -0.018371 -0.852614 -0.522219 -vn 0.974379 -0.017856 0.224202 -vn 0.020969 0.973180 0.229088 -vn -0.974379 0.017856 0.224202 -vn -0.020969 -0.973180 0.229088 -vn 0.966434 -0.017711 -0.256303 -vn 0.020794 0.965085 -0.261109 -vn -0.966434 0.017710 -0.256304 -vn -0.020794 -0.965085 -0.261109 -vn 0.619054 -0.644240 0.449140 -vn 0.644657 0.619456 0.447986 -vn -0.644657 -0.619456 0.447987 -vn -0.619055 0.644239 0.449140 -vn 0.575750 -0.599173 -0.556331 -vn 0.599769 0.576323 -0.555094 -vn -0.599768 -0.576322 -0.555095 -vn -0.575749 0.599172 -0.556332 -vn 0.999832 -0.018322 0.000000 -vn 0.999832 -0.018322 0.000000 -vn 0.999832 -0.018322 0.000000 -vn 0.999832 -0.018322 0.000000 -vn 0.021541 0.999768 -0.000000 -vn 0.021541 0.999768 -0.000000 -vn 0.021541 0.999768 -0.000000 -vn 0.021541 0.999768 -0.000000 -vn -0.999832 0.018322 -0.000000 -vn -0.999832 0.018322 -0.000000 -vn -0.999832 0.018322 -0.000000 -vn -0.999832 0.018322 -0.000000 -vn -0.021541 -0.999768 0.000000 -vn -0.021541 -0.999768 0.000000 -vn -0.021541 -0.999768 0.000000 -vn -0.021541 -0.999768 0.000000 -vn 0.014158 0.657083 0.753685 -vn 0.014158 0.657082 0.753686 -vn 0.014158 0.657083 0.753685 -vn 0.014158 0.657083 0.753685 -vn 0.669174 -0.012263 0.743005 -vn 0.669174 -0.012263 0.743005 -vn 0.669174 -0.012263 0.743005 -vn 0.669174 -0.012263 0.743005 -vn -0.014158 -0.657082 0.753686 -vn -0.014158 -0.657082 0.753686 -vn -0.014158 -0.657082 0.753686 -vn -0.014158 -0.657082 0.753686 -vn -0.669173 0.012263 0.743005 -vn -0.669173 0.012263 0.743005 -vn -0.669173 0.012263 0.743005 -vn -0.669173 0.012263 0.743005 -vn 0.999999 -0.001050 0.000000 -vn 0.999999 -0.001050 0.000000 -vn 0.999999 -0.001050 0.000000 -vn 0.999999 -0.001050 0.000000 -vn -0.999999 0.001055 0.000000 -vn -0.999999 0.001055 0.000000 -vn -0.999999 0.001055 0.000000 -vn -0.999999 0.001055 0.000000 -vn 0.000000 -0.770164 0.637845 -vn 0.000000 -0.770164 0.637845 -vn 0.000000 -0.770164 0.637845 -vn -0.016619 -0.771290 0.636266 -vn -0.016619 -0.771290 0.636266 -vn -0.016619 -0.771290 0.636266 -vn 0.193431 0.981114 -0.000000 -vn 0.193431 0.981114 -0.000000 -vn 0.193431 0.981114 -0.000000 -vn 0.193431 0.981114 -0.000000 -vn 0.021301 0.988620 0.148918 -vn 0.021301 0.988620 0.148918 -vn 0.021301 0.988620 0.148918 -vn 0.021301 0.988620 0.148918 -vn -0.148086 0.988975 -0.000000 -vn 0.999832 -0.018322 0.000000 -vn 0.999832 -0.018322 0.000000 -vn 0.999832 -0.018322 0.000000 -vn 0.999760 -0.021888 -0.000000 -vn 0.999760 -0.021888 -0.000000 -vn 0.999760 -0.021888 -0.000000 -vn 0.999760 -0.021888 -0.000000 -vn -0.999757 0.022035 0.000000 -vn -0.999757 0.022035 0.000000 -vn -0.999757 0.022035 0.000000 -vn -0.999757 0.022035 0.000000 -vn -0.000211 -0.004415 -0.999990 -vn 0.000000 -0.004485 -0.999990 -vn -0.000211 -0.004415 -0.999990 -vn -0.000211 -0.004415 -0.999990 -vn 0.999832 -0.018322 0.000000 -vn 0.999832 -0.018322 0.000000 -vn -0.021541 -0.999768 0.000000 -vn -0.021541 -0.999768 0.000000 -vn -0.021541 -0.999768 0.000000 -vn -0.021714 -0.999764 0.000317 -vn -0.999832 0.018323 -0.000000 -vn -0.999832 0.018323 -0.000000 -vn -0.999832 0.018320 -0.000006 -vn -0.999832 0.018322 0.000000 -vn -0.999999 0.001611 0.000000 -vn -0.999999 0.001614 0.000009 -vn -0.999999 0.001611 0.000000 -vn -0.999999 0.001611 0.000000 -vn -0.944355 -0.104600 -0.311853 -vn -0.608807 -0.773474 -0.176329 -vn 0.616344 -0.570219 0.543112 -vn -0.336067 -0.926478 0.169402 -vn -0.178933 -0.496218 0.849559 -vn 0.326412 -0.192288 0.925462 -vn -0.202221 0.886786 0.415592 -vn 0.525411 0.638120 0.562802 -vn 0.131097 0.303651 0.943721 -vn -0.459420 0.687735 0.562098 -vn -0.287476 0.887075 -0.361187 -vn -0.432678 0.718253 -0.544887 -vn -0.301712 -0.879869 -0.367153 -vn -0.452459 -0.701514 -0.550598 -vn -0.021541 -0.999768 0.000000 -vn -0.999832 0.018320 -0.000006 -vn 0.737134 0.424441 -0.525816 -vn 0.389168 -0.588615 -0.708576 -vn 0.389168 -0.588615 -0.708576 -vn 0.250198 -0.244643 -0.936777 -vn 0.251011 0.242045 -0.937234 -vn 0.737134 0.424441 -0.525816 -vn 0.004436 -0.999814 -0.018777 -vn 0.004436 -0.999814 -0.018777 -vn 0.004436 -0.999814 -0.018777 -vn 0.000000 -0.999987 0.004994 -vn 0.000000 -0.999987 0.004994 -vn 0.000000 -0.999987 0.004994 -vn 0.000006 0.999892 0.014681 -vn 0.000006 0.999892 0.014681 -vn 0.000006 0.999892 0.014681 -vn -0.004437 0.999978 -0.004971 -vn -0.004437 0.999978 -0.004971 -vn -0.004437 0.999978 -0.004971 -vn 0.000010 -0.002341 -0.999997 -vn 0.000010 -0.002341 -0.999997 -vn 0.000010 -0.002341 -0.999997 -vn 0.000010 -0.002341 -0.999997 -vn 0.616344 -0.570219 0.543112 -vn -0.019503 -0.999797 0.004993 -vn -0.019503 -0.999797 0.004993 -vn -0.019503 -0.999797 0.004993 -vn 0.021541 0.999756 -0.004970 -vn 0.021541 0.999756 -0.004970 -vn 0.021541 0.999756 -0.004970 -vn -0.999832 0.018323 -0.000000 -vn 0.999832 -0.018322 0.000000 -vn 0.999832 -0.018322 -0.000027 -vn 0.999832 -0.018322 -0.000027 -vn -0.028006 -0.999607 -0.000674 -vn -0.028006 -0.999607 -0.000674 -vn -0.028006 -0.999607 -0.000674 -vn 0.021541 0.999767 0.001458 -vn 0.021541 0.999767 0.001458 -vn 0.021541 0.999767 0.001458 -vn 0.026277 0.999654 -0.000654 -vn 0.026277 0.999654 -0.000654 -vn 0.026277 0.999654 -0.000654 -vn 0.000000 0.000001 -1.000000 -vn 0.000000 0.000001 -1.000000 -vn 0.000000 0.000001 -1.000000 -vn 0.000000 0.000001 -1.000000 -vn 0.251011 0.242045 -0.937234 -vn 0.250198 -0.244643 -0.936777 -vn -0.999832 0.018322 -0.000000 -vn -0.999832 0.018323 0.000012 -vn -0.999832 0.018323 0.000012 -vn 0.999832 -0.018322 0.000000 -vn 0.999832 -0.018322 0.000012 -vn 0.999832 -0.018322 0.000012 -vn -0.021910 -0.999760 -0.000674 -vn -0.016454 -0.999865 0.000337 -vn -0.016454 -0.999865 0.000337 -vn -0.016454 -0.999865 0.000337 -vn 0.021541 0.999768 -0.000654 -vn 0.021541 0.999768 -0.000654 -vn 0.021541 0.999768 -0.000654 -vn 0.014490 0.999894 0.001458 -vn 0.014490 0.999894 0.001458 -vn 0.014490 0.999894 0.001458 -vn 0.000000 0.000001 -1.000000 -vn 0.000000 0.000001 -1.000000 -vn 0.000000 0.000001 -1.000000 -vn 0.000000 0.000001 -1.000000 -vn 0.999921 0.012551 0.000071 -vn 0.999921 0.012577 -0.000000 -vn 0.999921 0.012551 0.000071 -vn 0.999921 0.012551 0.000071 -vn 0.004437 -0.999990 0.000000 -vn 0.004437 -0.999990 0.000000 -vn 0.004437 -0.999990 0.000000 -vn 0.004437 -0.999990 0.000000 -vn 0.909553 -0.332232 -0.249671 -vn 0.929055 -0.064665 -0.364246 -vn -0.754521 -0.319338 0.573342 -vn -0.729449 -0.645891 0.225232 -vn -0.176656 -0.422102 0.889170 -vn 0.362436 -0.382183 0.850045 -vn 0.968028 -0.109472 0.225694 -vn -0.171179 -0.888219 0.426339 -vn 0.062881 -0.915143 0.398194 -vn 0.465687 -0.809125 0.358404 -vn 0.465687 -0.809125 0.358404 -vn -0.000000 -0.000000 -1.000000 -vn -0.000000 -0.000000 -1.000000 -vn -0.000000 -0.000000 -1.000000 -vn -0.000000 -0.000000 -1.000000 -vn -0.000000 -0.000000 -1.000000 -vn -0.000000 -0.000000 -1.000000 -vn 0.011725 -0.985795 0.167542 -vn 0.909553 -0.332232 -0.249671 -vn -0.005642 -0.990634 0.136425 -vn -0.608807 -0.773474 -0.176329 -f 1/1/1 2/2/2 3/3/3 -f 4/4/4 5/5/5 6/6/6 -f 7/7/7 8/8/8 9/9/9 -f 10/10/10 11/11/11 12/12/12 -f 13/13/13 14/14/14 15/15/15 -f 16/16/16 17/17/17 18/18/18 -f 19/19/19 20/20/20 21/21/21 -f 20/20/20 19/19/19 22/22/22 -f 23/23/23 24/24/24 25/25/25 -f 24/24/24 23/23/23 26/26/26 -f 27/27/27 28/28/28 29/29/29 -f 28/28/28 27/27/27 30/30/30 -f 31/31/31 32/32/32 33/33/33 -f 32/32/32 31/31/31 34/34/34 -f 35/35/35 36/36/36 37/37/37 -f 38/38/38 39/39/39 40/40/40 -f 41/41/41 42/42/42 43/43/43 -f 44/44/44 45/45/45 46/46/46 -f 47/47/47 48/48/48 49/49/49 -f 48/48/48 47/47/47 50/50/50 -f 51/51/51 52/52/52 53/53/53 -f 52/52/52 51/51/51 54/54/54 -f 55/55/55 56/56/56 57/57/57 -f 56/56/56 55/55/55 58/58/58 -f 59/59/59 60/60/60 61/61/61 -f 60/60/60 59/59/59 62/62/62 -f 63/63/63 64/64/64 65/65/65 -f 64/64/64 63/63/63 66/66/66 -f 67/67/67 68/68/68 69/69/69 -f 68/68/68 67/67/67 70/70/70 -f 71/71/71 72/72/72 73/73/73 -f 74/74/74 75/75/75 76/76/76 -f 77/77/77 78/78/78 79/79/79 -f 78/78/78 77/77/77 80/80/80 -f 81/81/81 82/82/82 83/83/83 -f 84/84/84 85/85/85 86/86/86 -f 87/87/87 88/88/88 89/89/89 -f 88/88/88 87/87/87 90/90/90 -f 91/91/91 92/92/92 93/93/93 -f 94/94/94 95/95/95 96/96/96 -f 97/97/97 98/98/98 99/99/99 -f 98/98/98 97/97/97 100/100/100 -f 101/101/101 102/102/102 103/103/103 -f 104/104/104 105/105/105 106/106/106 -f 107/107/107 108/108/108 109/109/109 -f 110/110/110 111/111/111 112/112/112 -f 113/113/113 114/114/114 115/115/115 -f 116/116/116 117/117/117 118/118/118 -f 119/119/119 120/120/120 121/121/121 -f 122/122/122 123/123/123 124/124/124 -f 125/125/125 126/126/126 127/127/127 -f 128/128/128 129/129/129 130/130/130 -f 115/115/115 131/131/131 113/113/113 -f 131/131/131 115/115/115 132/132/132 -f 107/107/107 133/133/133 108/108/108 -f 133/133/133 107/107/107 134/134/134 -f 135/135/135 136/136/136 137/137/137 -f 138/138/138 139/139/139 140/140/140 -f 141/141/141 142/142/142 143/143/143 -f 142/142/142 141/141/141 144/144/144 -f 145/145/145 146/146/146 147/147/147 -f 146/146/146 145/145/145 148/148/148 -f 149/149/149 150/150/150 151/151/151 -f 152/152/152 153/153/153 154/154/154 -f 155/155/155 156/156/156 157/157/157 -f 158/158/158 157/157/157 156/156/156 -f 159/159/159 160/160/160 161/161/161 -f 160/160/160 159/159/159 162/162/162 -f 163/163/163 164/164/164 165/165/165 -f 164/164/164 163/163/163 166/166/166 -f 167/167/167 168/168/168 169/169/169 -f 168/168/168 167/167/167 170/170/170 -f 171/171/171 172/172/172 173/173/173 -f 172/172/172 171/171/171 174/174/174 -f 175/175/175 176/176/176 177/177/177 -f 176/176/176 175/175/175 178/178/178 -f 165/165/165 179/179/179 163/163/163 -f 169/169/169 180/180/180 167/167/167 -f 173/173/173 181/181/181 171/171/171 -f 177/177/177 182/182/182 175/175/175 -f 183/183/183 184/184/184 185/185/185 -f 186/186/186 185/185/185 184/184/184 -f 187/187/187 188/188/188 189/189/189 -f 190/190/190 189/189/189 188/188/188 -f 191/191/191 192/192/192 193/193/193 -f 194/194/194 193/193/193 192/192/192 -f 195/195/195 196/196/196 197/197/197 -f 198/198/198 197/197/197 196/196/196 -f 199/199/199 200/200/200 201/201/201 -f 202/202/202 203/203/203 204/204/204 -f 205/205/205 206/206/206 207/207/207 -f 208/208/208 209/209/209 210/210/210 -f 179/179/179 165/165/165 211/211/211 -f 180/180/180 169/169/169 212/212/212 -f 181/181/181 173/173/173 213/213/213 -f 182/182/182 177/177/177 214/214/214 -f 200/200/200 199/199/199 215/215/215 -f 203/203/203 202/202/202 216/216/216 -f 206/206/206 205/205/205 217/217/217 -f 209/209/209 208/208/208 218/218/218 -f 219/219/219 191/191/191 193/193/193 -f 183/183/183 185/185/185 220/220/220 -f 195/195/195 197/197/197 221/221/221 -f 187/187/187 189/189/189 222/222/222 -f 192/192/192 223/223/223 194/194/194 -f 224/224/224 186/186/186 184/184/184 -f 225/225/225 198/198/198 196/196/196 -f 226/226/226 190/190/190 188/188/188 -f 211/211/211 215/215/215 179/179/179 -f 215/215/215 211/211/211 200/200/200 -f 212/212/212 216/216/216 180/180/180 -f 216/216/216 212/212/212 203/203/203 -f 213/213/213 217/217/217 181/181/181 -f 217/217/217 213/213/213 206/206/206 -f 214/214/214 218/218/218 182/182/182 -f 218/218/218 214/214/214 209/209/209 -f 227/227/227 228/228/228 229/229/229 -f 228/228/228 227/227/227 230/230/230 -f 231/231/231 232/232/232 233/233/233 -f 232/232/232 231/231/231 234/234/234 -f 235/235/235 236/236/236 237/237/237 -f 236/236/236 235/235/235 238/238/238 -f 239/239/239 240/240/240 241/241/241 -f 240/240/240 239/239/239 242/242/242 -f 243/243/243 244/244/244 245/245/245 -f 244/244/244 243/243/243 246/246/246 -f 247/247/247 248/248/248 249/249/249 -f 248/248/248 247/247/247 250/250/250 -f 251/251/251 252/252/252 253/253/253 -f 252/252/252 251/251/251 254/254/254 -f 255/255/255 256/256/256 257/257/257 -f 256/256/256 255/255/255 258/258/258 -f 259/259/259 260/260/260 261/261/261 -f 260/260/260 259/259/259 262/262/262 -f 263/263/263 264/264/264 265/265/265 -f 264/264/264 263/263/263 266/266/266 -f 267/267/267 268/268/268 269/269/269 -f 270/270/270 271/271/271 272/272/272 -f 273/273/273 274/274/274 275/275/275 -f 274/274/274 273/273/273 276/276/276 -f 277/277/277 278/278/278 279/279/279 -f 278/278/278 277/277/277 280/280/280 -f 8/8/8 7/7/7 281/281/281 -f 282/282/282 283/283/283 284/284/284 -f 285/285/285 286/286/286 287/287/287 -f 286/286/286 285/285/285 288/288/288 -f 289/289/289 290/290/290 291/291/291 -f 290/290/290 289/289/289 292/292/292 -f 293/293/293 294/294/294 295/295/295 -f 294/294/294 293/293/293 296/296/296 -f 282/282/282 297/297/297 283/283/283 -f 297/297/297 282/282/282 298/298/298 -f 299/299/299 300/300/300 301/301/301 -f 300/300/300 299/299/299 302/302/302 -f 303/303/303 304/304/304 305/305/305 -f 304/304/304 303/303/303 306/306/306 -f 307/307/307 308/308/308 309/309/309 -f 308/308/308 307/307/307 310/310/310 -f 311/311/311 312/312/312 313/313/313 -f 312/312/312 311/311/311 314/314/314 -f 315/315/315 316/316/316 317/317/317 -f 316/316/316 315/315/315 318/318/318 -f 319/319/319 320/320/320 321/321/321 -f 320/320/320 319/319/319 322/322/322 -f 321/321/321 318/318/318 315/315/315 -f 318/318/318 321/321/321 320/320/320 -f 320/320/320 316/316/316 318/318/318 -f 316/316/316 320/320/320 322/322/322 -f 323/323/323 322/322/322 319/319/319 -f 322/322/322 323/323/323 324/324/324 -f 317/317/317 325/325/325 326/326/326 -f 325/325/325 317/317/317 316/316/316 -f 302/302/302 327/327/327 300/300/300 -f 304/304/304 306/306/306 328/328/328 -f 315/315/315 329/329/329 321/321/321 -f 329/329/329 315/315/315 330/330/330 -f 331/331/331 325/325/325 332/332/332 -f 325/325/325 331/331/331 326/326/326 -f 333/333/333 323/323/323 334/334/334 -f 323/323/323 333/333/333 324/324/324 -f 335/335/335 336/336/336 337/337/337 -f 338/338/338 339/339/339 340/340/340 -f 341/341/341 342/342/342 343/343/343 -f 344/344/344 345/345/345 346/346/346 -f 347/347/347 348/348/348 349/349/349 -f 348/348/348 347/347/347 350/350/350 -f 321/321/321 323/323/323 319/319/319 -f 323/323/323 321/321/321 334/334/334 -f 317/317/317 331/331/331 351/351/351 -f 331/331/331 317/317/317 326/326/326 -f 352/352/352 353/353/353 354/354/354 -f 355/355/355 356/356/356 357/357/357 -f 119/119/119 328/328/328 358/358/358 -f 328/328/328 119/119/119 304/304/304 -f 359/359/359 360/360/360 122/122/122 -f 360/360/360 359/359/359 361/361/361 -f 112/112/112 302/302/302 110/110/110 -f 362/362/362 363/363/363 364/364/364 -f 365/365/365 366/366/366 367/367/367 -f 368/368/368 369/369/369 370/370/370 -f 359/359/359 122/122/122 124/124/124 -f 120/120/120 119/119/119 358/358/358 -f 371/371/371 372/372/372 373/373/373 -f 372/372/372 371/371/371 374/374/374 -f 375/375/375 330/330/330 376/376/376 -f 330/330/330 375/375/375 329/329/329 -f 125/125/125 377/377/377 378/378/378 -f 377/377/377 125/125/125 379/379/379 -f 380/380/380 381/381/381 128/128/128 -f 381/381/381 380/380/380 382/382/382 -f 116/116/116 383/383/383 117/117/117 -f 384/384/384 385/385/385 386/386/386 -f 387/387/387 388/388/388 389/389/389 -f 390/390/390 391/391/391 392/392/392 -f 380/380/380 128/128/128 130/130/130 -f 126/126/126 125/125/125 378/378/378 -f 393/393/393 394/394/394 395/395/395 -f 394/394/394 393/393/393 396/396/396 -f 397/397/397 398/398/398 399/399/399 -f 398/398/398 397/397/397 400/400/400 -f 401/401/401 402/402/402 403/403/403 -f 402/402/402 401/401/401 404/404/404 -f 405/405/405 406/406/406 407/407/407 -f 406/406/406 405/405/405 408/408/408 -f 409/409/409 312/312/312 410/410/410 -f 312/312/312 409/409/409 313/313/313 -f 411/411/411 312/312/312 314/314/314 -f 312/312/312 411/411/411 410/410/410 -f 412/412/412 410/410/410 413/413/413 -f 410/410/410 412/412/412 409/409/409 -f 414/414/414 413/413/413 415/415/415 -f 413/413/413 414/414/414 412/412/412 -f 416/416/416 415/415/415 417/417/417 -f 415/415/415 416/416/416 414/414/414 -f 418/418/418 410/410/410 411/411/411 -f 410/410/410 418/418/418 413/413/413 -f 419/419/419 413/413/413 418/418/418 -f 413/413/413 419/419/419 415/415/415 -f 420/420/420 415/415/415 419/419/419 -f 415/415/415 420/420/420 417/417/417 -f 408/408/408 417/417/417 406/406/406 -f 417/417/417 408/408/408 421/421/421 -f 407/407/407 417/417/417 422/422/422 -f 417/417/417 407/407/407 406/406/406 -f 423/423/423 424/424/424 425/425/425 -f 424/424/424 423/423/423 426/426/426 -f 427/427/427 428/428/428 429/429/429 -f 428/428/428 427/427/427 430/430/430 -f 431/431/431 432/432/432 433/433/433 -f 432/432/432 431/431/431 434/434/434 -f 435/435/435 422/422/422 419/419/419 -f 422/422/422 435/435/435 436/436/436 -f 437/437/437 419/419/419 418/418/418 -f 419/419/419 437/437/437 435/435/435 -f 438/438/438 418/418/418 411/411/411 -f 418/418/418 438/438/438 437/437/437 -f 439/439/439 440/440/440 441/441/441 -f 442/442/442 443/443/443 444/444/444 -f 445/445/445 446/446/446 447/447/447 -f 448/448/448 449/449/449 450/450/450 -f 451/451/451 452/452/452 453/453/453 -f 454/454/454 455/455/455 456/456/456 -f 19/19/19 21/21/21 457/457/457 -f 457/457/457 458/458/458 19/19/19 -f 459/459/459 460/460/460 461/461/461 -f 461/461/461 462/462/462 459/459/459 -f 27/27/27 29/29/29 463/463/463 -f 463/463/463 464/464/464 27/27/27 -f 465/465/465 466/466/466 467/467/467 -f 467/467/467 468/468/468 465/465/465 -f 469/469/469 470/470/470 471/471/471 -f 472/472/472 473/473/473 474/474/474 -f 475/475/475 476/476/476 477/477/477 -f 478/478/478 479/479/479 480/480/480 -f 481/481/481 482/482/482 483/483/483 -f 483/483/483 484/484/484 481/481/481 -f 485/485/485 486/486/486 487/487/487 -f 487/487/487 488/488/488 485/485/485 -f 489/489/489 490/490/490 491/491/491 -f 491/491/491 492/492/492 489/489/489 -f 493/493/493 494/494/494 495/495/495 -f 495/495/495 496/496/496 493/493/493 -f 497/497/497 498/498/498 499/499/499 -f 499/499/499 500/500/500 497/497/497 -f 501/501/501 502/502/502 503/503/503 -f 503/503/503 504/504/504 501/501/501 -f 505/505/505 506/506/506 507/507/507 -f 508/508/508 509/509/509 510/510/510 -f 511/511/511 512/512/512 513/513/513 -f 513/513/513 514/514/514 511/511/511 -f 515/515/515 516/516/516 517/517/517 -f 518/518/518 519/519/519 520/520/520 -f 521/521/521 522/522/522 523/523/523 -f 523/523/523 524/524/524 521/521/521 -f 525/525/525 526/526/526 527/527/527 -f 528/528/528 529/529/529 530/530/530 -f 531/531/531 532/532/532 533/533/533 -f 533/533/533 534/534/534 531/531/531 -f 535/535/535 536/536/536 537/537/537 -f 538/538/538 539/539/539 540/540/540 -f 541/541/541 542/542/542 543/543/543 -f 544/544/544 545/545/545 546/546/546 -f 547/547/547 548/548/548 549/549/549 -f 550/550/550 551/551/551 552/552/552 -f 553/553/553 554/554/554 555/555/555 -f 556/556/556 557/557/557 558/558/558 -f 559/559/559 560/560/560 561/561/561 -f 562/562/562 563/563/563 564/564/564 -f 548/548/548 547/547/547 565/565/565 -f 565/565/565 566/566/566 548/548/548 -f 541/541/541 543/543/543 567/567/567 -f 567/567/567 568/568/568 541/541/541 -f 569/569/569 570/570/570 571/571/571 -f 572/572/572 573/573/573 574/574/574 -f 575/575/575 576/576/576 577/577/577 -f 577/577/577 578/578/578 575/575/575 -f 579/579/579 580/580/580 581/581/581 -f 581/581/581 582/582/582 579/579/579 -f 583/583/583 584/584/584 585/585/585 -f 586/586/586 587/587/587 588/588/588 -f 589/589/589 590/590/590 591/591/591 -f 592/592/592 591/591/591 590/590/590 -f 593/593/593 594/594/594 595/595/595 -f 595/595/595 596/596/596 593/593/593 -f 597/597/597 598/598/598 599/599/599 -f 599/599/599 600/600/600 597/597/597 -f 601/601/601 602/602/602 603/603/603 -f 603/603/603 604/604/604 601/601/601 -f 605/605/605 606/606/606 607/607/607 -f 607/607/607 608/608/608 605/605/605 -f 609/609/609 610/610/610 611/611/611 -f 611/611/611 612/612/612 609/609/609 -f 598/598/598 597/597/597 613/613/613 -f 602/602/602 601/601/601 614/614/614 -f 606/606/606 605/605/605 615/615/615 -f 610/610/610 609/609/609 616/616/616 -f 617/617/617 618/618/618 619/619/619 -f 620/620/620 619/619/619 618/618/618 -f 621/621/621 622/622/622 623/623/623 -f 624/624/624 623/623/623 622/622/622 -f 625/625/625 626/626/626 627/627/627 -f 628/628/628 627/627/627 626/626/626 -f 629/629/629 630/630/630 631/631/631 -f 632/632/632 631/631/631 630/630/630 -f 633/633/633 634/634/634 635/635/635 -f 636/636/636 637/637/637 638/638/638 -f 639/639/639 640/640/640 641/641/641 -f 642/642/642 643/643/643 644/644/644 -f 613/613/613 645/645/645 598/598/598 -f 614/614/614 646/646/646 602/602/602 -f 615/615/615 647/647/647 606/606/606 -f 616/616/616 648/648/648 610/610/610 -f 635/635/635 649/649/649 633/633/633 -f 638/638/638 650/650/650 636/636/636 -f 641/641/641 651/651/651 639/639/639 -f 644/644/644 652/652/652 642/642/642 -f 653/653/653 626/626/626 625/625/625 -f 617/617/617 654/654/654 618/618/618 -f 629/629/629 655/655/655 630/630/630 -f 621/621/621 656/656/656 622/622/622 -f 627/627/627 628/628/628 657/657/657 -f 658/658/658 619/619/619 620/620/620 -f 659/659/659 631/631/631 632/632/632 -f 660/660/660 623/623/623 624/624/624 -f 645/645/645 613/613/613 649/649/649 -f 649/649/649 635/635/635 645/645/645 -f 646/646/646 614/614/614 650/650/650 -f 650/650/650 638/638/638 646/646/646 -f 647/647/647 615/615/615 651/651/651 -f 651/651/651 641/641/641 647/647/647 -f 648/648/648 616/616/616 652/652/652 -f 652/652/652 644/644/644 648/648/648 -f 661/661/661 662/662/662 663/663/663 -f 663/663/663 664/664/664 661/661/661 -f 665/665/665 666/666/666 667/667/667 -f 667/667/667 668/668/668 665/665/665 -f 669/669/669 670/670/670 671/671/671 -f 671/671/671 672/672/672 669/669/669 -f 673/673/673 674/674/674 675/675/675 -f 675/675/675 676/676/676 673/673/673 -f 677/677/677 678/678/678 679/679/679 -f 679/679/679 680/680/680 677/677/677 -f 681/681/681 682/682/682 683/683/683 -f 683/683/683 684/684/684 681/681/681 -f 685/685/685 686/686/686 687/687/687 -f 687/687/687 688/688/688 685/685/685 -f 689/689/689 690/690/690 691/691/691 -f 691/691/691 692/692/692 689/689/689 -f 693/693/693 694/694/694 695/695/695 -f 695/695/695 696/696/696 693/693/693 -f 697/697/697 698/698/698 699/699/699 -f 699/699/699 700/700/700 697/697/697 -f 701/701/701 702/702/702 703/703/703 -f 704/704/704 705/705/705 706/706/706 -f 707/707/707 708/708/708 709/709/709 -f 709/709/709 710/710/710 707/707/707 -f 711/711/711 712/712/712 713/713/713 -f 713/713/713 714/714/714 711/711/711 -f 447/447/447 715/715/715 445/445/445 -f 716/716/716 717/717/717 718/718/718 -f 719/719/719 720/720/720 721/721/721 -f 721/721/721 722/722/722 719/719/719 -f 723/723/723 724/724/724 725/725/725 -f 725/725/725 726/726/726 723/723/723 -f 727/727/727 728/728/728 729/729/729 -f 729/729/729 730/730/730 727/727/727 -f 716/716/716 718/718/718 731/731/731 -f 731/731/731 732/732/732 716/716/716 -f 733/733/733 734/734/734 735/735/735 -f 735/735/735 736/736/736 733/733/733 -f 737/737/737 738/738/738 739/739/739 -f 739/739/739 740/740/740 737/737/737 -f 741/741/741 742/742/742 743/743/743 -f 743/743/743 744/744/744 741/741/741 -f 311/311/311 313/313/313 745/745/745 -f 745/745/745 746/746/746 311/311/311 -f 747/747/747 748/748/748 749/749/749 -f 749/749/749 750/750/750 747/747/747 -f 751/751/751 752/752/752 753/753/753 -f 753/753/753 754/754/754 751/751/751 -f 752/752/752 747/747/747 750/750/750 -f 750/750/750 753/753/753 752/752/752 -f 753/753/753 750/750/750 749/749/749 -f 749/749/749 754/754/754 753/753/753 -f 755/755/755 751/751/751 754/754/754 -f 754/754/754 756/756/756 755/755/755 -f 748/748/748 757/757/757 758/758/758 -f 758/758/758 749/749/749 748/748/748 -f 736/736/736 735/735/735 759/759/759 -f 739/739/739 760/760/760 740/740/740 -f 747/747/747 752/752/752 761/761/761 -f 761/761/761 762/762/762 747/747/747 -f 763/763/763 764/764/764 758/758/758 -f 758/758/758 757/757/757 763/763/763 -f 765/765/765 766/766/766 755/755/755 -f 755/755/755 756/756/756 765/765/765 -f 767/767/767 768/768/768 769/769/769 -f 770/770/770 771/771/771 772/772/772 -f 773/773/773 774/774/774 775/775/775 -f 776/776/776 777/777/777 778/778/778 -f 779/779/779 780/780/780 781/781/781 -f 781/781/781 782/782/782 779/779/779 -f 752/752/752 751/751/751 755/755/755 -f 755/755/755 766/766/766 752/752/752 -f 748/748/748 783/783/783 763/763/763 -f 763/763/763 757/757/757 748/748/748 -f 784/784/784 785/785/785 786/786/786 -f 787/787/787 788/788/788 789/789/789 -f 553/553/553 790/790/790 760/760/760 -f 760/760/760 739/739/739 553/553/553 -f 791/791/791 556/556/556 792/792/792 -f 792/792/792 793/793/793 791/791/791 -f 545/545/545 544/544/544 736/736/736 -f 794/794/794 795/795/795 796/796/796 -f 797/797/797 798/798/798 799/799/799 -f 800/800/800 801/801/801 802/802/802 -f 791/791/791 557/557/557 556/556/556 -f 555/555/555 790/790/790 553/553/553 -f 803/803/803 804/804/804 805/805/805 -f 805/805/805 806/806/806 803/803/803 -f 807/807/807 808/808/808 762/762/762 -f 762/762/762 761/761/761 807/807/807 -f 559/559/559 809/809/809 810/810/810 -f 810/810/810 811/811/811 559/559/559 -f 812/812/812 562/562/562 813/813/813 -f 813/813/813 814/814/814 812/812/812 -f 550/550/550 552/552/552 815/815/815 -f 816/816/816 817/817/817 818/818/818 -f 819/819/819 820/820/820 821/821/821 -f 822/822/822 823/823/823 824/824/824 -f 812/812/812 563/563/563 562/562/562 -f 561/561/561 809/809/809 559/559/559 -f 825/825/825 826/826/826 827/827/827 -f 827/827/827 828/828/828 825/825/825 -f 829/829/829 830/830/830 831/831/831 -f 831/831/831 832/832/832 829/829/829 -f 833/833/833 834/834/834 835/835/835 -f 835/835/835 836/836/836 833/833/833 -f 405/405/405 837/837/837 838/838/838 -f 838/838/838 408/408/408 405/405/405 -f 409/409/409 839/839/839 745/745/745 -f 745/745/745 313/313/313 409/409/409 -f 840/840/840 746/746/746 745/745/745 -f 745/745/745 839/839/839 840/840/840 -f 412/412/412 841/841/841 839/839/839 -f 839/839/839 409/409/409 412/412/412 -f 414/414/414 842/842/842 841/841/841 -f 841/841/841 412/412/412 414/414/414 -f 416/416/416 843/843/843 842/842/842 -f 842/842/842 414/414/414 416/416/416 -f 844/844/844 840/840/840 839/839/839 -f 839/839/839 841/841/841 844/844/844 -f 845/845/845 844/844/844 841/841/841 -f 841/841/841 842/842/842 845/845/845 -f 846/846/846 845/845/845 842/842/842 -f 842/842/842 843/843/843 846/846/846 -f 408/408/408 838/838/838 843/843/843 -f 843/843/843 421/421/421 408/408/408 -f 837/837/837 847/847/847 843/843/843 -f 843/843/843 838/838/838 837/837/837 -f 423/423/423 425/425/425 848/848/848 -f 848/848/848 849/849/849 423/423/423 -f 427/427/427 850/850/850 851/851/851 -f 851/851/851 430/430/430 427/427/427 -f 431/431/431 433/433/433 852/852/852 -f 852/852/852 853/853/853 431/431/431 -f 854/854/854 845/845/845 847/847/847 -f 847/847/847 855/855/855 854/854/854 -f 856/856/856 844/844/844 845/845/845 -f 845/845/845 854/854/854 856/856/856 -f 857/857/857 840/840/840 844/844/844 -f 844/844/844 856/856/856 857/857/857 diff --git a/convex_decomposition/ConvexDecomposition/readme.txt b/convex_decomposition/ConvexDecomposition/readme.txt deleted file mode 100644 index d687f13..0000000 --- a/convex_decomposition/ConvexDecomposition/readme.txt +++ /dev/null @@ -1,75 +0,0 @@ - -ConvexDecomposition library written by John W. Ratcliff - -Usage: Test (options) - -Options: - - -d : How deep to recursively split. Values of 3-7 are reasonable. - -c : Percentage of concavity to keep splitting. 0-20 4324640s reasonable. - -p : Percentage of volume delta to collapse hulls. 0-30 4324544s reasonable. - -v : Maximum number of vertices in the output hull. Default is 32. - -s : Skin Width inflation. Default is 0.0 - -To run the sample provided with defaults: - -DecomposeSample chair.obj - -Will produce 'chair_convex.obj' a Wavefront OBJ file useful for debug visualization. - 'chair.dae' a COLLADA physics representation of the model. - 'chair.xml' an Ageia PhysX NxuStream representation of the model. - - -/*! -** -** Copyright (c) 2007 by John W. Ratcliff mailto:jratcliff@infiniplex.net -** -** Portions of this source has been released with the PhysXViewer application, as well as -** Rocket, CreateDynamics, ODF, and as a number of sample code snippets. -** -** If you find this code useful or you are feeling particularily generous I would -** ask that you please go to http://www.amillionpixels.us and make a donation -** to Troy DeMolay. -** -** DeMolay is a youth group for young men between the ages of 12 and 21. -** It teaches strong moral principles, as well as leadership skills and -** public speaking. The donations page uses the 'pay for pixels' paradigm -** where, in this case, a pixel is only a single penny. Donations can be -** made for as small as $4 or as high as a $100 block. Each person who donates -** will get a link to their own site as well as acknowledgement on the -** donations blog located here http://www.amillionpixels.blogspot.com/ -** -** If you wish to contact me you can use the following methods: -** -** Skype Phone: 636-486-4040 (let it ring a long time while it goes through switches) -** Skype ID: jratcliff63367 -** Yahoo: jratcliff63367 -** AOL: jratcliff1961 -** email: jratcliff@infiniplex.net -** Personal website: http://jratcliffscarab.blogspot.com -** Coding Website: http://codesuppository.blogspot.com -** FundRaising Blog: http://amillionpixels.blogspot.com -** Fundraising site: http://www.amillionpixels.us -** New Temple Site: http://newtemple.blogspot.com -** -** -** The MIT license: -** -** Permission is hereby granted, free of charge, to any person obtaining a copy -** of this software and associated documentation files (the "Software"), to deal -** in the Software without restriction, including without limitation the rights -** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -** copies of the Software, and to permit persons to whom the Software is furnished -** to do so, subject to the following conditions: -** -** The above copyright notice and this permission notice shall be included in all -** copies or substantial portions of the Software. - -** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ diff --git a/convex_decomposition/Makefile b/convex_decomposition/Makefile deleted file mode 100644 index 076c2eb..0000000 --- a/convex_decomposition/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -all: installed - -TARBALL = build/ConvexDecomposition.zip -TARBALL_URL = http://pr.willowgarage.com/downloads/ConvexDecomposition.zip -SOURCE_DIR = build/convex_decomposition -INITIAL_DIR = build/ConvexDecomposition -UNPACK_CMD = unzip -TARBALL_PATCH=convex_decomposition.patch - -include $(shell rospack find mk)/download_unpack_build.mk - -ROOT = $(shell rospack find convex_decomposition)/convex_decomposition - -installed: wiped $(SOURCE_DIR)/unpacked - @echo "making it" - @echo "ROOT is: $(ROOT)" - -mkdir -p $(ROOT) - -mkdir -p $(ROOT)/bin - cd $(SOURCE_DIR) ; make $(ROS_PARALLEL_JOBS); make install - touch installed - -wiped: Makefile - make wipe - touch wiped - -clean: - -cd $(SOURCE_DIR) && make clean - rm -rf $(ROOT) installed - -wipe: clean - rm -rf build - -.PHONY : clean download wipe diff --git a/convex_decomposition/convex_decomposition.patch b/convex_decomposition/convex_decomposition.patch deleted file mode 100644 index db8d786..0000000 --- a/convex_decomposition/convex_decomposition.patch +++ /dev/null @@ -1,429 +0,0 @@ -Index: ConvexDecomposition/vlookup.cpp -=================================================================== ---- ConvexDecomposition/vlookup.cpp (revision 8299) -+++ ConvexDecomposition/vlookup.cpp (working copy) -@@ -164,7 +164,7 @@ - }; - - --template class VertexLess -+template class VertexLess - { - public: - typedef std::vector< Type > VertexVector; -@@ -188,7 +188,7 @@ - static VertexVector *mList; - }; - --template class VertexPool -+template class VertexPool - { - public: - typedef std::set > VertexSet; -@@ -197,7 +197,7 @@ - int GetVertex(const Type& vtx) - { - VertexLess::SetSearch(vtx,&mVtxs); -- VertexSet::iterator found; -+ typename VertexSet::iterator found; - found = mVertSet.find( -1 ); - if ( found != mVertSet.end() ) - { -@@ -254,10 +254,10 @@ - VertexVector mVtxs; // set of vertices. - }; - -+double tmpp[3] = {0,0,0}; -+template<> VertexPosition VertexLess::mFind = tmpp; -+template<> std::vector *VertexLess::mList =0; - --VertexPosition VertexLess::mFind; --std::vector *VertexLess::mList=0; -- - enum RDIFF - { - RD_EQUAL, -@@ -288,6 +288,7 @@ - } - - -+template<> - bool VertexLess::operator()(int v1,int v2) const - { - bool ret = false; -Index: ConvexDecomposition/ConvexDecomposition.cpp -=================================================================== ---- ConvexDecomposition/ConvexDecomposition.cpp (revision 8299) -+++ ConvexDecomposition/ConvexDecomposition.cpp (working copy) -@@ -66,7 +66,7 @@ - #include "cd_vector.h" - #include "cd_hull.h" - #include "bestfit.h" --#include "PlaneTri.h" -+#include "planetri.h" - #include "vlookup.h" - #include "splitplane.h" - #include "meshvolume.h" -@@ -760,3 +760,3 @@ -- assert( fcount >= 3 && fcount <= 4); -- assert( bcount >= 3 && bcount <= 4); -- -+ if ( fcount >= 3 && fcount <= 4) -+ if ( bcount >= 3 && bcount <= 4) -+ { -@@ -777,1 +777,1 @@ -- -+ } -Index: ConvexDecomposition/splitplane.cpp -=================================================================== ---- ConvexDecomposition/splitplane.cpp (revision 8299) -+++ ConvexDecomposition/splitplane.cpp (working copy) -@@ -67,7 +67,7 @@ - #include "cd_hull.h" - #include "cd_wavefront.h" - #include "bestfit.h" --#include "PlaneTri.h" -+#include "planetri.h" - #include "vlookup.h" - #include "meshvolume.h" - #include "bestfitobb.h" -Index: ConvexDecomposition/cd_vector.h -=================================================================== ---- ConvexDecomposition/cd_vector.h (revision 8299) -+++ ConvexDecomposition/cd_vector.h (working copy) -@@ -309,12 +309,12 @@ - - Type FastMagnitude(void) const - { -- return Type(fast_sqrt(x * x + y * y + z * z)); -+ return Type(sqrt(x * x + y * y + z * z)); - }; - - Type FasterMagnitude(void) const - { -- return Type(faster_sqrt(x * x + y * y + z * z)); -+ return Type(sqrt(x * x + y * y + z * z)); - }; - - void Lerp(const Vector3d& from,const Vector3d& to,double slerp) -@@ -436,13 +436,13 @@ - - Type FastLength(void) const // length of vector. - { -- return Type(fast_sqrt( x*x + y*y + z*z )); -+ return Type(sqrt( x*x + y*y + z*z )); - }; - - - Type FasterLength(void) const // length of vector. - { -- return Type(faster_sqrt( x*x + y*y + z*z )); -+ return Type(sqrt( x*x + y*y + z*z )); - }; - - Type Length2(void) const // squared distance, prior to square root. -@@ -518,7 +518,7 @@ - - inline double FastNormalize(void) // normalize to a unit vector, returns distance. - { -- double d = fast_sqrt( static_cast< double >( x*x + y*y + z*z ) ); -+ double d = sqrt( static_cast< double >( x*x + y*y + z*z ) ); - if ( d > 0 ) - { - double r = 1.0f / d; -@@ -535,7 +535,7 @@ - - inline double FasterNormalize(void) // normalize to a unit vector, returns distance. - { -- double d = faster_sqrt( static_cast< double >( x*x + y*y + z*z ) ); -+ double d = sqrt( static_cast< double >( x*x + y*y + z*z ) ); - if ( d > 0 ) - { - double r = 1.0f / d; -@@ -1029,7 +1029,8 @@ - - void Zero(void) - { -- x = y = z = 0; -+ x = 0; -+ y = 0; - }; - - Vector2d negative(void) const -@@ -1047,12 +1048,12 @@ - - Type fastmagnitude(void) const - { -- return (Type) fast_sqrt(x * x + y * y ); -+ return (Type) sqrt(x * x + y * y ); - } - - Type fastermagnitude(void) const - { -- return (Type) faster_sqrt( x * x + y * y ); -+ return (Type) sqrt( x * x + y * y ); - } - - void Reflection(Vector2d &a,Vector2d &b); // compute reflection vector. -@@ -1064,12 +1065,12 @@ - - Type FastLength(void) const // length of vector. - { -- return Type(fast_sqrt( x*x + y*y )); -+ return Type(sqrt( x*x + y*y )); - }; - - Type FasterLength(void) const // length of vector. - { -- return Type(faster_sqrt( x*x + y*y )); -+ return Type(sqrt( x*x + y*y )); - }; - - Type Length2(void) // squared distance, prior to square root. -@@ -1090,7 +1091,7 @@ - Type dx = a.x - x; - Type dy = a.y - y; - Type d = dx*dx+dy*dy; -- return fast_sqrt(d); -+ return sqrt(d); - }; - - Type FasterDistance(const Vector2d &a) const // distance between two points. -@@ -1098,7 +1099,7 @@ - Type dx = a.x - x; - Type dy = a.y - y; - Type d = dx*dx+dy*dy; -- return faster_sqrt(d); -+ return sqrt(d); - }; - - Type Distance2(Vector2d &a) // squared distance. -Index: ConvexDecomposition/float_math.cpp -=================================================================== ---- ConvexDecomposition/float_math.cpp (revision 8299) -+++ ConvexDecomposition/float_math.cpp (working copy) -@@ -212,8 +212,14 @@ - matrix[1*4+2] = 2 * ( yz + wx ); - matrix[2*4+2] = 1 - 2 * ( xx + yy ); - -- matrix[3*4+0] =(double) matrix[3*4+1] = matrix[3*4+2] = 0.0f; -- matrix[0*4+3] =(double) matrix[1*4+3] = matrix[2*4+3] = 0.0f; -+ matrix[3*4+0] = 0.0f; -+ matrix[3*4+1] = 0.0f; -+ matrix[3*4+2] = 0.0f; -+ -+ matrix[0*4+3] = 0.0f; -+ matrix[1*4+3] = 0.0f; -+ matrix[2*4+3] = 0.0f; -+ - matrix[3*4+3] =(double) 1.0f; - - } -Index: ConvexDecomposition/cd_wavefront.cpp -=================================================================== ---- ConvexDecomposition/cd_wavefront.cpp (revision 8299) -+++ ConvexDecomposition/cd_wavefront.cpp (working copy) -@@ -672,7 +672,7 @@ - const char *foo = argv[0]; - if ( *foo != '#' ) - { -- if ( stricmp(argv[0],"v") == 0 && argc == 4 ) -+ if ( strcmp(argv[0],"v") == 0 && argc == 4 ) - { - double vx = (double) atof( argv[1] ); - double vy = (double) atof( argv[2] ); -@@ -681,14 +681,14 @@ - mVerts.push_back(vy); - mVerts.push_back(vz); - } -- else if ( stricmp(argv[0],"vt") == 0 && argc == 3 ) -+ else if ( strcmp(argv[0],"vt") == 0 && argc == 3 ) - { - double tx = (double) atof( argv[1] ); - double ty = (double) atof( argv[2] ); - mTexels.push_back(tx); - mTexels.push_back(ty); - } -- else if ( stricmp(argv[0],"vn") == 0 && argc == 4 ) -+ else if ( strcmp(argv[0],"vn") == 0 && argc == 4 ) - { - double normalx = (double) atof(argv[1]); - double normaly = (double) atof(argv[2]); -@@ -697,7 +697,7 @@ - mNormals.push_back(normaly); - mNormals.push_back(normalz); - } -- else if ( stricmp(argv[0],"f") == 0 && argc >= 4 ) -+ else if ( strcmp(argv[0],"f") == 0 && argc >= 4 ) - { - GeometryVertex v[32]; - -Index: Makefile -=================================================================== ---- Makefile (revision 0) -+++ Makefile (revision 8581) -@@ -0,0 +1,93 @@ -+ -+ -+OBJS = DecomposeSample.o \ -+ ConvexDecomposition/bestfit.o ConvexDecomposition/float_math.o \ -+ ConvexDecomposition/bestfitobb.o ConvexDecomposition/meshvolume.o \ -+ ConvexDecomposition/cd_hull.o ConvexDecomposition/planetri.o \ -+ ConvexDecomposition/cd_wavefront.o ConvexDecomposition/raytri.o \ -+ ConvexDecomposition/concavity.o ConvexDecomposition/splitplane.o \ -+ ConvexDecomposition/ConvexDecomposition.o ConvexDecomposition/triangulate.o \ -+ ConvexDecomposition/fitsphere.o ConvexDecomposition/vlookup.o -+ -+HEADERS = \ -+ ConvexDecomposition/bestfit.h \ -+ ConvexDecomposition/bestfitobb.h \ -+ ConvexDecomposition/cd_hull.h \ -+ ConvexDecomposition/cd_vector.h \ -+ ConvexDecomposition/cd_wavefront.h \ -+ ConvexDecomposition/concavity.h \ -+ ConvexDecomposition/ConvexDecomposition.h \ -+ ConvexDecomposition/fitsphere.h \ -+ ConvexDecomposition/float_math.h \ -+ ConvexDecomposition/meshvolume.h \ -+ ConvexDecomposition/planetri.h \ -+ ConvexDecomposition/raytri.h \ -+ ConvexDecomposition/splitplane.h \ -+ ConvexDecomposition/triangulate.h \ -+ ConvexDecomposition/vlookup.h -+ -+CC = g++ -+ -+DEBUG = -ggdb -+ -+CFLAGS = -IConvexDecomposition -Wall -c $(DEBUG) -+ -+LFLAGS = $(DEBUG) -+ -+convex_decomposition: $(OBJS) -+ $(CC) $(LFLAGS) $(OBJS) -o convex_decomposition -+ -+DecomposeSample.o: DecomposeSample.cpp -+ $(CC) $(CFLAGS) DecomposeSample.cpp -o $@ -+ -+ConvexDecomposition/bestfit.o: ConvexDecomposition/bestfit.cpp -+ $(CC) $(CFLAGS) ConvexDecomposition/bestfit.cpp -o $@ -+ -+ConvexDecomposition/bestfitobb.o: ConvexDecomposition/bestfitobb.cpp -+ $(CC) $(CFLAGS) ConvexDecomposition/bestfitobb.cpp -o $@ -+ -+ConvexDecomposition/cd_hull.o: ConvexDecomposition/cd_hull.cpp -+ $(CC) $(CFLAGS) ConvexDecomposition/cd_hull.cpp -o $@ -+ -+ConvexDecomposition/cd_wavefront.o: ConvexDecomposition/cd_wavefront.cpp -+ $(CC) $(CFLAGS) ConvexDecomposition/cd_wavefront.cpp -o $@ -+ -+ConvexDecomposition/concavity.o: ConvexDecomposition/concavity.cpp -+ $(CC) $(CFLAGS) ConvexDecomposition/concavity.cpp -o $@ -+ -+ConvexDecomposition/ConvexDecomposition.o: ConvexDecomposition/ConvexDecomposition.cpp -+ $(CC) $(CFLAGS) ConvexDecomposition/ConvexDecomposition.cpp -o $@ -+ -+ConvexDecomposition/fitsphere.o: ConvexDecomposition/fitsphere.cpp -+ $(CC) $(CFLAGS) ConvexDecomposition/fitsphere.cpp -o $@ -+ -+ConvexDecomposition/float_math.o: ConvexDecomposition/float_math.cpp -+ $(CC) $(CFLAGS) ConvexDecomposition/float_math.cpp -o $@ -+ -+ConvexDecomposition/meshvolume.o: ConvexDecomposition/meshvolume.cpp -+ $(CC) $(CFLAGS) ConvexDecomposition/meshvolume.cpp -o $@ -+ -+ConvexDecomposition/planetri.o: ConvexDecomposition/planetri.cpp -+ $(CC) $(CFLAGS) ConvexDecomposition/planetri.cpp -o $@ -+ -+ConvexDecomposition/raytri.o: ConvexDecomposition/raytri.cpp -+ $(CC) $(CFLAGS) ConvexDecomposition/raytri.cpp -o $@ -+ -+ConvexDecomposition/splitplane.o: ConvexDecomposition/splitplane.cpp -+ $(CC) $(CFLAGS) ConvexDecomposition/splitplane.cpp -o $@ -+ -+ConvexDecomposition/triangulate.o: ConvexDecomposition/triangulate.cpp -+ $(CC) $(CFLAGS) ConvexDecomposition/triangulate.cpp -o $@ -+ -+ConvexDecomposition/vlookup.o: ConvexDecomposition/vlookup.cpp ConvexDecomposition/vlookup.cpp -+ $(CC) $(CFLAGS) ConvexDecomposition/vlookup.cpp -o $@ -+ -+install: -+ cp convex_decomposition ../../convex_decomposition/bin/ -+ -+clean: -+ \rm *.o */*.o convex_decomposition -+ -+tar: -+ tar cfv ConvexDecomposition.tar DecomposeSample.cpp convex_decomposition Makefile \ -+ ConvexDecomposition -Index: DecomposeSample.cpp -=================================================================== ---- DecomposeSample.cpp (revision 8299) -+++ DecomposeSample.cpp (working copy) -@@ -6,7 +6,7 @@ - - #include - --#include "./ConvexDecomposition/convexdecomposition.h" -+#include "./ConvexDecomposition/ConvexDecomposition.h" - #include "./ConvexDecomposition/cd_wavefront.h" - - using namespace ConvexDecomposition; -@@ -227,7 +227,7 @@ - - if ( fph ) - { -- printf("Saving convex decomposition of %d hulls to COLLADA file '%s'\r\n", mHulls.size(), scratch ); -+ printf("Saving convex decomposition of %d hulls to COLLADA file '%s'\r\n", (int)mHulls.size(), scratch ); - - fprintf(fph,"\r\n"); - fprintf(fph,"\r\n"); -@@ -537,7 +537,7 @@ - }; - - --void main(int argc,const char **argv) -+int main(int argc,const char **argv) - { - if ( argc < 2 ) - { -Index: DecomposeSample.cpp -=================================================================== ---- DecomposeSample.cpp (revision 8299) -+++ DecomposeSample.cpp (working copy) -@@ -67,3 +67,3 @@ - strcpy(mBaseName,fname); -- char *dot = strstr(mBaseName,"."); -+ char *dot = strstr(mBaseName,".obj"); - if ( dot ) *dot = 0; -Index: ConvexDecomposition/cd_wavefront.cpp -=================================================================== ---- ConvexDecomposition/cd_wavefront.cpp (revision 8299) -+++ ConvexDecomposition/cd_wavefront.cpp (working copy) -@@ -573,6 +573,7 @@ - FloatVector mNormals; - - GeometryInterface *mCallback; -+ friend class WavefrontObj; - }; - - -@@ -839,7 +840,17 @@ - memcpy(mIndices, &indices[0], sizeof(int)*mTriCount*3); - ret = mTriCount; - } -- -+ else if( obj.mVerts.size() > 0 ) { -+ // take consecutive vertices -+ mVertexCount = obj.mVerts.size()/3; -+ mVertices = new double[mVertexCount*3]; -+ memcpy( mVertices, &obj.mVerts[0], sizeof(double)*mVertexCount*3 ); -+ mTriCount = mVertexCount/3; -+ mIndices = new int[mTriCount*3*sizeof(int)]; -+ for(int i = 0; i < mVertexCount; ++i) -+ mIndices[i] = i; -+ ret = mTriCount; -+ } - - return ret; - } diff --git a/convex_decomposition/manifest.xml b/convex_decomposition/manifest.xml deleted file mode 100644 index 075eca9..0000000 --- a/convex_decomposition/manifest.xml +++ /dev/null @@ -1,29 +0,0 @@ - - - -

-convex_decomposition contains the Convex Mesh Generation Library, by John Ratcliff. This library is used to auto-generate convex decomposed meshes for -collision and visualization of robot links. -

-

-We are using the latest and the only version available. We plan on deprecating this package -once we find a better alternative. -

-

-The Convex Mesh Generation Library is not provided by -any of the major OS package managers, and this version provided -here contains patches required for compilation. -These patches have not been submitted back as there -appears to be no available revision control. -

- -
-John Ratcliff -MIT - -http://www.amillionpixels.us/ConvexDecomposition.zip - - - - -
diff --git a/ivcon/CMakeLists.txt b/ivcon/CMakeLists.txt deleted file mode 100644 index 6cc84f8..0000000 --- a/ivcon/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -cmake_minimum_required(VERSION 2.4.6) -include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake) -rosbuild_init() - -#uncomment for profiling -set(ROS_LINK_FLAGS "-lm" ${ROS_LINK_FLAGS}) - -rosbuild_add_executable(bin/ivcon src/ivcon.c) -target_link_libraries(bin/ivcon m) - diff --git a/ivcon/Makefile b/ivcon/Makefile deleted file mode 100644 index bbd3fc6..0000000 --- a/ivcon/Makefile +++ /dev/null @@ -1 +0,0 @@ -include $(shell rospack find mk)/cmake.mk diff --git a/ivcon/manifest.xml b/ivcon/manifest.xml deleted file mode 100644 index 172cf82..0000000 --- a/ivcon/manifest.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - -Mesh Conversion Utility - -Used to generate '.iv' files from '.stl' files. This package has not -been changed since 2001 and appears to be very stable. We plan on -keeping this package in this revision for mesh conversions. This -package is only available as a single source file for download. There -are no local modifications to this package. - - -John Burkardt -GPL - -https://sourceforge.net/projects/ivcon/ - - - - - - - diff --git a/ivcon/src/ivcon.c b/ivcon/src/ivcon.c deleted file mode 100644 index 5539860..0000000 --- a/ivcon/src/ivcon.c +++ /dev/null @@ -1,16707 +0,0 @@ -/* ivcon.c 24 May 2001 */ - -/* - Purpose: - - IVCON converts various 3D graphics files. - - Acknowledgements: - - Coding, comments, and advice were supplied by a number of collaborators. - - John F Flanagan made some corrections to the 3D Studio Max routines. - - Zik Saleeba (zik@zikzak.net) enhanced the DXF routines, and added the - Golgotha GMOD routines. - - Thanks to Susan M. Fisher, University of North Carolina, - Department of Computer Science, for pointing out a coding error - in FACE_NULL_DELETE that was overwriting all the data! - - Modified: - - 04 July 2000 - - Author: - - John Burkardt -*/ - -#include -#include -#include -#include -#include - -#define FALSE 0 -#define TRUE 1 - -#define ERROR 1 -#define G1_SECTION_MODEL_QUADS 18 -#define G1_SECTION_MODEL_TEXTURE_NAMES 19 -#define G1_SECTION_MODEL_VERT_ANIMATION 20 -#define GMOD_MAX_SECTIONS 32 -#define GMOD_UNUSED_VERTEX 65535 -#define PI 3.141592653589793238462643 -#define SUCCESS 0 - -#define DEG_TO_RAD ( PI / 180.0 ) -#define RAD_TO_DEG ( 180.0 / PI ) - -/******************************************************************************/ - -/* GLOBAL DATA */ - -/******************************************************************************/ - -/* - BACKGROUND_RGB[3], the background color. - - BYTE_SWAP, byte swapping option. - - COR3[3][COR3_MAX], the coordinates of nodes. - - COR3_MATERIAL[COR3_MAX], the index of the material of each node. - - COR3_MAX, the maximum number of points. - - COR3_NORMAL[3][COR3_MAX], normal vectors associated with nodes. - - COR3_NUM, the number of points. - - COR3_RGB[3][COR3_MAX], RGB colors associated with nodes. - - COR3_TEX_UV[2][COR3_MAX], texture coordinates associated with nodes. - - FACE[ORDER_MAX][FACE_MAX] contains the index of the I-th node making up face J. - - FACE_AREA(FACE_MAX), the area of each face. - - FACE_MATERIAL[FACE_MAX]; the material of each face. - - FACE_MAX, the maximum number of faces. - - FACE_NORMAL[3][FACE_MAX], the face normal vectors. - - FACE_NUM, the number of faces. - - FACE_ORDER[FACE_MAX], the number of vertices per face. - - FACE_TEX_UV[2][FACE_MAX], texture coordinates associated with faces. - - LINE_DEX[LINES_MAX], node indices, denoting polylines, each terminated by -1. - - LINE_MATERIAL[LINES_MAX], index into RGBCOLOR for line color. - - LINES_MAX, the maximum number of line definition items. - - LINE_NUM, the number of line definition items. - - LINE_PRUNE, pruning option ( 0 = no pruning, nonzero = pruning). - - MATERIAL_MAX, the maximum number of materials. - - MATERIAL_NUM, the number of materials. - - ORDER_MAX, the maximum number of vertices per face. - - TEXTURE_MAX, the maximum number of textures. - - TEXTURE_NAME[TEXTURE_MAX][LINE_MAX_LEN], ... - - TEXTURE_NUM, the number of textures. - - TRANSFORM_MATRIX[4][4], the current transformation matrix. - - VERTEX_MATERIAL[ORDER_MAX][FACE_MAX]; the material of vertices of faces. - - VERTEX_NORMAL[3][ORDER_MAX][FACE_MAX], normals at vertices of faces. - - VERTEX_RGB[3][ORDER_MAX][FACE_MAX], colors of vertices of faces. - - VERTEX_TEX_UV[2][ORDER_MAX][FACE_MAX], texture coordinates of vertices of faces. -*/ - -#define COLOR_MAX 1000 -#define COR3_MAX 200000 -#define FACE_MAX 200000 -#define LINE_MAX_LEN 256 -#define LEVEL_MAX 10 -#define LINES_MAX 100000 -#define MATERIAL_MAX 100 -#define ORDER_MAX 10 -#define TEXTURE_MAX 100 - -char anim_name[LINE_MAX_LEN]; -float background_rgb[3]; -int bad_num; -int byte_swap; -int bytes_num; -int color_num; -int comment_num; - -float cor3[3][COR3_MAX]; -int cor3_material[COR3_MAX]; -float cor3_normal[3][COR3_MAX]; -int cor3_num; -float cor3_tex_uv[3][COR3_MAX]; - -int debug; - -int dup_num; - -int face[ORDER_MAX][FACE_MAX]; -float face_area[FACE_MAX]; -int face_flags[FACE_MAX]; -int face_material[FACE_MAX]; -float face_normal[3][FACE_MAX]; -int face_num; -int face_object[FACE_MAX]; -int face_order[FACE_MAX]; -int face_smooth[FACE_MAX]; -float face_tex_uv[2][FACE_MAX]; - -char filein_name[1024]; -char fileout_name[1024]; - -int group_num; - -int i; -char input[LINE_MAX_LEN]; -int k; -char level_name[LEVEL_MAX][LINE_MAX_LEN]; - -int line_dex[LINES_MAX]; -int line_material[LINES_MAX]; -int line_num; -int line_prune; - -int list[COR3_MAX]; - -char material_binding[80]; -char material_name[MATERIAL_MAX][LINE_MAX_LEN]; -int material_num; -float material_rgba[4][MATERIAL_MAX]; - -char mat_name[81]; -int max_order2; - -char normal_binding[80]; -float normal_temp[3][ORDER_MAX*FACE_MAX]; - -char object_name[81]; -int object_num; - -float origin[3]; -float pivot[3]; -float rgbcolor[3][COLOR_MAX]; -char temp_name[81]; - -int text_num; - -char texture_binding[80]; -char texture_name[TEXTURE_MAX][LINE_MAX_LEN]; -int texture_num; -float texture_temp[2][ORDER_MAX*FACE_MAX]; - -float transform_matrix[4][4]; - -int vertex_material[ORDER_MAX][FACE_MAX]; -float vertex_normal[3][ORDER_MAX][FACE_MAX]; -float vertex_rgb[3][ORDER_MAX][FACE_MAX]; -float vertex_tex_uv[2][ORDER_MAX][FACE_MAX]; - -/******************************************************************************/ - -/* FUNCTION PROTOTYPES */ - -/******************************************************************************/ - -int main ( int argc, char **argv ); -int ase_read ( FILE *filein ); -int ase_write ( FILE *fileout ); -int byu_read ( FILE *filein ); -int byu_write ( FILE *fileout ); -int char_index_last ( char* string, char c ); -int char_pad ( int *char_index, int *null_index, char *string, - int STRING_MAX ); -char char_read ( FILE *filein ); -int char_write ( FILE *fileout, char c ); -int command_line ( char **argv ); -void cor3_normal_set ( void ); -void cor3_range ( void ); -void data_check ( void ); -void data_init ( void ); -int data_read ( void ); -void data_report ( void ); -int data_write ( void ); -int dxf_read ( FILE *filein ); -int dxf_write ( FILE *fileout ); -void edge_null_delete ( void ); -void face_area_set ( void ); -void face_normal_ave ( void ); -void face_null_delete ( void ); -int face_print ( int iface ); -void face_reverse_order ( void ); -int face_subset ( void ); -void face_to_line ( void ); -void face_to_vertex_material ( void ); -char *file_ext ( char *file_name ); -float float_read ( FILE *filein ); -float float_reverse_bytes ( float x ); -int float_write ( FILE *fileout, float float_val ); -int gmod_arch_check ( void ); -int gmod_read ( FILE *filein ); -float gmod_read_float ( FILE *filein ); -unsigned short gmod_read_w16 ( FILE *filein ); -unsigned long gmod_read_w32 ( FILE *filein ); -int gmod_write ( FILE *fileout ); -void gmod_write_float ( float Val, FILE *fileout ); -void gmod_write_w16 ( unsigned short Val, FILE *fileout ); -void gmod_write_w32 ( unsigned long Val, FILE *fileout ); -void hello ( void ); -void help ( void ); -int hrc_read ( FILE *filein ); -int hrc_write ( FILE *fileout ); -void init_program_data ( void ); -int interact ( void ); -int iv_read ( FILE *filein ); -int iv_write ( FILE *fileout ); -int ivec_max ( int n, int *a ); -int leqi ( char* string1, char* string2 ); -long int long_int_read ( FILE *filein ); -int long_int_write ( FILE *fileout, long int int_val ); -void news ( void ); -void node_to_vertex_material ( void ); -int obj_read ( FILE *filein ); -int obj_write ( FILE *fileout ); -int pov_write ( FILE *fileout ); -int rcol_find ( float a[][COR3_MAX], int m, int n, float r[] ); -float rgb_to_hue ( float r, float g, float b ); -short int short_int_read ( FILE *filein ); -int short_int_write ( FILE *fileout, short int int_val ); -int smf_read ( FILE *filein ); -int smf_write ( FILE *fileout ); -int stla_read ( FILE *filein ); -int stla_write ( FILE *fileout ); -int stlb_read ( FILE *filein ); -int stlb_write ( FILE *fileout ); -void tds_pre_process ( void ); -int tds_read ( FILE *filein ); -unsigned long int tds_read_ambient_section ( FILE *filein ); -unsigned long int tds_read_background_section ( FILE *filein ); -unsigned long int tds_read_boolean ( unsigned char *boolean, FILE *filein ); -unsigned long int tds_read_camera_section ( FILE *filein ); -unsigned long int tds_read_edit_section ( FILE *filein, int *views_read ); -unsigned long int tds_read_keyframe_section ( FILE *filein, int *views_read ); -unsigned long int tds_read_keyframe_objdes_section ( FILE *filein ); -unsigned long int tds_read_light_section ( FILE *filein ); -unsigned long int tds_read_u_long_int ( FILE *filein ); -int tds_read_long_name ( FILE *filein ); -unsigned long int tds_read_matdef_section ( FILE *filein ); -unsigned long int tds_read_material_section ( FILE *filein ); -int tds_read_name ( FILE *filein ); -unsigned long int tds_read_obj_section ( FILE *filein ); -unsigned long int tds_read_object_section ( FILE *filein ); -unsigned long int tds_read_tex_verts_section ( FILE *filein ); -unsigned long int tds_read_texmap_section ( FILE *filein ); -unsigned short int tds_read_u_short_int ( FILE *filein ); -unsigned long int tds_read_spot_section ( FILE *filein ); -unsigned long int tds_read_unknown_section ( FILE *filein ); -unsigned long int tds_read_view_section ( FILE *filein, int *views_read ); -unsigned long int tds_read_vp_section ( FILE *filein, int *views_read ); -int tds_write ( FILE *fileout ); -int tds_write_string ( FILE *fileout, char *string ); -int tds_write_u_short_int ( FILE *fileout, - unsigned short int int_val ); -int tec_write ( FILE *fileout ); -void tmat_init ( float a[4][4] ); -void tmat_mxm ( float a[4][4], float b[4][4], float c[4][4] ); -void tmat_mxp ( float a[4][4], float x[4], float y[4] ); -void tmat_mxp2 ( float a[4][4], float x[][3], float y[][3], int n ); -void tmat_mxv ( float a[4][4], float x[4], float y[4] ); -void tmat_rot_axis ( float a[4][4], float b[4][4], float angle, - char axis ); -void tmat_rot_vector ( float a[4][4], float b[4][4], float angle, - float v1, float v2, float v3 ); -void tmat_scale ( float a[4][4], float b[4][4], float sx, float sy, - float sz ); -void tmat_shear ( float a[4][4], float b[4][4], char *axis, - float s ); -void tmat_trans ( float a[4][4], float b[4][4], float x, float y, - float z ); -int tria_read ( FILE *filein ); -int tria_write ( FILE *fileout ); -int trib_read ( FILE *filein ); -int trib_write ( FILE *fileout ); -int txt_write ( FILE *fileout ); -int ucd_write ( FILE *fileout ); -void vertex_normal_set ( void ); -void vertex_to_face_material ( void ); -void vertex_to_node_material ( void ); -int vla_read ( FILE *filein ); -int vla_write ( FILE *fileout ); -int wrl_write ( FILE *filout ); -int xgl_write ( FILE *fileout ); - -/******************************************************************************/ - -int main ( int argc, char **argv ) - -/******************************************************************************/ - -/* - Purpose: - - MAIN is the main program for converting graphics files. - - Modified: - - 26 May 1999 - - Author: - - John Burkardt -*/ -{ - int result; -/* - Initialize the program data. -*/ - init_program_data ( ); -/* - If there are at least two command line arguments, call COMMAND_LINE. - Otherwise call INTERACT and get information from the user. -*/ - if ( argc >= 2 ) { - result = command_line ( argv ); - } - else { - result = interact ( ); - } - - return result; -} -/******************************************************************************/ - -int ase_read ( FILE *filein ) - -/******************************************************************************/ - -/* - Purpose: - - ASE_READ reads an AutoCAD ASE file. - - Modified: - - 22 May 1999 - - Author: - - John Burkardt -*/ -{ - float bval; - int count; - float gval; - int i; - int iface; - int ivert; - int iword; - int level; - char *next; - int nlbrack; - int nrbrack; - int cor3_num_old; - int face_num_old; - float rval; - float temp; - int width; - char word[LINE_MAX_LEN]; - char word1[LINE_MAX_LEN]; - char word2[LINE_MAX_LEN]; - char wordm1[LINE_MAX_LEN]; - float x; - float y; - float z; - - level = 0; - strcpy ( level_name[0], "Top" ); - cor3_num_old = cor3_num; - face_num_old = face_num; - nlbrack = 0; - nrbrack = 0; - - strcpy ( word, " " ); - strcpy ( wordm1, " " ); -/* - Read a line of text from the file. -*/ - - for ( ;; ) { - - if ( fgets ( input, LINE_MAX_LEN, filein ) == NULL ) { - break; - } - - text_num = text_num + 1; - next = input; - iword = 0; -/* - Read the next word from the line. -*/ - for ( ;; ) { - - strcpy ( wordm1, word ); - strcpy ( word, " " ); - - count = sscanf ( next, "%s%n", word, &width ); - next = next + width; - - if ( count <= 0 ) { - break; - } - - iword = iword + 1; - - if ( iword == 1 ) { - strcpy ( word1, word ); - } -/* - In case the new word is a bracket, update the bracket count. -*/ - if ( strcmp ( word, "{" ) == 0 ) { - - nlbrack = nlbrack + 1; - level = nlbrack - nrbrack; - strcpy ( level_name[level], wordm1 ); - } - else if ( strcmp ( word, "}" ) == 0 ) { - - nrbrack = nrbrack + 1; - - if ( nlbrack < nrbrack ) { - - printf ( "\n" ); - printf ( "ASE_READ - Fatal error!\n" ); - printf ( " Extraneous right bracket on line %d\n", text_num ); - printf ( " Currently processing field:\n" ); - printf ( "%s\n", level_name[level] ); - return ERROR; - } - - } -/* - *3DSMAX_ASCIIEXPORT 200 -*/ - if ( strcmp ( word1, "*3DSMAX_ASCIIEXPORT" ) == 0 ) { - break; - } -/* - *COMMENT -*/ - else if ( strcmp ( word1, "*COMMENT" ) == 0 ) { - break; - } -/* - *GEOMOBJECT -*/ - else if ( strcmp ( level_name[level], "*GEOMOBJECT" ) == 0 ) { - - if ( strcmp ( word, "{" ) == 0 ) { - continue; - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - continue; - } -/* - Why don't you read and save this name? -*/ - else if ( strcmp ( word, "*NODE_NAME" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*NODE_TM" ) == 0 ) { - continue; - } - else if ( strcmp ( word, "*MESH" ) == 0 ) { - continue; - } - else if ( strcmp ( word, "*PROP_CASTSHADOW" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*PROP_MOTIONBLUR" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*PROP_RECVSHADOW" ) == 0 ) { - break; - } - else { - bad_num = bad_num + 1; - printf ( "Bad data in GEOMOBJECT, line %d\n", text_num ); - break; - } - } -/* - *MESH -*/ - else if ( strcmp ( level_name[level], "*MESH" ) == 0 ) { - - if ( strcmp ( word, "{" ) == 0 ) { - continue; - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - continue; - } - else if ( strcmp ( word, "*MESH_CFACELIST" ) == 0 ) { - continue; - } - else if ( strcmp ( word, "*MESH_CVERTLIST" ) == 0 ) { - continue; - } - else if ( strcmp ( word, "*MESH_FACE_LIST" ) == 0 ) { - continue; - } - else if ( strcmp ( word, "*MESH_NORMALS" ) == 0 ) { - continue; - } - else if ( strcmp ( word, "*MESH_NUMCVERTEX" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*MESH_NUMCVFACES" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*MESH_NUMFACES" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*MESH_NUMTVERTEX" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*MESH_NUMTVFACES" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*MESH_NUMVERTEX" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*MESH_TFACELIST" ) == 0 ) { - continue; - } - else if ( strcmp ( word, "*MESH_TVERTLIST" ) == 0 ) { - continue; - } - else if ( strcmp ( word, "*MESH_VERTEX_LIST" ) == 0 ) { - continue; - } - else if ( strcmp ( word, "*TIMEVALUE" ) == 0 ) { - break; - } - else { - bad_num = bad_num + 1; - printf ( "Bad data in MESH, line %d\n", text_num ); - break; - } - } -/* - *MESH_CFACELIST -*/ - else if ( strcmp ( level_name[level], "*MESH_CFACELIST" ) == 0 ) { - - if ( strcmp ( word, "{" ) == 0 ) { - continue; - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - continue; - } - else if ( strcmp ( word, "*MESH_CFACE" ) == 0 ) { - break; - } - else { - bad_num = bad_num + 1; - printf ( "Bad data in MESH_CFACE, line %d\n", text_num ); - break; - } - } -/* - *MESH_CVERTLIST - - Mesh vertex indices must be incremented by COR3_NUM_OLD before being stored - in the internal array. -*/ - else if ( strcmp ( level_name[level], "*MESH_CVERTLIST" ) == 0 ) { - - if ( strcmp ( word, "{" ) == 0 ) { - continue; - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - continue; - } - else if ( strcmp ( word, "*MESH_VERTCOL" ) == 0 ) { - - count = sscanf ( next, "%d%n", &i, &width ); - next = next + width; - - i = i + cor3_num_old; - - count = sscanf ( next, "%f%n", &rval, &width ); - next = next + width; - - count = sscanf ( next, "%f%n", &gval, &width ); - next = next + width; - - count = sscanf ( next, "%f%n", &bval, &width ); - next = next + width; - - if ( material_num < MATERIAL_MAX ) { - material_rgba[0][material_num] = rval; - material_rgba[1][material_num] = gval; - material_rgba[2][material_num] = bval; - material_rgba[3][material_num] = 1.0; - } - - material_num = material_num + 1; - cor3_material[i] = material_num; - } - else { - bad_num = bad_num + 1; - printf ( "\n" ); - printf ( "ASE_READ - Warning!\n" ); - printf ( " Bad data in MESH_CVERTLIST, line %d\n", text_num ); - break; - } - - } -/* - *MESH_FACE_LIST - This coding assumes a face is always triangular or quadrilateral. -*/ - else if ( strcmp ( level_name[level], "*MESH_FACE_LIST" ) == 0 ) { - - if ( strcmp ( word, "{" ) == 0 ) { - continue; - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - continue; - } - else if ( strcmp ( word, "*MESH_FACE" ) == 0 ) { - - if ( face_num < FACE_MAX ) { - - face_material[face_num] = 0; - face_order[face_num] = 0; - - count = sscanf ( next, "%d%n", &i, &width ); - next = next + width; - - count = sscanf ( next, "%s%n", word2, &width ); - next = next + width; - count = sscanf ( next, "%s%n", word2, &width ); - next = next + width; - - count = sscanf ( next, "%d%n", &i, &width ); - next = next + width; - face[0][face_num] = i + cor3_num_old; - face_order[face_num] = face_order[face_num] + 1; - - count = sscanf ( next, "%s%n", word2, &width ); - next = next + width; - - count = sscanf ( next, "%d%n", &i, &width ); - next = next + width; - face[1][face_num] = i + cor3_num_old; - face_order[face_num] = face_order[face_num] + 1; - - count = sscanf ( next, "%s%n", word2, &width ); - next = next + width; - - count = sscanf ( next, "%d%n", &i, &width ); - next = next + width; - face[2][face_num] = i + cor3_num_old; - face_order[face_num] = face_order[face_num] + 1; - - count = sscanf ( next, "%s%n", word2, &width ); - next = next + width; - - if ( strcmp ( word2, "D:" ) == 0 ) { - count = sscanf ( next, "%d%n", &i, &width ); - next = next + width; - face[3][face_num] = i + cor3_num_old; - face_order[face_num] = face_order[face_num] + 1; - } - } - - face_num = face_num + 1; - - break; - - } - else { - bad_num = bad_num + 1; - printf ( "Bad data in MESH_FACE_LIST, line %d\n", text_num ); - break; - } - } -/* - *MESH_NORMALS -*/ - else if ( strcmp ( level_name[level], "*MESH_NORMALS" ) == 0 ) { - - if ( strcmp ( word, "{" ) == 0 ) { - continue; - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - continue; - } - else if ( strcmp ( word, "*MESH_FACENORMAL" ) == 0 ) { - - count = sscanf ( next, "%d%n", &iface, &width ); - next = next + width; - - count = sscanf ( next, "%f%n", &x, &width ); - next = next + width; - - count = sscanf ( next, "%f%n", &y, &width ); - next = next + width; - - count = sscanf ( next, "%f%n", &z, &width ); - next = next + width; - - iface = iface + face_num_old; - ivert = 0; - - face_normal[0][iface] = x; - face_normal[1][iface] = y; - face_normal[2][iface] = z; - - break; - - } - else if ( strcmp ( word, "*MESH_VERTEXNORMAL" ) == 0 ) { - - count = sscanf ( next, "%d%n", &i, &width ); - next = next + width; - - count = sscanf ( next, "%f%n", &x, &width ); - next = next + width; - - count = sscanf ( next, "%f%n", &y, &width ); - next = next + width; - - count = sscanf ( next, "%f%n", &z, &width ); - next = next + width; - - vertex_normal[0][ivert][iface] = x; - vertex_normal[1][ivert][iface] = y; - vertex_normal[2][ivert][iface] = z; - ivert = ivert + 1; - - break; - } - else { - bad_num = bad_num + 1; - printf ( "Bad data in MESH_NORMALS, line %d\n", text_num ); - break; - } - } -/* - *MESH_TFACELIST -*/ - else if ( strcmp ( level_name[level], "*MESH_TFACELIST" ) == 0 ) { - - if ( strcmp ( word, "{" ) == 0 ) { - continue; - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - continue; - } - else if ( strcmp ( word1, "*MESH_TFACE" ) == 0 ) { - break; - } - else { - bad_num = bad_num + 1; - printf ( "Bad data in MESH_TFACE_LIST, line %d\n", text_num ); - break; - } - } -/* - *MESH_TVERTLIST -*/ - else if ( strcmp ( level_name[level], "*MESH_TVERTLIST" ) == 0 ) { - - if ( strcmp ( word, "{" ) == 0 ) { - continue; - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - continue; - } - else if ( strcmp ( word1, "*MESH_TVERT" ) == 0 ) { - break; - } - else { - bad_num = bad_num + 1; - printf ( "Bad data in MESH_TVERTLIST, line %d\n", text_num ); - break; - } - } -/* - *MESH_VERTEX_LIST -*/ - else if ( strcmp ( level_name[level], "*MESH_VERTEX_LIST" ) == 0 ) { - - if ( strcmp ( word, "{" ) == 0 ) { - cor3_num_old = cor3_num; - continue; - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - continue; - } - else if ( strcmp ( word1, "*MESH_VERTEX" ) == 0 ) { - - count = sscanf ( next, "%d%n", &i, &width ); - next = next + width; - - count = sscanf ( next, "%f%n", &x, &width ); - next = next + width; - - count = sscanf ( next, "%f%n", &y, &width ); - next = next + width; - - count = sscanf ( next, "%f%n", &z, &width ); - next = next + width; - - i = i + cor3_num_old; - if ( cor3_num < i + 1 ) { - cor3_num = i + 1; - } - - if ( i < COR3_MAX ) { - - cor3[0][i] = - transform_matrix[0][0] * x - + transform_matrix[0][1] * y - + transform_matrix[0][2] * z - + transform_matrix[0][3]; - - cor3[1][i] = - transform_matrix[1][0] * x - + transform_matrix[1][1] * y - + transform_matrix[1][2] * z - + transform_matrix[1][3]; - - cor3[2][i] = - transform_matrix[2][0] * x - + transform_matrix[2][1] * y - + transform_matrix[2][2] * z - + transform_matrix[2][3]; - } - - break; - } - else { - bad_num = bad_num + 1; - printf ( "Bad data in MESH_VERTEX_LIST, line %d\n", text_num ); - break; - } - } -/* - *NODE_TM - - Each node should start out with a default transformation matrix. -*/ - else if ( strcmp ( level_name[level], "*NODE_TM" ) == 0 ) { - - if ( strcmp ( word, "{" ) == 0 ) { - - tmat_init ( transform_matrix ); - - continue; - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - continue; - } - else if ( strcmp ( word, "*INHERIT_POS" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*INHERIT_ROT" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*INHERIT_SCL" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*NODE_NAME" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*TM_POS" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*TM_ROTANGLE" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*TM_ROTAXIS" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*TM_ROW0" ) == 0 ) { - - count = sscanf ( next, "%f%n", &temp, &width ); - next = next + width; - transform_matrix[0][0] = temp; - - count = sscanf ( next, "%f%n", &temp, &width ); - next = next + width; - transform_matrix[1][0] = temp; - - count = sscanf ( next, "%f%n", &temp, &width ); - next = next + width; - transform_matrix[2][0] = temp; - - break; - } - else if ( strcmp ( word, "*TM_ROW1" ) == 0 ) { - - count = sscanf ( next, "%f%n", &temp, &width ); - next = next + width; - transform_matrix[0][1] = temp; - - count = sscanf ( next, "%f%n", &temp, &width ); - next = next + width; - transform_matrix[1][1] = temp; - - count = sscanf ( next, "%f%n", &temp, &width ); - next = next + width; - transform_matrix[2][1] = temp; - - break; - } - else if ( strcmp ( word, "*TM_ROW2" ) == 0 ) { - - count = sscanf ( next, "%f%n", &temp, &width ); - next = next + width; - transform_matrix[0][2] = temp; - - count = sscanf ( next, "%f%n", &temp, &width ); - next = next + width; - transform_matrix[1][2] = temp; - - count = sscanf ( next, "%f%n", &temp, &width ); - next = next + width; - transform_matrix[2][2] = temp; - - break; - } - else if ( strcmp ( word, "*TM_ROW3" ) == 0 ) { - - count = sscanf ( next, "%f%n", &temp, &width ); - next = next + width; - transform_matrix[0][3] = temp; - - count = sscanf ( next, "%f%n", &temp, &width ); - next = next + width; - transform_matrix[1][3] = temp; - - count = sscanf ( next, "%f%n", &temp, &width ); - next = next + width; - transform_matrix[2][3] = temp; - - break; - } - else if ( strcmp ( word, "*TM_SCALE" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*TM_SCALEAXIS" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*TM_SCALEAXISANG" ) == 0 ) { - break; - } - else { - bad_num = bad_num + 1; - printf ( "Bad data in NODE_TM, line %d\n", text_num ); - break; - } - } -/* - *SCENE -*/ - else if ( strcmp ( level_name[level], "*SCENE" ) == 0 ) { - - if ( strcmp ( word, "{" ) == 0 ) { - continue; - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - continue; - } - else if ( strcmp ( word, "*SCENE_AMBIENT_STATIC" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*SCENE_BACKGROUND_STATIC" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*SCENE_FILENAME" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*SCENE_FIRSTFRAME" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*SCENE_FRAMESPEED" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*SCENE_LASTFRAME" ) == 0 ) { - break; - } - else if ( strcmp ( word, "*SCENE_TICKSPERFRAME" ) == 0 ) { - break; - } - else { - bad_num = bad_num + 1; - printf ( "Bad data in SCENE, line %d\n", text_num ); - break; - } - - } - - } -/* - End of loop reading words from the line. -*/ - } -/* - End of loop reading lines from input file. -*/ - - return SUCCESS; -} -/******************************************************************************/ - -int ase_write ( FILE *fileout ) - -/******************************************************************************/ - -/* - Purpose: - - ASE_WRITE writes graphics information to an AutoCAD ASE file. - - Modified: - - 30 September 1998 - - Author: - - John Burkardt - -*/ -{ - int i1; - int i2; - int i3; - int i4; - int iface; - int ivert; - int j; - int text_num; - - text_num = 0; -/* - Write the header. -*/ - fprintf ( fileout, "*3DSMAX_ASCIIEXPORT 200\n" ); - fprintf ( fileout, "*COMMENT \"%s, created by IVCON.\"\n", fileout_name ); - fprintf ( fileout, "*COMMENT \"Original data in %s\"\n", filein_name ); - - text_num = text_num + 3; -/* - Write the scene block. -*/ - fprintf ( fileout, "*SCENE {\n" ); - fprintf ( fileout, " *SCENE_FILENAME \"\"\n" ); - fprintf ( fileout, " *SCENE_FIRSTFRAME 0\n" ); - fprintf ( fileout, " *SCENE_LASTFRAME 100\n" ); - fprintf ( fileout, " *SCENE_FRAMESPEED 30\n" ); - fprintf ( fileout, " *SCENE_TICKSPERFRAME 160\n" ); - fprintf ( fileout, " *SCENE_BACKGROUND_STATIC 0.0000 0.0000 0.0000\n" ); - fprintf ( fileout, " *SCENE_AMBIENT_STATIC 0.0431 0.0431 0.0431\n" ); - fprintf ( fileout, "}\n" ); - - text_num = text_num + 9; -/* - Begin the big geometry block. -*/ - fprintf ( fileout, "*GEOMOBJECT {\n" ); - fprintf ( fileout, " *NODE_NAME \"%s\"\n", object_name ); - - text_num = text_num + 2; -/* - Sub block NODE_TM: -*/ - fprintf ( fileout, " *NODE_TM {\n" ); - fprintf ( fileout, " *NODE_NAME \"Object01\"\n" ); - fprintf ( fileout, " *INHERIT_POS 0 0 0\n" ); - fprintf ( fileout, " *INHERIT_ROT 0 0 0\n" ); - fprintf ( fileout, " *INHERIT_SCL 0 0 0\n" ); - fprintf ( fileout, " *TM_ROW0 1.0000 0.0000 0.0000\n" ); - fprintf ( fileout, " *TM_ROW1 0.0000 1.0000 0.0000\n" ); - fprintf ( fileout, " *TM_ROW2 0.0000 0.0000 1.0000\n" ); - fprintf ( fileout, " *TM_ROW3 0.0000 0.0000 0.0000\n" ); - fprintf ( fileout, " *TM_POS 0.0000 0.0000 0.0000\n" ); - fprintf ( fileout, " *TM_ROTAXIS 0.0000 0.0000 0.0000\n" ); - fprintf ( fileout, " *TM_ROTANGLE 0.0000\n" ); - fprintf ( fileout, " *TM_SCALE 1.0000 1.0000 1.0000\n" ); - fprintf ( fileout, " *TM_SCALEAXIS 0.0000 0.0000 0.0000\n" ); - fprintf ( fileout, " *TM_SCALEAXISANG 0.0000\n" ); - fprintf ( fileout, " }\n" ); - - text_num = text_num + 16; -/* - Sub block MESH: - Items -*/ - fprintf ( fileout, " *MESH {\n" ); - fprintf ( fileout, " *TIMEVALUE 0\n" ); - fprintf ( fileout, " *MESH_NUMVERTEX %d\n", cor3_num ); - fprintf ( fileout, " *MESH_NUMFACES %d\n", face_num ); - - text_num = text_num + 4; -/* - Sub sub block MESH_VERTEX_LIST -*/ - fprintf ( fileout, " *MESH_VERTEX_LIST {\n" ); - text_num = text_num + 1; - - for ( j = 0; j < cor3_num; j++ ) { - fprintf ( fileout, " *MESH_VERTEX %d %f %f %f\n", j, cor3[0][j], - cor3[1][j], cor3[2][j] ); - text_num = text_num + 1; - } - - fprintf ( fileout, " }\n" ); - text_num = text_num + 1; -/* - Sub sub block MESH_FACE_LIST - Items MESH_FACE -*/ - fprintf ( fileout, " *MESH_FACE_LIST {\n" ); - text_num = text_num + 1; - - for ( iface = 0; iface < face_num; iface++ ) { - - i1 = face[0][iface]; - i2 = face[1][iface]; - i3 = face[2][iface]; - - if ( face_order[iface] == 3 ) { - fprintf ( fileout, " *MESH_FACE %d: A: %d B: %d C: %d", iface, i1, i2, i3 ); - fprintf ( fileout, " AB: 1 BC: 1 CA: 1 *MESH_SMOOTHING *MESH_MTLID 1\n" ); - text_num = text_num + 1; - } - else if ( face_order[iface] == 4 ) { - i4 = face[3][iface]; - fprintf ( fileout, " *MESH_FACE %d: A: %d B: %d C: %d D: %d", iface, i1, i2, i3, i4 ); - fprintf ( fileout, " AB: 1 BC: 1 CD: 1 DA: 1 *MESH_SMOOTHING *MESH_MTLID 1\n" ); - text_num = text_num + 1; - } - } - - fprintf ( fileout, " }\n" ); - text_num = text_num + 1; -/* - Item MESH_NUMTVERTEX. -*/ - fprintf ( fileout, " *MESH_NUMTVERTEX 0\n" ); - text_num = text_num + 1; -/* - Item NUMCVERTEX. -*/ - fprintf ( fileout, " *MESH_NUMCVERTEX 0\n" ); - text_num = text_num + 1; -/* - Sub block MESH_NORMALS - Items MESH_FACENORMAL, MESH_VERTEXNORMAL (repeated) -*/ - fprintf ( fileout, " *MESH_NORMALS {\n" ); - text_num = text_num + 1; - - for ( iface = 0; iface < face_num; iface++ ) { - - fprintf ( fileout, " *MESH_FACENORMAL %d %f %f %f\n", - iface, face_normal[0][iface], face_normal[1][iface], face_normal[2][iface] ); - text_num = text_num + 1; - - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - fprintf ( fileout, " *MESH_VERTEXNORMAL %d %f %f %f\n", - face[ivert][iface], vertex_normal[0][ivert][iface], - vertex_normal[1][ivert][iface], vertex_normal[2][ivert][iface] ); - text_num = text_num + 1; - } - } - - fprintf ( fileout, " }\n" ); - text_num = text_num + 1; -/* - Close the MESH object. -*/ - fprintf ( fileout, " }\n" ); -/* - A few closing parameters. -*/ - fprintf ( fileout, " *PROP_MOTIONBLUR 0\n" ); - fprintf ( fileout, " *PROP_CASTSHADOW 1\n" ); - fprintf ( fileout, " *PROP_RECVSHADOW 1\n" ); -/* - Close the GEOM object. -*/ - fprintf ( fileout, "}\n" ); - - text_num = text_num + 5; -/* - Report. -*/ - printf ( "\n" ); - printf ( "ASE_WRITE - Wrote %d text lines;\n", text_num ); - - return SUCCESS; -} -/**********************************************************************/ - -int byu_read ( FILE *filein ) - -/**********************************************************************/ - -/* - Purpose: - - BYU_READ reads graphics data from a Movie.BYU surface geometry file. - - Discussion: - - A Movie.BYU surface geometry file contains 4 groups of data. - - The first group of data is a single line, containing 4 integers, - each one left justified in 8 columns. The integers are: - - PART_NUM, VERTEX_NUM, POLY_NUM, EDGE_NUM, - - that is, the number of parts or objects, the number of vertices or nodes, - the number of polygons or faces, and the number of edges. - - The second group of data is a single line, containing 2 integers, - each one left justified in 8 columnes. The integers are: - - POLY1, POLY2, - - the starting and ending polygon numbers. Presumably, this means - that the polygons are labeled POLY1, POLY1+1, ..., POLY2, comprising - a total of POLY_NUM polygons. - - The third group is the X, Y and Z coordinates of all the vertices. - These may be written using a FORTRAN format of 6E12.5, which - crams two sets of (X,Y,Z) data onto each line, with each real value - written in an exponential format with 5 places after the decimal. - However, it is generally possible to write the XYZ coordinate data - for each vertex on a separate line. - - The fourth group defines the polygons in terms of the vertex indices. - For each polygon, the vertices that make up the polygon are listed in - counterclockwise order. The last vertex listed is given with a negative - sign to indicate the end of the list. All the vertices for all the - polygons are listed one after the other, using a format that puts - up to 10 left-justified integers on a line, with each integer occupying - 8 spaces. - - This code will certainly read a BYU file created by BYU_WRITE, but - it will not handle more general files. In particular, an object - can have several parts, the coordinate data can be grouped so - that there are 2 sets of (x,y,z) data per line, and so on. - - Example: - - 1 8 6 24 - 1 6 - 0.00000E+00 0.00000E+00 0.00000E+00 - 1.00000E+00 0.00000E+00 0.00000E+00 - 1.00000E+00 2.00000E+00 0.00000E+00 - 0.00000E+00 2.00000E+00 0.00000E+00 - 0.00000E+00 0.00000E+00 1.00000E+00 - 1.00000E+00 0.00000E+00 1.00000E+00 - 1.00000E+00 2.00000E+00 1.00000E+00 - 0.00000E+00 2.00000E+00 1.00000E+00 - 4 3 2 -1 - 5 6 7 -8 - 1 5 8 -4 - 4 8 7 -3 - 3 7 6 -2 - 2 6 5 -1 - - Modified: - - 24 May 2001 - - Author: - - John Burkardt - -*/ -{ - int cor3_num_new; - int count; - int edge_num; - int face_num_new; - int iface; - int ival; - int ivert; - int j; - char *next; - int part_num; - int poly1; - int poly2; - int text_num; - int width; - float x; - float y; - float z; - - text_num = 0; - - if ( fgets ( input, LINE_MAX_LEN, filein ) == NULL ) { - return ERROR; - } - text_num = text_num + 1; - - sscanf ( input, "%d %d %d %d", &part_num, &cor3_num_new, &face_num_new, - &edge_num ); - - if ( fgets ( input, LINE_MAX_LEN, filein ) == NULL ) { - return ERROR; - } - text_num = text_num + 1; - - sscanf ( input, "%d %d", &poly1, &poly2 ); - - for ( j = cor3_num; j < cor3_num + cor3_num_new; j++ ) { - - if ( fgets ( input, LINE_MAX_LEN, filein ) == NULL ) { - return ERROR; - } - text_num = text_num + 1; - - sscanf ( input, "%f %f %f", &x, &y, &z ); - cor3[0][j] = x; - cor3[1][j] = y; - cor3[2][j] = z; - } - - for ( iface = face_num; iface < face_num + face_num_new; iface++ ) { - - if ( fgets ( input, LINE_MAX_LEN, filein ) == NULL ) { - return ERROR; - } - text_num = text_num + 1; - - next = input; - ivert = 0; - - for (;;) { - - count = sscanf ( next, "%d%n", &ival, &width ); - next = next + width; - - if ( count <= 0 ) { - return ERROR; - } - - if ( ival > 0 ) { - face[ivert][iface] = ival - 1 + cor3_num; - } - else { - face[ivert][iface] = - ival - 1 - cor3_num; - break; - } - - ivert = ivert + 1; - - } - face_order[iface] = ivert + 1; - } - - cor3_num = cor3_num + cor3_num_new; - face_num = face_num + face_num_new; -/* - Report. -*/ - printf ( "\n" ); - printf ( "BYU_READ - Read %d text lines.\n", text_num ); - - return SUCCESS; -} -/**********************************************************************/ - -int byu_write ( FILE *fileout ) - -/**********************************************************************/ - -/* - Purpose: - - BYU_WRITE writes out the graphics data as a Movie.BYU surface geometry file. - - Discussion: - - A Movie.BYU surface geometry file contains 4 groups of data. - - The first group of data is a single line, containing 4 integers, - each one left justified in 8 columns. The integers are: - - PART_NUM, VERTEX_NUM, POLY_NUM, EDGE_NUM, - - that is, the number of parts or objects, the number of vertices or nodes, - the number of polygons or faces, and the number of edges. - - The second group of data is a single line, containing 2 integers, - each one left justified in 8 columnes. The integers are: - - POLY1, POLY2, - - the starting and ending polygon numbers. Presumably, this means - that the polygons are labeled POLY1, POLY1+1, ..., POLY2, comprising - a total of POLY_NUM polygons. - - The third group is the X, Y and Z coordinates of all the vertices. - These may be written using a FORTRAN format of 6E12.5, which - crams two sets of (X,Y,Z) data onto each line, with each real value - written in an exponential format with 5 places after the decimal. - However, it is generally possible to write the XYZ coordinate data - for each vertex on a separate line. - - The fourth group defines the polygons in terms of the vertex indices. - For each polygon, the vertices that make up the polygon are listed in - counterclockwise order. The last vertex listed is given with a negative - sign to indicate the end of the list. All the vertices for all the - polygons are listed one after the other, using a format that puts - up to 10 left-justified integers on a line, with each integer occupying - 8 spaces. - - Example: - - 1 8 6 24 - 1 6 - 0.00000E+00 0.00000E+00 0.00000E+00 - 1.00000E+00 0.00000E+00 0.00000E+00 - 1.00000E+00 2.00000E+00 0.00000E+00 - 0.00000E+00 2.00000E+00 0.00000E+00 - 0.00000E+00 0.00000E+00 1.00000E+00 - 1.00000E+00 0.00000E+00 1.00000E+00 - 1.00000E+00 2.00000E+00 1.00000E+00 - 0.00000E+00 2.00000E+00 1.00000E+00 - 4 3 2 -1 - 5 6 7 -8 - 1 5 8 -4 - 4 8 7 -3 - 3 7 6 -2 - 2 6 5 -1 - - Modified: - - 24 May 2001 - - Author: - - John Burkardt -*/ -{ - int edge_num; - int iface; - int ivert; - int j; - int jp; - int part_num; - int text_num; - - text_num = 0; - - edge_num = 0; - for ( iface = 0; iface < face_num; iface++ ) { - edge_num = edge_num + face_order[iface]; - } - - part_num = 1; - - fprintf ( fileout, "%d %d %d %d\n", part_num, cor3_num, face_num, edge_num ); - text_num = text_num + 1; - - fprintf ( fileout, "1 %d\n", face_num ); - text_num = text_num + 1; - - for ( j = 0; j < cor3_num; j++ ) { - fprintf ( fileout, "%f %f %f\n", cor3[0][j], cor3[1][j], cor3[2][j] ); - text_num = text_num + 1; - } - - for ( iface = 0; iface < face_num; iface++ ) { - - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - - jp = face[ivert][iface] + 1; - if ( ivert == face_order[iface] - 1 ) { - jp = - jp; - } - fprintf ( fileout, "%d ", jp ); - } - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - } -/* - Report. -*/ - printf ( "\n" ); - printf ( "BYU_WRITE - Wrote %d text lines.\n", text_num ); - - return SUCCESS; -} -/******************************************************************************/ - -int char_index_last ( char* string, char c ) - -/******************************************************************************/ - -/* - Purpose: - - CHAR_INDEX_LAST reports the last occurrence of a character in a string. - - Author: - - John Burkardt -*/ -{ - int i; - int j; - int nchar; - - j = -1; - - nchar = strlen ( string ); - - for ( i = 0; i < nchar; i++ ) { - if ( string[i] == c ) { - j = i; - } - } - - return j; - -} -/******************************************************************************/ - -int char_pad ( int *char_index, int *null_index, char *string, - int STRING_MAX ) - -/******************************************************************************/ - -/* - Purpose: - - CHAR_PAD "pads" a character in a string with a blank on either side. - - Modified: - - 16 October 1998 - - Author: - - John Burkardt - - Parameters: - - Input/output, int *CHAR_INDEX, the position of the character to be padded. - On output, this is increased by 1. - - Input/output, int *NULL_INDEX, the position of the terminating NULL in - the string. On output, this is increased by 2. - - Input/output, char STRING[STRING_MAX], the string to be manipulated. - - Input, int STRING_MAX, the maximum number of characters that can be stored - in the string. - - Output, int CHAR_PAD, is SUCCESS if the operation worked, and ERROR otherwise. -*/ -{ - int i; - - if ( *char_index < 0 || - *char_index >= *null_index || - *char_index > STRING_MAX-1 ) { - return ERROR; - } - - if ( (*null_index) + 2 > STRING_MAX-1 ) { - return ERROR; - } - - for ( i = *null_index + 2; i > *char_index + 2; i-- ) { - string[i] = string[i-2]; - } - string[*char_index+2] = ' '; - string[*char_index+1] = string[*char_index]; - string[*char_index] = ' '; - - *char_index = *char_index + 1; - *null_index = *null_index + 2; - - return SUCCESS; -} -/******************************************************************************/ - -char char_read ( FILE *filein ) - -/******************************************************************************/ - -/* - Purpose: - - CHAR_READ reads one character from a binary file. - - Modified: - - 24 May 1999 - - Author: - - John Burkardt -*/ -{ - char c; - - c = ( char ) fgetc ( filein ); - - return c; -} -/******************************************************************************/ - -int char_write ( FILE *fileout, char c ) - -/******************************************************************************/ - -/* - Purpose: - - CHAR_WRITE writes one character to a binary file. - - Modified: - - 24 May 1999 - - Author: - - John Burkardt -*/ -{ - fputc ( c, fileout ); - - return 1; -} -/******************************************************************************/ - -int command_line ( char **argv ) - -/******************************************************************************/ - -/* - - Purpose: - - COMMAND_LINE carries out a command-line session of file conversion. - - Discussion: - - This routine is invoked when the user command is something like - - ivcon filein_name fileout_name - - or - - ivcon -rn filein_name fileout_name - - where "-rn" signals the "reverse normals" option, or - - ivcon -rf filein_name fileout_name - - where "-rf" signals the "reverse faces" option. - - Modified: - - 28 June 1999 - - Author: - - John Burkardt -*/ -{ - int i; - int iarg; - int icor3; - int ierror; - int iface; - int ivert; - int reverse_faces; - int reverse_normals; -/* - Initialize local data. -*/ - iarg = 0; - ierror = 0; - reverse_faces = FALSE; - reverse_normals = FALSE; -/* - Initialize the graphics data. -*/ - data_init ( ); -/* - Get the -RN option, -RF option, and the input file name. -*/ - iarg = iarg + 1; - strcpy ( filein_name, argv[iarg] ); - - if ( leqi ( filein_name, "-RN" ) == TRUE ) { - reverse_normals = TRUE; - printf ( "\n" ); - printf ( "COMMAND_LINE: Reverse_Normals option requested.\n" ); - iarg = iarg + 1; - strcpy ( filein_name, argv[iarg] ); - } - - if ( leqi ( filein_name, "-RF" ) == TRUE ) { - reverse_faces = TRUE; - printf ( "\n" ); - printf ( "COMMAND_LINE: Reverse_Faces option requested.\n" ); - iarg = iarg + 1; - strcpy ( filein_name, argv[iarg] ); - } -/* - Read the input. -*/ - ierror = data_read ( ); - - if ( ierror == ERROR ) { - printf ( "\n" ); - printf ( "COMMAND_LINE - Fatal error!\n" ); - printf ( " Failure while reading input data.\n" ); - return ERROR; - } -/* - Reverse the normal vectors if requested. -*/ - if ( reverse_normals == TRUE ) { - - for ( icor3 = 0; icor3 < cor3_num; icor3++ ) { - for ( i = 0; i < 3; i++ ) { - cor3_normal[i][icor3] = - cor3_normal[i][icor3]; - } - } - - for ( iface = 0; iface < face_num; iface++ ) { - for ( i = 0; i < 3; i++ ) { - face_normal[i][iface] = - face_normal[i][iface]; - } - } - - for ( iface = 0; iface < face_num; iface++ ) { - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - for ( i = 0; i < 3; i++ ) { - vertex_normal[i][ivert][iface] = - - vertex_normal[i][ivert][iface]; - } - } - } - printf ( "\n" ); - printf ( "COMMAND_LINE - Note:\n" ); - printf ( " Reversed node, face, and vertex normals.\n" ); - } -/* - Reverse the faces if requested. -*/ - if ( reverse_faces == TRUE ) { - - face_reverse_order ( ); - - printf ( "\n" ); - printf ( "COMMAND_LINE - Note:\n" ); - printf ( " Reversed the face definitions.\n" ); - } -/* - Write the output file. -*/ - iarg = iarg + 1; - strcpy ( fileout_name, argv[iarg] ); - - ierror = data_write ( ); - - if ( ierror == ERROR ) { - printf ( "\n" ); - printf ( "COMMAND_LINE - Fatal error!\n" ); - printf ( " Failure while writing output data.\n" ); - return ERROR; - } - return SUCCESS; -} -/******************************************************************************/ - -void cor3_normal_set ( void ) - -/******************************************************************************/ - -/* - Purpose: - - COR3_NORMAL_SET computes node normal vectors. - - Modified: - - 18 November 1998 - - Author: - - John Burkardt -*/ -{ - int icor3; - int iface; - int ivert; - int j; - float norm; - float temp; - - for ( icor3 = 0; icor3 < cor3_num; icor3++ ) { - for ( j = 0; j < 3; j++ ) { - cor3_normal[j][icor3] = 0.0; - } - } -/* - Add up the normals at all the faces to which the node belongs. -*/ - for ( iface = 0; iface < face_num; iface++ ) { - - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - - icor3 = face[ivert][iface]; - - for ( j = 0; j < 3; j++ ) { - cor3_normal[j][icor3] = cor3_normal[j][icor3] - + vertex_normal[j][ivert][iface]; - } - } - } -/* - Renormalize. -*/ - for ( icor3 = 0; icor3 < cor3_num; icor3++ ) { - - norm = 0.0; - for ( j = 0; j < 3; j++ ) { - temp = cor3_normal[j][icor3]; - norm = norm + temp * temp; - } - - if ( norm == 0.0 ) { - norm = 3.0; - for ( j = 0; j < 3; j++ ) { - cor3_normal[j][icor3] = 1.0; - } - } - - norm = ( float ) sqrt ( norm ); - - for ( j = 0; j < 3; j++ ) { - cor3_normal[j][icor3] = cor3_normal[j][icor3] / norm; - } - } - - return; -} -/******************************************************************************/ - -void cor3_range ( void ) - -/******************************************************************************/ - -/* - Purpose: - - COR3_RANGE computes the coordinate minima and maxima. - - Modified: - - 31 August 1998 - - Author: - - John Burkardt -*/ -{ - int i; - float xave; - float xmax; - float xmin; - float yave; - float ymax; - float ymin; - float zave; - float zmax; - float zmin; - - xave = cor3[0][0]; - xmax = cor3[0][0]; - xmin = cor3[0][0]; - - yave = cor3[1][0]; - ymax = cor3[1][0]; - ymin = cor3[1][0]; - - zave = cor3[2][0]; - zmax = cor3[2][0]; - zmin = cor3[2][0]; - - for ( i = 1; i < cor3_num; i++ ) { - - xave = xave + cor3[0][i]; - if ( cor3[0][i] < xmin ) { - xmin = cor3[0][i]; - } - if ( cor3[0][i] > xmax ) { - xmax = cor3[0][i]; - } - - yave = yave + cor3[1][i]; - if ( cor3[1][i] < ymin ) { - ymin = cor3[1][i]; - } - if ( cor3[1][i] > ymax ) { - ymax = cor3[1][i]; - } - - zave = zave + cor3[2][i]; - if ( cor3[2][i] < zmin ) { - zmin = cor3[2][i]; - } - if ( cor3[2][i] > zmax ) { - zmax = cor3[2][i]; - } - } - - xave = xave / cor3_num; - yave = yave / cor3_num; - zave = zave / cor3_num; - - printf ( "\n" ); - printf ( "COR3_RANGE - Data range:\n" ); - printf ( "\n" ); - printf ( " Minimum Average Maximum Range\n" ); - printf ( "\n" ); - printf ( "X %f %f %f %f\n", xmin, xave, xmax, xmax-xmin ); - printf ( "Y %f %f %f %f\n", ymin, yave, ymax, ymax-ymin ); - printf ( "Z %f %f %f %f\n", zmin, zave, zmax, zmax-zmin ); - -} -/******************************************************************************/ - -void data_check ( void ) - -/******************************************************************************/ - -/* - Purpose: - - DATA_CHECK checks the input data. - - Modified: - - 18 May 1999 - - Author: - - John Burkardt -*/ -{ - int iface; - int nfix; - - if ( color_num > COLOR_MAX ) { - printf ( "\n" ); - printf ( "DATA_CHECK - Warning!\n" ); - printf ( " The input data requires %d colors.\n", color_num ); - printf ( " There was only room for %d\n", COLOR_MAX ); - color_num = COLOR_MAX; - } - - if ( cor3_num > COR3_MAX ) { - printf ( "\n" ); - printf ( "DATA_CHECK - Warning!\n" ); - printf ( " The input data requires %d points.\n", cor3_num ); - printf ( " There was only room for %d\n", COR3_MAX ); - cor3_num = COR3_MAX; - } - - if ( face_num > FACE_MAX ) { - printf ( "\n" ); - printf ( "DATA_CHECK - Warning!\n" ); - printf ( " The input data requires %d faces.\n", face_num ); - printf ( " There was only room for %d\n", FACE_MAX ); - face_num = FACE_MAX; - } - - if ( line_num > LINES_MAX ) { - printf ( "\n" ); - printf ( "DATA_CHECK - Warning!\n" ); - printf ( " The input data requires %d line items.\n", line_num ); - printf ( " There was only room for %d.\n", LINES_MAX ); - line_num = LINES_MAX; - } - - nfix = 0; - - for ( iface = 0; iface < face_num; iface++ ) { - - if ( face_order[iface] > ORDER_MAX ) { - face_order[iface] = ORDER_MAX; - nfix = nfix + 1; - } - - } - - if ( nfix > 0 ) { - printf ( "\n" ); - printf ( "DATA_CHECK - Warning!\n" ); - printf ( " Corrected %d faces using more than %d vertices per face.\n", - nfix, ORDER_MAX ); - } - - for ( i = 0; i < material_num; i++ ) { - if ( strcmp ( material_name[i], "" ) == 0 ) { - strcpy ( material_name[i], "Material_0000" ); - } - } - - for ( i = 0; i < texture_num; i++ ) { - if ( strcmp ( texture_name[i], "" ) == 0 ) { - strcpy ( texture_name[i], "Texture_0000" ); - } - } - - printf ( "\n" ); - printf ( "DATA_CHECK - Data checked.\n" ); - - return; -} -/******************************************************************************/ - -void data_init ( void ) - -/******************************************************************************/ - -/* - Purpose: - - DATA_INIT initializes the internal graphics data. - - Modified: - - 04 July 2000 - - Author: - - John Burkardt -*/ -{ - int i; - int iface; - int ivert; - int j; - int k; - - strcpy( anim_name, "" ); - - for ( i = 0; i < 3; i++ ) { - background_rgb[i] = 0.0; - } - - for ( i = 0; i < 3; i++ ) { - for ( j = 0; j < COR3_MAX; j++ ) { - cor3[i][j] = 0.0; - } - } - - for ( i = 0; i < COR3_MAX; i++ ) { - cor3_material[i] = 0; - } - - for ( i = 0; i < 3; i++ ) { - for ( j = 0; j < COR3_MAX; j++ ) { - cor3_normal[i][j] = 0.0; - } - } - - for ( j = 0; j < COR3_MAX; j++ ) { - cor3_tex_uv[0][j] = 0.0; - cor3_tex_uv[1][j] = 0.0; - } - - for ( iface = 0; iface < FACE_MAX; iface++ ) { - for ( ivert = 0; ivert < ORDER_MAX; ivert++ ) { - face[ivert][iface] = 0; - } - } - - for ( iface = 0; iface < FACE_MAX; iface++ ) { - face_flags[iface] = 6; - } - - for ( iface = 0; iface < FACE_MAX; iface++ ) { - face_material[iface] = 0; - } - - for ( iface = 0; iface < FACE_MAX; iface++ ) { - for ( i = 0; i < 3; i++ ) { - face_normal[i][iface] = 0; - } - } - - for ( iface = 0; iface < FACE_MAX; iface++ ) { - face_object[iface] = -1; - } - - for ( iface = 0; iface < FACE_MAX; iface++ ) { - face_order[iface] = 0; - } - - for ( iface = 0; iface < FACE_MAX; iface++ ) { - face_smooth[iface] = 1; - } - - for ( i = 0; i < LINES_MAX; i++ ) { - line_dex[i] = -1; - } - - for ( i = 0; i < LINES_MAX; i++ ) { - line_material[i] = 0; - } - - strcpy ( material_binding, "DEFAULT" ); - - for ( j = 0; j < MATERIAL_MAX; j++ ) { - strcpy ( material_name[j], "Material_0000" ); - } - - for ( i = 0; i < 4; i++ ) { - for ( j = 0; j < MATERIAL_MAX; j++ ) { - material_rgba[i][j] = 0.0; - } - } - - strcpy ( normal_binding, "DEFAULT" ); - - for ( j = 0; j < ORDER_MAX*FACE_MAX; j++ ) { - for ( i = 0; i < 3; i++ ) { - normal_temp[i][j] = 0; - } - } - - color_num = 0; - cor3_num = 0; - face_num = 0; - group_num = 0; - line_num = 0; - material_num = 0; - object_num = 0; - texture_num = 0; - - strcpy ( object_name, "IVCON" ); - - for ( i = 0; i < 3; i++ ) { - origin[i] = 0.0; - } - - for ( i = 0; i < 3; i++ ) { - pivot[i] = 0.0; - } - - for ( j = 0; j < COLOR_MAX; j++ ) { - rgbcolor[0][j] = 0.299; - rgbcolor[1][j] = 0.587; - rgbcolor[2][j] = 0.114; - } - - strcpy ( texture_binding, "DEFAULT" ); - - for ( j = 0; j < TEXTURE_MAX; j++ ) { - strcpy ( texture_name[j], "Texture_0000" ); - } - - tmat_init ( transform_matrix ); - - for ( iface = 0; iface < FACE_MAX; iface++ ) { - for ( ivert = 0; ivert < ORDER_MAX; ivert++ ) { - vertex_material[ivert][iface] = 0; - } - } - - for ( iface = 0; iface < FACE_MAX; iface++ ) { - for ( ivert = 0; ivert < ORDER_MAX; ivert++ ) { - for ( i = 0; i < 3; i++ ) { - vertex_normal[i][ivert][iface] = 0.0; - } - } - } - - for ( j = 0; j < 3; j++ ) { - for ( k = 0; k < FACE_MAX; k++ ) { - vertex_rgb[0][j][k] = 0.299; - vertex_rgb[1][j][k] = 0.587; - vertex_rgb[2][j][k] = 0.114; - } - } - - for ( iface = 0; iface < FACE_MAX; iface++ ) { - for ( ivert = 0; ivert < ORDER_MAX; ivert++ ) { - for ( i = 0; i < 2; i++ ) { - vertex_tex_uv[i][ivert][iface] = 0.0; - } - } - } - - if ( debug ) { - printf ( "\n" ); - printf ( "DATA_INIT: Graphics data initialized.\n" ); - } - - return; -} -/******************************************************************************/ - -int data_read ( void ) - -/******************************************************************************/ - -/* - Purpose: - - DATA_READ reads a file into internal graphics data. - - Modified: - - 26 September 1999 - - Author: - - John Burkardt -*/ -{ - FILE *filein; - char *filein_type; - int icor3; - int ierror; - int iface; - int iline; - int ivert; - int ntemp; -/* - Retrieve the input file type. -*/ - filein_type = file_ext ( filein_name ); - - if ( filein_type == NULL ) { - printf ( "\n" ); - printf ( "DATA_READ - Fatal error!\n" ); - printf ( " Could not determine the type of '%s'.\n", filein_name ); - return ERROR; - } - else if ( debug ) { - printf ( "\n" ); - printf ( "DATA_READ: Input file has type %s.\n", filein_type ); - } -/* - Initialize some data. -*/ - max_order2 = 0; - bad_num = 0; - bytes_num = 0; - comment_num = 0; - dup_num = 0; - text_num = 0; -/* - Open the file. -*/ - if ( leqi ( filein_type, "3DS" ) == TRUE || - leqi ( filein_type, "STLB" ) == TRUE || - leqi ( filein_type, "TRIB" ) == TRUE ) { - filein = fopen ( filein_name, "rb" ); - } - else { - filein = fopen ( filein_name, "r" ); - } - - if ( filein == NULL ) { - printf ( "\n" ); - printf ( "DATA_READ - Fatal error!\n" ); - printf ( " Could not open the input file '%s'!\n", filein_name ); - return ERROR; - } -/* - Read the information in the file. -*/ - if ( leqi ( filein_type, "3DS" ) == TRUE ) { - - ierror = tds_read ( filein ); -/* - Cleanup: distribute the node textures to the vertices. -*/ - if ( ierror == SUCCESS ) { - - for ( iface = 0; iface < face_num; iface++ ) { - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - icor3 = face[ivert][iface]; - vertex_tex_uv[0][ivert][iface] = cor3_tex_uv[0][icor3]; - vertex_tex_uv[1][ivert][iface] = cor3_tex_uv[1][icor3]; - } - } - - } - - } - else if ( leqi ( filein_type, "ASE" ) == TRUE ) { - - ierror = ase_read ( filein ); - - if ( ierror == SUCCESS ) { - - node_to_vertex_material ( ); - - vertex_to_face_material ( ); - - } - - } - else if ( leqi ( filein_type, "BYU" ) == TRUE ) { - - ierror = byu_read ( filein ); - - } - else if ( leqi ( filein_type, "DXF" ) == TRUE ) { - - ierror = dxf_read ( filein ); - - } - else if ( leqi ( filein_type, "GMOD" ) == TRUE ) { - - ierror = gmod_read ( filein ); - - } - else if ( leqi ( filein_type, "HRC" ) == TRUE ) { - - ierror = hrc_read ( filein ); - - } - else if ( leqi ( filein_type, "IV" ) == TRUE ) { - - ierror = iv_read ( filein ); - - } - else if ( leqi ( filein_type, "OBJ" ) == TRUE ) { - - ierror = obj_read ( filein ); - - } - else if ( leqi ( filein_type, "SMF" ) == TRUE ) { - - ierror = smf_read ( filein ); - - } - else if ( - leqi ( filein_type, "STL" ) == TRUE || - leqi ( filein_type, "STLA") == TRUE ) { - - ierror = stla_read ( filein ); - - if( ierror ) { - // might be binary - fclose(filein); - filein = fopen ( filein_name, "rb" ); - ierror = stlb_read ( filein ); - } - } - else if ( leqi ( filein_type, "STLB") == TRUE ) { - - ierror = stlb_read ( filein ); - - } - else if ( - leqi ( filein_type, "TRI" ) == TRUE || - leqi ( filein_type, "TRIA") == TRUE ) { - - ierror = tria_read ( filein ); - - } - else if ( leqi ( filein_type, "TRIB") == TRUE ) { - - ierror = trib_read ( filein ); - - } - else if ( leqi ( filein_type, "VLA" ) == TRUE ) { - - ierror = vla_read ( filein ); - - } - else { - printf ( "\n" ); - printf ( "DATA_READ - Fatal error!\n" ); - printf ( " Unacceptable input file type.\n" ); - return ERROR; - } - - fclose ( filein ); - - if ( debug ) { - printf ( "DATA_READ: Finished reading the data file.\n" ); - } -/* - Catch errors reported by the various reading routines. -*/ - if ( ierror == ERROR ) { - return ierror; - } -/* - Restore the transformation matrix. -*/ - tmat_init ( transform_matrix ); -/* - Report on what we read. -*/ - if ( face_num < FACE_MAX ) { - ntemp = face_num; - } - else { - ntemp = FACE_MAX; - } - - max_order2 = ivec_max ( ntemp, face_order ); - - data_report ( ); -/* - Warn about any errors that occurred during reading. -*/ - if ( ierror == ERROR ) { - printf ( "\n" ); - printf ( "DATA_READ - Fatal error!\n" ); - printf ( " An error occurred while reading the input file.\n" ); - return ERROR; - } -/* - Check the data. - You MUST wait until after this check before doing other computations, - since COR3_NUM and other variables could be much larger than the legal - maximums, until corrected by DATA_CHECK. -*/ - data_check ( ); -/* - MATERIALS FIXUPS: - - If there are no materials at all, define one. -*/ - if ( material_num < 1 ) { - material_num = 1; - strcpy ( material_name[0], "Material_0000" ); - material_rgba[0][0] = 0.7; - material_rgba[1][0] = 0.7; - material_rgba[2][0] = 0.7; - material_rgba[3][0] = 1.0; - } -/* - If a node has not been assigned a material, set it to material 0. -*/ - for ( icor3 = 0; icor3 < cor3_num; icor3++ ) { - if ( cor3_material[icor3] < 0 || cor3_material[icor3] > material_num - 1 ) { - cor3_material[icor3] = 0; - } - } -/* - If a vertex has not been assigned a material, set it to material 0. -*/ - for ( iface = 0; iface < face_num; iface++ ) { - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - if ( vertex_material[ivert][iface] < 0 || vertex_material[ivert][iface] > material_num - 1 ) { - vertex_material[ivert][iface] = 0; - } - } - } -/* - If a face has not been assigned a material, set it to material 0. -*/ - for ( iface = 0; iface < face_num; iface++ ) { - if ( face_material[iface] < 0 || face_material[iface] > material_num - 1 ) { - face_material[iface] = 0; - } - } -/* - If a line item has not been assigned a material, set it to material 0. -*/ - for ( iline = 0; iline < line_num; iline++ ) { - if ( line_dex[iline] == -1 ) { - line_material[iline] = -1; - } - else if ( line_material[iline] < 0 || line_material[iline] > material_num - 1 ) { - line_material[iline] = 0; - } - } -/* - Delete edges of zero length. -*/ - edge_null_delete ( ); -/* - Compute the area of each face. -*/ - face_area_set ( ); -/* - Delete faces with zero area. -*/ - face_null_delete ( ); -/* - Recompute zero face-vertex normals from vertex positions. -*/ - vertex_normal_set ( ); -/* - Compute the node normals from the vertex normals. -*/ - cor3_normal_set ( ); -/* - Recompute zero face normals by averaging face-vertex normals. -*/ - face_normal_ave ( ); -/* - Report on the nodal coordinate range. -*/ - cor3_range ( ); - - return SUCCESS; -} -/**********************************************************************/ - -void data_report ( void ) - -/**********************************************************************/ - -/* - Purpose: - - DATA_REPORT gives a summary of the contents of the data file. - - Modified: - - 24 May 1999 - - Author: - - John Burkardt -*/ -{ - printf ( "\n" ); - printf ( "DATA_REPORT - The input file contains:\n" ); - printf ( "\n" ); - printf ( " Bad data items %d\n", bad_num ); - printf ( " Text lines %d\n", text_num ); - printf ( " Text bytes (binary data) %d\n", bytes_num ); - printf ( " Colors %d\n", color_num ); - printf ( " Comments %d\n", comment_num ); - printf ( " Duplicate points %d\n", dup_num ); - printf ( " Faces %d\n", face_num ); - printf ( " Groups %d\n", group_num ); - printf ( " Vertices per face, maximum %d\n", max_order2 ); - printf ( " Line items %d\n", line_num ); - printf ( " Points %d\n", cor3_num ); - printf ( " Objects %d\n", object_num ); - - return; -} -/******************************************************************************/ - -int data_write ( void ) - -/******************************************************************************/ - -/* - Purpose: - - DATA_WRITE writes the internal graphics data to a file. - - Modified: - - 22 May 1999 - - Author: - - John Burkardt -*/ -{ - FILE *fileout; - char *fileout_type; - int line_num_save; - int result; - - result = SUCCESS; -/* - Retrieve the output file type. -*/ - fileout_type = file_ext ( fileout_name ); - - if ( fileout_type == NULL ) { - printf ( "\n" ); - printf ( "DATA_WRITE - Fatal error!\n" ); - printf ( " Could not determine the output file type.\n" ); - return ERROR; - } -/* - Open the output file. -*/ - if ( leqi ( fileout_type, "3DS" ) == TRUE || - leqi ( fileout_type, "STLB" ) == TRUE || - leqi ( fileout_type, "TRIB" ) ) { - fileout = fopen ( fileout_name, "wb" ); - } - else { - fileout = fopen ( fileout_name, "w" ); - } - - if ( fileout == NULL ) { - printf ( "\n" ); - printf ( "DATA_WRITE - Fatal error!\n" ); - printf ( " Could not open the output file!\n" ); - return ERROR; - } -/* - Write the output file. -*/ - if ( leqi ( fileout_type, "3DS" ) == TRUE ) { - - tds_pre_process(); - result = tds_write ( fileout ); - - } - else if ( leqi ( fileout_type, "ASE" ) == TRUE ) { - - result = ase_write ( fileout ); - - } - else if ( leqi ( fileout_type, "BYU" ) == TRUE ) { - - result = byu_write ( fileout ); - - } - else if ( leqi ( fileout_type, "DXF" ) == TRUE ) { - - result = dxf_write ( fileout ); - - } - else if ( leqi ( fileout_type, "GMOD" ) == TRUE ) { - - result = gmod_write ( fileout ); - - } - else if ( leqi ( fileout_type, "HRC" ) == TRUE ) { - - result = hrc_write ( fileout ); - - } - else if ( leqi ( fileout_type, "IV" ) == TRUE ) { - - result = iv_write ( fileout ); - - } - else if ( leqi ( fileout_type, "OBJ" ) == TRUE ) { - - result = obj_write ( fileout ); - - } - else if ( leqi ( fileout_type, "POV" ) == TRUE ) { - - result = pov_write ( fileout ); - - } - else if ( leqi ( fileout_type, "SMF" ) == TRUE ) { - - result = smf_write ( fileout ); - - } - else if ( - leqi ( fileout_type, "STL" ) == TRUE || - leqi ( fileout_type, "STLA" ) == TRUE ) { - - result = stla_write ( fileout ); - - } - else if ( leqi ( fileout_type, "STLB" ) == TRUE ) { - - result = stlb_write ( fileout ); - - } - else if ( leqi ( fileout_type, "TEC" ) == TRUE ) { - - result = tec_write ( fileout ); - - } - else if ( - leqi ( fileout_type, "TRI" ) == TRUE || - leqi ( fileout_type, "TRIA" ) == TRUE ) { - - result = tria_write ( fileout ); - - } - else if ( leqi ( fileout_type, "TRIB" ) == TRUE ) { - - result = trib_write ( fileout ); - - } - else if ( leqi ( fileout_type, "TXT" ) == TRUE ) { - - result = txt_write ( fileout ); - - } - else if ( leqi ( fileout_type, "UCD" ) == TRUE ) { - - result = ucd_write ( fileout ); - - } - else if ( leqi ( fileout_type, "VLA" ) == TRUE ) { - - line_num_save = line_num; - - if ( face_num > 0 ) { - - printf ( "\n" ); - printf ( "DATA_WRITE - Note:\n" ); - printf ( " Face information will temporarily be converted to\n" ); - printf ( " line information for output to a VLA file.\n" ); - - face_to_line ( ); - - if ( line_num > LINES_MAX ) { - printf ( "\n" ); - printf ( "DATA_WRITE - Warning:\n" ); - printf ( " Some face information was lost.\n" ); - printf ( " The maximum number of lines is %d.\n", LINES_MAX ); - printf ( " The number of lines needed is %d.\n", line_num ); - line_num = LINES_MAX; - } - - } - - result = vla_write ( fileout ); - - line_num = line_num_save; - - } - else if ( leqi ( fileout_type, "WRL" ) == TRUE ) { - - result = wrl_write ( fileout ); - - } - else if ( leqi ( fileout_type, "XGL" ) == TRUE ) { - - result = xgl_write ( fileout ); - - } - else { - - result = ERROR; - printf ( "\n" ); - printf ( "DATA_WRITE - Fatal error!\n" ); - printf ( " Unacceptable output file type \"%s\".\n", fileout_type ); - - } -/* - Close the output file. -*/ - fclose ( fileout ); - - if ( result == ERROR ) { - return ERROR; - } - else { - return SUCCESS; - } -} -/******************************************************************************/ - -int dxf_read ( FILE *filein ) - -/******************************************************************************/ - -/* - Purpose: - - DXF_READ reads an AutoCAD DXF file. - - Examples: - - 0 - SECTION - 2 - HEADER - 999 - diamond.dxf created by IVREAD. - 999 - Original data in diamond.obj. - 0 - ENDSEC - 0 - SECTION - 2 - TABLES - 0 - ENDSEC - 0 - SECTION - 2 - BLOCKS - 0 - ENDSEC - 0 - SECTION - 2 - ENTITIES - 0 - LINE - 8 - 0 - 10 - 0.00 (X coordinate of beginning of line.) - 20 - 0.00 (Y coordinate of beginning of line.) - 30 - 0.00 (Z coordinate of beginning of line.) - 11 - 1.32 (X coordinate of end of line.) - 21 - 1.73 (Y coordinate of end of line.) - 31 - 2.25 (Z coordinate of end of line.) - 0 - 3DFACE - 8 - Cube - 10 - -0.50 (X coordinate of vertex 1) - 20 - 0.50 (Y coordinate of vertex 1) - 30 - 1.0 (Z coordinate of vertex 1) - 11 - 0.50 (X coordinate of vertex 2) - 21 - 0.50 (Y coordinate of vertex 2) - 31 - 1.0 (Z coordinate of vertex 2) - 12 - 0.50 (X coordinate of vertex 3) - 22 - 0.50 (Y coordinate of vertex 3) - 32 - 0.00 (Z coordinate of vertex 3) - 0 - ENDSEC - 0 - EOF - - Modified: - - 23 May 1999 - - Author: - - John Burkardt -*/ -{ - int code; - int count; - float cvec[3]; - int icor3; - char input1[LINE_MAX_LEN]; - char input2[LINE_MAX_LEN]; - int ivert; - float rval; - int width; - int linemode; - int cpos; - - linemode = 0; - ivert = 0; -/* - Read the next two lines of the file into INPUT1 and INPUT2. -*/ - - for ( ;; ) { - -/* - INPUT1 should contain a single integer, which tells what INPUT2 - will contain. -*/ - if ( fgets ( input1, LINE_MAX_LEN, filein ) == NULL ) { - break; - } - - text_num = text_num + 1; - - count = sscanf ( input1, "%d%n", &code, &width ); - if ( count <= 0 ) { - break; - } -/* - Read the second line, and interpret it according to the code. -*/ - if ( fgets ( input2, LINE_MAX_LEN, filein ) == NULL ) { - break; - } - - text_num = text_num + 1; - - if ( code == 0 ) { - - if ( ivert > 0 ) { - /* finish off the face */ - face_order[face_num] = ivert; - face_num = face_num + 1; - ivert = 0; - } - - if ( strncmp( input2, "LINE", 4 ) == 0 ) { - linemode = 1; - } - else if ( strncmp( input2, "3DFACE", 6 ) == 0 ) { - linemode = 0; - ivert = 0; - } - } - else { - - for (cpos = 0; input1[cpos] == ' '; cpos++) - {}; - - if ( input1[cpos] == '1' || input1[cpos] == '2' || input1[cpos] == '3' ) { - - count = sscanf ( input2, "%e%n", &rval, &width ); - - switch ( input1[cpos] ) - { - case '1': - if ( line_num > 0 ) { - if ( linemode ) { - line_dex[line_num] = - 1; - line_material[line_num] = - 1; - line_num = line_num + 1; - } - } - cvec[0] = rval; - break; - - case '2': - cvec[1] = rval; - break; - - case '3': - cvec[2] = rval; - - if ( cor3_num < 1000 ) { - icor3 = rcol_find ( cor3, 3, cor3_num, cvec ); - } - else { - icor3 = -1; - } - - if ( icor3 == -1 ) { - icor3 = cor3_num; - if ( cor3_num < COR3_MAX ) { - cor3[0][cor3_num] = cvec[0]; - cor3[1][cor3_num] = cvec[1]; - cor3[2][cor3_num] = cvec[2]; - } - cor3_num = cor3_num + 1; - } - else { - dup_num = dup_num + 1; - } - - if ( linemode ) { - line_dex[line_num] = icor3; - line_material[line_num] = 0; - line_num = line_num + 1; - } - else { - face[ivert][face_num] = icor3; - ivert = ivert + 1; - } - break; - - default: - break; - } - } - } - } - - if ( line_num > 0 ) { - if ( linemode ) { - line_dex[line_num] = - 1; - line_material[line_num] = - 1; - line_num = line_num + 1; - } - } - return SUCCESS; -} -/******************************************************************************/ - -int dxf_write ( FILE *fileout ) - -/******************************************************************************/ - -/* - Purpose: - - DXF_WRITE writes graphics information to an AutoCAD DXF file. - - Examples: - - 0 - SECTION - 2 - HEADER - 999 - diamond.dxf created by IVREAD. - 999 - Original data in diamond.obj. - 0 - ENDSEC - 0 - SECTION - 2 - TABLES - 0 - ENDSEC - 0 - SECTION - 2 - BLOCKS - 0 - ENDSEC - 0 - SECTION - 2 - ENTITIES - 0 - LINE - 8 - 0 - 10 - 0.00 (X coordinate of beginning of line.) - 20 - 0.00 (Y coordinate of beginning of line.) - 30 - 0.00 (Z coordinate of beginning of line.) - 11 - 1.32 (X coordinate of end of line.) - 21 - 1.73 (Y coordinate of end of line.) - 31 - 2.25 (Z coordinate of end of line.) - 0 - 3DFACE - 8 - Cube - 10 - -0.50 (X coordinate of vertex 1) - 20 - 0.50 (Y coordinate of vertex 1) - 30 - 1.0 (Z coordinate of vertex 1) - 11 - 0.50 (X coordinate of vertex 2) - 21 - 0.50 (Y coordinate of vertex 2) - 31 - 1.0 (Z coordinate of vertex 2) - 12 - 0.50 (X coordinate of vertex 3) - 22 - 0.50 (Y coordinate of vertex 3) - 32 - 0.00 (Z coordinate of vertex 3) - 0 - ENDSEC - 0 - EOF - - Modified: - - 16 May 1999 - - Author: - - John Burkardt -*/ -{ - int icor3; - int iline; - int iface; - int ivert; - int jcor3; - int newline; - int text_num; - -/* - Initialize. -*/ - text_num = 0; - - fprintf ( fileout, " 0\n" ); - fprintf ( fileout, "SECTION\n" ); - fprintf ( fileout, " 2\n" ); - fprintf ( fileout, "HEADER\n" ); - fprintf ( fileout, "999\n" ); - fprintf ( fileout, "%s created by IVCON.\n", fileout_name ); - fprintf ( fileout, "999\n" ); - fprintf ( fileout, "Original data in %s.\n", filein_name ); - fprintf ( fileout, " 0\n" ); - fprintf ( fileout, "ENDSEC\n" ); - text_num = text_num + 10; - - fprintf ( fileout, " 0\n" ); - fprintf ( fileout, "SECTION\n" ); - fprintf ( fileout, " 2\n" ); - fprintf ( fileout, "TABLES\n" ); - fprintf ( fileout, " 0\n" ); - fprintf ( fileout, "ENDSEC\n" ); - text_num = text_num + 6; - - fprintf ( fileout, " 0\n" ); - fprintf ( fileout, "SECTION\n" ); - fprintf ( fileout, " 2\n" ); - fprintf ( fileout, "BLOCKS\n" ); - fprintf ( fileout, " 0\n" ); - fprintf ( fileout, "ENDSEC\n" ); - text_num = text_num + 6; - - fprintf ( fileout, " 0\n" ); - fprintf ( fileout, "SECTION\n" ); - fprintf ( fileout, " 2\n" ); - fprintf ( fileout, "ENTITIES\n" ); - text_num = text_num + 4; -/* - Handle lines. -*/ - jcor3 = 0; - newline = TRUE; - - for ( iline = 0; iline < line_num; iline++ ) { - - icor3 = line_dex[iline]; - - if ( icor3 == -1 ) { - - newline = TRUE; - } - else { - - if ( newline == FALSE ) { - - fprintf ( fileout, " 0\n" ); - fprintf ( fileout, "LINE\n" ); - fprintf ( fileout, " 8\n" ); - fprintf ( fileout, " 0\n" ); - fprintf ( fileout, " 10\n" ); - fprintf ( fileout, "%f\n", cor3[0][jcor3] ); - fprintf ( fileout, " 20\n" ); - fprintf ( fileout, "%f\n", cor3[1][jcor3] ); - fprintf ( fileout, " 30\n" ); - fprintf ( fileout, "%f\n", cor3[2][jcor3] ); - fprintf ( fileout, " 11\n" ); - fprintf ( fileout, "%f\n", cor3[0][icor3] ); - fprintf ( fileout, " 21\n" ); - fprintf ( fileout, "%f\n", cor3[1][icor3] ); - fprintf ( fileout, " 31\n" ); - fprintf ( fileout, "%f\n", cor3[2][icor3] ); - - text_num = text_num + 16; - - } - - jcor3 = icor3; - newline = FALSE; - - } - } -/* - Handle faces. - (If FACE_ORDER is greater than 10, you're sure to have problems here) -*/ - for ( iface = 0; iface < face_num; iface++ ) { - - fprintf ( fileout, " 0\n" ); - fprintf ( fileout, "3DFACE\n" ); - fprintf ( fileout, " 8\n" ); - fprintf ( fileout, " Cube\n" ); - text_num = text_num + 4; - - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - - icor3 = face[ivert][iface]; - - fprintf ( fileout, "1%d\n", ivert ); - fprintf ( fileout, "%f\n", cor3[0][icor3] ); - fprintf ( fileout, "2%d\n", ivert ); - fprintf ( fileout, "%f\n", cor3[1][icor3] ); - fprintf ( fileout, "3%d\n", ivert ); - fprintf ( fileout, "%f\n", cor3[2][icor3] ); - - text_num = text_num + 6; - } - } - - fprintf ( fileout, " 0\n" ); - fprintf ( fileout, "ENDSEC\n" ); - fprintf ( fileout, " 0\n" ); - fprintf ( fileout, "EOF\n" ); - text_num = text_num + 4; -/* - Report. -*/ - printf ( "\n" ); - printf ( "DXF_WRITE - Wrote %d text lines.\n", text_num ); - - return SUCCESS; -} -/**********************************************************************/ - -void edge_null_delete ( void ) - -/**********************************************************************/ - -/* - Purpose: - - EDGE_NULL_DELETE deletes face edges with zero length. - - Modified: - - 16 July 1999 - - Author: - - John Burkardt -*/ -{ - float distsq; - int face2[ORDER_MAX]; - int face_order2; - int iface; - int inode; - int ivert; - int j; - int jnode; - int jvert; - int edge_num; - int edge_num_del; - float vertex_normal2[3][ORDER_MAX]; - float x; - float y; - float z; - - edge_num = 0; - edge_num_del = 0; -/* - Consider each face. -*/ - for ( iface = 0; iface < face_num; iface++ ) { -/* - Consider each pair of consecutive vertices. -*/ - face_order2 = 0; - - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - - edge_num = edge_num + 1; - - jvert = ivert + 1; - if ( jvert >= face_order[iface] ) { - jvert = 0; - } - - inode = face[ivert][iface]; - jnode = face[jvert][iface]; - - - x = cor3[0][inode] - cor3[0][jnode]; - y = cor3[1][inode] - cor3[1][jnode]; - z = cor3[2][inode] - cor3[2][jnode]; - - distsq = x * x + y * y + z * z; - - if ( distsq != 0.0 ) { - face2[face_order2] = face[ivert][iface]; - vertex_normal2[0][face_order2] = vertex_normal[0][ivert][iface]; - vertex_normal2[1][face_order2] = vertex_normal[1][ivert][iface]; - vertex_normal2[2][face_order2] = vertex_normal[2][ivert][iface]; - face_order2 = face_order2 + 1; - } - else { - edge_num_del = edge_num_del + 1; - } - - } - - face_order[iface] = face_order2; - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - face[ivert][iface] = face2[ivert]; - for ( j = 0; j < 3; j++ ) { - vertex_normal[j][ivert][iface] = vertex_normal2[j][ivert]; - } - } - - } - - printf ( "\n" ); - printf ( "EDGE_NULL_DELETE:\n" ); - printf ( " There are a total of %d edges.\n", edge_num ); - printf ( " Of these, %d were of zero length, and deleted.\n", edge_num_del ); - - return; -} -/**********************************************************************/ - -void face_area_set ( void ) - -/**********************************************************************/ - -/* - Purpose: - - FACE_AREA_SET computes the area of the faces. - - Formula: - - The area is the sum of the areas of the triangles formed by - node N with consecutive pairs of nodes. - - Reference: - - Adrian Bowyer and John Woodwark, - A Programmer's Geometry, - Butterworths, 1983. - - Modified: - - 17 July 1999 - - Author: - - John Burkardt -*/ -{ - float alpha; - float area_max; - float area_min; - float area_tri; - float base; - float dot; - float height; - int i; - int i1; - int i2; - int i3; - int iface; - int face_num_del; - float tol; - float x; - float x1; - float x2; - float x3; - float y; - float y1; - float y2; - float y3; - float z; - float z1; - float z2; - float z3; - - for ( iface = 0; iface < face_num; iface++ ) { - - face_area[iface] = 0.0; - - for ( i = 0; i < face_order[iface]-2; i++ ) { - - i1 = face[i][iface]; - i2 = face[i+1][iface]; - i3 = face[i+2][iface]; - - x1 = cor3[0][i1]; - y1 = cor3[1][i1]; - z1 = cor3[2][i1]; - - x2 = cor3[0][i2]; - y2 = cor3[1][i2]; - z2 = cor3[2][i2]; - - x3 = cor3[0][i3]; - y3 = cor3[1][i3]; - z3 = cor3[2][i3]; -/* - Find the projection of (P3-P1) onto (P2-P1). -*/ - dot = - ( x2 - x1 ) * ( x3 - x1 ) + - ( y2 - y1 ) * ( y3 - y1 ) + - ( z2 - z1 ) * ( z3 - z1 ); - - base = sqrt ( - ( x2 - x1 ) * ( x2 - x1 ) - + ( y2 - y1 ) * ( y2 - y1 ) - + ( z2 - z1 ) * ( z2 - z1 ) ); -/* - The height of the triangle is the length of (P3-P1) after its - projection onto (P2-P1) has been subtracted. -*/ - if ( base == 0.0 ) { - height = 0.0; - } - else { - - alpha = dot / ( base * base ); - - x = x3 - x1 - alpha * ( x2 - x1 ); - y = y3 - y1 - alpha * ( y2 - y1 ); - z = z3 - z1 - alpha * ( z2 - z1 ); - - height = sqrt ( x * x + y * y + z * z ); - - } - - area_tri = 0.5 * base * height; - - face_area[iface] = face_area[iface] + area_tri; - - } - - } - - area_min = face_area[0]; - area_max = face_area[0]; - - for ( iface = 1; iface < face_num; iface++ ) { - if ( area_min > face_area[iface] ) { - area_min = face_area[iface]; - } - if ( area_max < face_area[iface] ) { - area_max = face_area[iface]; - } - } - - printf ( "\n" ); - printf ( "FACE_AREA_SET:\n" ); - printf ( " Minimum face area is %f\n", area_min ); - printf ( " Maximum face area is %f\n", area_max ); - - tol = area_max / 10000.0; - - if ( area_min < tol ) { - - face_num_del = 0; - - for ( iface = 0; iface < face_num; iface++ ) { - if ( face_area[iface] < tol ) { - face_order[iface] = 0; - face_num_del = face_num_del + 1; - } - } - - printf ( " Marked %d tiny faces for deletion.\n", face_num_del ); - - } - - return; -} -/******************************************************************************/ - -void face_normal_ave ( void ) - -/******************************************************************************/ - -/* - Purpose: - - FACE_NORMAL_AVE sets face normals as average of face vertex normals. - - Modified: - - 09 October 1998 - - Author: - - John Burkardt -*/ -{ - int i; - int iface; - int ivert; - int nfix; - float norm; - float x; - float y; - float z; - - if ( face_num <= 0 ) { - return; - } - - nfix = 0; - - for ( iface = 0; iface < face_num; iface++ ) { - -/* - Check the norm of the current normal vector. -*/ - x = face_normal[0][iface]; - y = face_normal[1][iface]; - z = face_normal[2][iface]; - norm = ( float ) sqrt ( x * x + y * y + z * z ); - - if ( norm == 0.0 ) { - - nfix = nfix + 1; - - for ( i = 0; i < 3; i++ ) { - face_normal[i][iface] = 0.0; - } - - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - for ( i = 0; i < 3; i++ ) { - face_normal[i][iface] = face_normal[i][iface] + - vertex_normal[i][ivert][iface]; - } - } - - x = face_normal[0][iface]; - y = face_normal[1][iface]; - z = face_normal[2][iface]; - norm = ( float ) sqrt ( x * x + y * y + z * z ); - - if ( norm == 0.0 ) { - for ( i = 0; i < 3; i++ ) { - face_normal[i][iface] = ( float ) ( 1.0 / sqrt ( 3.0 ) ); - } - } - else { - for ( i = 0; i < 3; i++ ) { - face_normal[i][iface] = face_normal[i][iface] / norm; - } - } - } - } - - if ( nfix > 0 ) { - printf ( "\n" ); - printf ( "FACE_NORMAL_AVE: Recomputed %d face normals\n", nfix ); - printf ( " by averaging face vertex normals.\n" ); - } - return; -} -/**********************************************************************/ - -void face_null_delete ( void ) - -/**********************************************************************/ - -/* - Purpose: - - FACE_NULL_DELETE deletes faces of order less than 3. - - Comments: - - Thanks to Susan M. Fisher, University of North Carolina, - Department of Computer Science, for pointing out a coding error - in FACE_NULL_DELETE that was overwriting all the data! - - Modified: - - 30 November 1999 - - Author: - - John Burkardt -*/ -{ - int iface; - int ivert; - int j; - int face_num2; -/* - FACE_NUM2 is the number of faces we'll keep. -*/ - face_num2 = 0; -/* - Check every face. -*/ - for ( iface = 0; iface < face_num; iface++ ) { -/* - Keep it only if it has order 3 or more. -*/ - if ( face_order[iface] >= 3 ) { -/* - We don't have to slide data down in the array until - NUMFACE2 and IFACE get out of synch, that is, after - we've discarded at least one face. -*/ - if ( face_num2 != iface ) { - - face_area[face_num2] = face_area[iface]; - face_material[face_num2] = face_material[iface]; - face_order[face_num2] = face_order[iface]; - for ( ivert = 0; ivert < ORDER_MAX; ivert++ ) { - face[ivert][face_num2] = face[ivert][iface]; - vertex_material[ivert][face_num2] = vertex_material[ivert][iface]; - for ( j = 0; j < 3; j++ ) { - vertex_normal[j][ivert][face_num2] = vertex_normal[j][ivert][iface]; - } - } - - } -/* - Update the count only after we've used the un-incremented value - as a pointer. -*/ - face_num2 = face_num2 + 1; - - } - - } - - printf ( "\n" ); - printf ( "FACE_NULL_DELETE\n" ); - printf ( " There are a total of %d faces.\n", face_num ); - printf ( " Of these, %d passed the order test.\n", face_num2 ); - - face_num = face_num2; - - return; -} -/******************************************************************************/ - -int face_print ( int iface ) - -/******************************************************************************/ - -/* - Purpose: - - FACE_PRINT prints out information about a face. - - Modified: - - 31 August 1998 - - Author: - - John Burkardt -*/ -{ - int ivert; - int j; - int k; - - if ( iface < 0 || iface > face_num-1 ) { - printf ( "\n" ); - printf ( "FACE_PRINT - Fatal error!\n" ); - printf ( " Face indices must be between 1 and %d\n", face_num ); - printf ( " But your requested value was %d\n", iface ); - return ERROR; - } - - printf ( "\n" ); - printf ( "FACE_PRINT\n" ); - printf ( " Information about face %d\n", iface ); - printf ( "\n" ); - printf ( " Number of vertices is %d\n", face_order[iface] ); - printf ( "\n" ); - printf ( " Vertex list:\n" ); - printf ( " Vertex #, Node #, Material #, X, Y, Z:\n" ); - printf ( "\n" ); - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - j = face[ivert][iface]; - k = vertex_material[ivert][iface]; - printf ( " %d %d %d %f %f %f\n", ivert, j, k, cor3[0][j], cor3[1][j], - cor3[2][j] ); - } - - printf ( "\n" ); - printf ( " Face normal vector:\n" ); - printf ( "\n" ); - printf ( " %f %f %f\n", face_normal[0][iface], face_normal[1][iface], - face_normal[2][iface] ); - - printf ( "\n" ); - printf ( " Vertex face normals:\n" ); - printf ( "\n" ); - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - printf ( " %d %f %f %f\n", ivert, vertex_normal[0][ivert][iface], - vertex_normal[1][ivert][iface], vertex_normal[2][ivert][iface] ); - } - - return SUCCESS; - -} -/**********************************************************************/ - -void face_reverse_order ( void ) - -/**********************************************************************/ - -/* - Purpose: - - FACE_REVERSE_ORDER reverses the order of the nodes in each face. - - Discussion: - - Reversing the order of the nodes requires that the normal vectors - be reversed as well, so this routine will automatically reverse - the normals associated with nodes, vertices and faces. - - Modified: - - 28 June 1999 - - Author: - - John Burkardt -*/ -{ - int i; - int iface; - int itemp; - int ivert; - int j; - int m; - float temp; - - for ( iface = 0; iface < face_num; iface++ ) { - - m = face_order[iface]; - - for ( ivert = 0; ivert < ( m / 2 ); ivert++ ) { - - itemp = face[ivert][iface]; - face[ivert][iface] = face[m-1-ivert][iface]; - face[m-1-ivert][iface] = itemp; - - itemp = vertex_material[ivert][iface]; - vertex_material[ivert][iface] = vertex_material[m-1-ivert][iface]; - vertex_material[m-1-ivert][iface] = itemp; - - for ( j = 0; j < 3; j++ ) { - temp = vertex_normal[j][ivert][iface]; - vertex_normal[j][ivert][iface] = vertex_normal[j][m-1-ivert][iface]; - vertex_normal[j][m-1-ivert][iface] = temp; - } - - for ( j = 0; j < 2; j++ ) { - temp = vertex_tex_uv[j][ivert][iface]; - vertex_tex_uv[j][ivert][iface] = vertex_tex_uv[j][m-1-ivert][iface]; - vertex_tex_uv[j][m-1-ivert][iface] = temp; - } - - } - - } - - for ( i = 0; i < cor3_num; i++ ) { - for ( j = 0; j < 3; j++ ) { - cor3_normal[j][i] = - cor3_normal[j][i]; - } - } - - for ( i = 0; i < face_num; i++ ) { - for ( j = 0; j < 3; j++ ) { - face_normal[j][i] = - face_normal[j][i]; - } - } - - printf ( "\n" ); - printf ( "FACE_REVERSE_ORDER\n" ); - printf ( " Each list of nodes defining a face\n" ); - printf ( " has been reversed; related information,\n" ); - printf ( " including normal vectors, was also updated.\n" ); - - return; -} - -/******************************************************************************/ - -int face_subset ( void ) - -/******************************************************************************/ - -/* - Purpose: - - FACE_SUBSET selects a subset of the current faces as the new object. - - Warning: - - The original graphic object is overwritten by the new one. - - Modified: - - 12 October 1998 - - Author: - - John Burkardt - -*/ -{ - int i; - int iface; - int iface1; - int iface2; - int inc; - int ivert; - int j; - int k; - int cor3_num2; - - line_num = 0; -/* - Get the first and last faces to save, IFACE1 and IFACE2. -*/ - printf ( "\n" ); - printf ( "Enter lowest face number to save between 0 and %d:\n", face_num-1 ); - scanf ( "%d", &iface1 ); - if ( iface1 < 0 || iface1 > face_num - 1 ) { - printf ( "Illegal choice!\n" ); - return ERROR; - } - - printf ( "\n" ); - printf ( "Enter highest face number to save between %d and %d:\n", - iface1, face_num-1 ); - scanf ( "%d", &iface2 ); - if ( iface2 < iface1 || iface2 > face_num - 1 ) { - printf ( "Illegal choice!\n" ); - return ERROR; - } - - inc = iface1; -/* - "Slide" the data for the saved faces down the face arrays. -*/ - for ( iface = 0; iface < iface2 + 1 - iface1; iface++ ) { - face_order[iface] = face_order[iface+inc]; - for ( ivert = 0; ivert < ORDER_MAX; ivert++ ) { - face[ivert][iface] = face[ivert][iface+inc]; - vertex_material[ivert][iface] = vertex_material[ivert][iface+inc]; - for ( i = 0; i < 3; i++ ) { - vertex_normal[i][ivert][iface] = - vertex_normal[i][ivert][iface+inc]; - vertex_rgb[i][ivert][iface] = vertex_rgb[i][ivert][iface+inc]; - } - } - for ( i = 0; i < 3; i++ ) { - face_normal[i][iface] = face_normal[i][iface+inc]; - } - } -/* - Now reset the number of faces. -*/ - face_num = iface2 + 1 - iface1; -/* - Now, for each point I, set LIST(I) = J if point I is the J-th - point we are going to save, and 0 otherwise. Then J will be - the new label of point I. -*/ - for ( i = 0; i < cor3_num; i++ ) { - list[i] = -1; - } - - cor3_num2 = 0; - - for ( iface = 0; iface < face_num; iface++ ){ - for ( ivert = 0; ivert < face_order[iface]; ivert++ ){ - j = face[ivert][iface]; - if ( list[j] == -1 ) { - cor3_num2 = cor3_num2 + 1; - list[j] = cor3_num2; - } - } - } -/* - Now make the nonzero list entries rise in order, so that - we can compress the COR3 data in a minute. -*/ - cor3_num2 = 0; - - for ( i = 0; i < cor3_num; i++ ) { - if ( list[i] != -1 ) { - list[i] = cor3_num2; - cor3_num2 = cor3_num2 + 1; - } - } -/* - Relabel the FACE array with the new node indices. -*/ - for ( iface = 0; iface < face_num; iface++ ){ - for ( ivert = 0; ivert < face_order[iface]; ivert++ ){ - j = face[ivert][iface]; - face[ivert][iface] = list[j]; - } - } -/* - Rebuild the COR3 array by sliding data down. -*/ - for ( i = 0; i < cor3_num; i++ ){ - k = list[i]; - if ( k != -1 ) { - for ( j = 0; j < 3; j++ ) { - cor3[j][k] = cor3[j][i]; - } - } - } - - cor3_num = cor3_num2; - - return SUCCESS; -} -/**********************************************************************/ - -void face_to_line ( void ) - -/**********************************************************************/ - -/* - Purpose: - - FACE_TO_LINE converts face information to line information. - - Discussion: - - In some cases, the graphic information represented by polygonal faces - must be converted to a representation based solely on line segments. - This is particularly true if a VLA file is being written. - - Modified: - - 26 May 1999 - - Author: - - John Burkardt -*/ -{ - int icor3; - int iface; - int ivert; - int jcor3; - int jvert; -/* - Case 0: - No line pruning. -*/ - if ( line_prune == 0 ) { - - for ( iface = 0; iface < face_num; iface++ ) { - - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - - icor3 = face[ivert][iface]; - - line_num = line_num + 1; - if ( line_num <= LINES_MAX ) { - line_dex[line_num] = icor3; - line_material[line_num] = vertex_material[ivert][iface]; - } - } - - ivert = 0; - icor3 = face[ivert][iface]; - - line_num = line_num + 1; - if ( line_num <= LINES_MAX ) { - line_dex[line_num] = icor3; - line_material[line_num] = vertex_material[ivert][iface]; - } - - line_num = line_num + 1; - if ( line_num <= LINES_MAX ) { - line_dex[line_num] = -1; - line_material[line_num] = -1; - } - } - - } -/* - Case 2: - Simple-minded line pruning. - Only draw line (I,J) if I < J. -*/ - else { - - for ( iface = 0; iface < face_num; iface++ ) { - - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - - icor3 = face[ivert][iface]; - - if ( ivert + 1 < face_order[iface] ) { - jvert = ivert + 1; - } - else { - jvert = 0; - } - - jcor3 = face[jvert][iface]; - - if ( icor3 < jcor3 ) { - - if ( line_num + 3 < LINES_MAX ) { - - line_num = line_num + 1; - line_dex[line_num] = icor3; - line_material[line_num] = vertex_material[ivert][iface]; - - line_num = line_num + 1; - line_dex[line_num] = jcor3; - line_material[line_num] = vertex_material[jvert][iface]; - - line_num = line_num + 1; - line_dex[line_num] = -1; - line_material[line_num] = -1; - - } - } - } - } - - } - - return; -} -/**********************************************************************/ - -void face_to_vertex_material ( void ) - -/**********************************************************************/ - -/* - Purpose: - - FACE_TO_VERTEX_MAT extends face material definitions to vertices. - - Discussion: - - Assuming material indices are defined for all the faces, this - routine assigns to each vertex of a face the material of that face. - - Modified: - - 22 May 1999 - - Author: - - John Burkardt -*/ -{ - int iface; - int ivert; - - for ( iface = 0; iface < face_num; iface++ ) { - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - vertex_material[ivert][iface] = face_material[iface]; - } - } - - return; -} -/******************************************************************************/ - -char *file_ext ( char *file_name ) - -/******************************************************************************/ - -/* - Purpose: - - FILE_EXT picks out the extension in a file name. - - Modified: - - 21 July 1998 - - Author: - - John Burkardt -*/ -{ - int i; - - i = char_index_last ( file_name, '.' ); - - if ( i == -1 ) { - return NULL; - } - else { - return file_name + i + 1; - } -} -/******************************************************************************/ - -float float_read ( FILE *filein ) - -/******************************************************************************/ - -/* - Purpose: - - FLOAT_READ reads 1 float from a binary file. - - Modified: - - 24 May 1999 -*/ -{ - float rval; - float temp; - - fread ( &temp, sizeof ( float ), 1, filein ); - - if ( byte_swap == TRUE ) { - rval = float_reverse_bytes ( temp ); - } - else { - rval = temp; - } - - return rval; -} -/******************************************************************************/ - -float float_reverse_bytes ( float x ) - -/******************************************************************************/ - -/* - Purpose: - - FLOAT_REVERSE_BYTES reverses the four bytes in a float. - - Modified: - - 24 May 1999 - - Author: - - John Burkardt - - Parameters: - - X, a float whose bytes are to be reversed. - - FLOAT_REVERSE_BYTES, a float with bytes in reverse order from those in X. -*/ -{ - char c; - union { - float yfloat; - char ychar[4]; - } y; - - y.yfloat = x; - - c = y.ychar[0]; - y.ychar[0] = y.ychar[3]; - y.ychar[3] = c; - - c = y.ychar[1]; - y.ychar[1] = y.ychar[2]; - y.ychar[2] = c; - - return ( y.yfloat ); -} -/******************************************************************************/ - -int float_write ( FILE *fileout, float float_val ) - -/******************************************************************************/ - -/* - Purpose: - - FLOAT_WRITE writes 1 float to a binary file. - - Modified: - - 23 September 1998 -*/ -{ - int nbyte = sizeof ( float ); - float temp; - - if ( byte_swap == TRUE ) { - temp = float_reverse_bytes ( float_val ); - } - else { - temp = float_val; - } - - fwrite ( &temp, nbyte, 1, fileout ); - - return nbyte; -} -/******************************************************************************/ - -int gmod_arch_check ( void ) - -/******************************************************************************/ - -/* - Purpose: - - GMOD_ARCH_CHECK inquires into some features of the computer architecture. - - Modified: - - 19 May 1999 - - Author: - - Zik Saleeba (zik@zikzak.net) -*/ -{ - static unsigned char one[4]; - int temp; - - temp = sizeof ( float ); - if ( temp != 4 ) { - return FALSE; - } - - *(float *)one = 1.0; - - if (one[0] == 0 && one[1] == 0 && one[2] == 128 && one[3] == 63) { - /* little endian IEEE floats */ - return TRUE; - } - - if (one[0] == 63 && one[1] == 128 && one[2] == 0 && one[3] == 0) { - /* big endian IEEE floats */ - return TRUE; - } - - return FALSE; -} -/******************************************************************************/ - -int gmod_read ( FILE *filein ) - -/******************************************************************************/ - -/* - Purpose: - - GMOD_READ reads a golgotha GMOD file. - - Modified: - - 19 May 1999 - - Author: - - Zik Saleeba (zik@zikzak.net) -*/ - -/* -golgotha GMOD file format: - - - FILE HEADER - -w32 magic number f9 fa 63 1e -w32 number of sections -[ number of sections - w32 section id - w32 section offset -] - - - TEXTURE NAME SECTION - section id = 0x13 (19) - -w16 number of faces -[ number of faces - w16 texture name length - [ texture name length - w8 texture name character - ] -] - - - - MODEL QUADS SECTION - section id = 0x12 (18) - -w16 number of faces -[ number of faces - [ four vertices - w16 vertex index - float xpos (0.0-1.0) - float ypos (0.0-1.0) - ] - float scale - w16 flags - float xnormal (normal should be normalised) - float ynormal - float znormal -] - - - VERTEX ARRAY SECTION - section id = 0x14 (20) - -w16 number of vertices -w16 number of animations -w16 length of animation name -[ length of animation name - w8 animation name character -] -w16 number of frames in animation -[ number of frames in animation - [ number of vertices - float xpos - float ypos - float zpos - float xnormal - float ynormal - float znormal - ] -] -*/ -{ - unsigned char MagicNumber[4]; - unsigned long int NumSections; - int SectionCount; - unsigned long int SectionID[GMOD_MAX_SECTIONS]; - unsigned long int SectionOffset[GMOD_MAX_SECTIONS]; - - unsigned short NumAnimations; - unsigned short NumFrames; - unsigned short FaceCount; - unsigned short TextureCount; - int VertexCount; - - float Scale; - unsigned short Flags; - unsigned short TextureNameLen; - unsigned short AnimationNameLen; - int Order; - int MaxCor = 0; - - /* - * check if we can handle this architecture - */ - - if (!gmod_arch_check()) { - printf("GMOD_READ - This architecture not supported.\n"); - return ERROR; - } - - /* - * read the file header - */ - - /* read the magic number */ - fread(MagicNumber, 1, 4, filein); - if (MagicNumber[0] != 0xf9 || - MagicNumber[1] != 0xfa || - MagicNumber[2] != 0x63 || - MagicNumber[3] != 0x1e) { - printf("GMOD_READ - Bad magic number on GMOD file.\n"); - return ERROR; - } - - NumSections = gmod_read_w32(filein); - if (NumSections >= GMOD_MAX_SECTIONS) { - printf("GMOD_READ - Too many sections (%ld) in GMOD file - please increase static limit GMOD_MAX_SECTIONS\n", NumSections); - return ERROR; - } - -/* - Read the sections. -*/ - - for ( SectionCount = 0; SectionCount < ( int ) NumSections; SectionCount++ ) { - SectionID[SectionCount] = gmod_read_w32(filein); - SectionOffset[SectionCount] = gmod_read_w32(filein); - } -/* - Read each successive section. -*/ - for ( SectionCount = 0; SectionCount < ( int ) NumSections; SectionCount++ ) { -/* - Go to the start of the section. -*/ - fseek ( filein, ( long int ) SectionOffset[SectionCount], SEEK_SET ); -/* - What type of section is it? -*/ - switch (SectionID[SectionCount]) { - -/* - Model section. -*/ - case G1_SECTION_MODEL_QUADS: -/* - Get the number of faces. -*/ - face_num = gmod_read_w16 ( filein ); - - if (face_num > FACE_MAX) { - printf("GMOD_READ - Too many faces (%d) in GMOD file - please increase static limit FACE_MAX.\n", face_num); - return ERROR; - } -/* - Get the information on each face. -*/ - for ( FaceCount = 0; FaceCount < ( unsigned short ) face_num; FaceCount++ ) { - - Order = 0; - for ( VertexCount = 0; VertexCount < 4; VertexCount++ ) { - - /* read the vertex index */ - - face[VertexCount][FaceCount] = gmod_read_w16(filein); - - if (face[VertexCount][FaceCount] != GMOD_UNUSED_VERTEX) { - Order = VertexCount+1; - if (MaxCor < face[VertexCount][FaceCount]) - MaxCor = face[VertexCount][FaceCount]; - } - - /* read the texture position */ - - vertex_tex_uv[0][VertexCount][FaceCount] = gmod_read_float(filein); - vertex_tex_uv[1][VertexCount][FaceCount] = gmod_read_float(filein); - } - - /* scale and flags */ - - fread(&Scale, sizeof(Scale), 1, filein); - Flags = gmod_read_w16(filein); - - if ( debug ) { - printf ( "Flags = %d\n", Flags ); - } - - /* normal vector */ - - face_normal[0][FaceCount] = gmod_read_float(filein); - face_normal[1][FaceCount] = gmod_read_float(filein); - face_normal[2][FaceCount] = gmod_read_float(filein); - - /* the order is the number of used vertices */ - - face_order[FaceCount] = Order; - } - break; - - -/* - Texture name section. -*/ - - case G1_SECTION_MODEL_TEXTURE_NAMES: - - /* get the number of textures */ - - texture_num = gmod_read_w16(filein); - if (texture_num > TEXTURE_MAX) { - printf ( "GMOD_READ - Too many texture maps (%d) in GMOD file.\n", texture_num ); - printf ( " Increase static limit TEXTURE_MAX.\n" ); - return ERROR; - } - face_num = texture_num; - - for (TextureCount = 0; TextureCount < ( unsigned short ) texture_num; - TextureCount++) { - - /* read the texture name */ - - TextureNameLen = gmod_read_w16(filein); - fread ( texture_name[TextureCount], sizeof(char), TextureNameLen, filein); - texture_name[TextureCount][TextureNameLen] = '\0'; - } - break; - - - /* - * vertex section - */ - - case G1_SECTION_MODEL_VERT_ANIMATION: - - /* get the number of vertices */ - - cor3_num = gmod_read_w16(filein); - if (cor3_num > COR3_MAX) { - printf("GMOD_READ - Too many vertices (%d) in GMOD file - please increase static limit COR3_MAX.\n", cor3_num); - return ERROR; - } - -/* - Get the number of animations. -*/ - - NumAnimations = gmod_read_w16(filein); - - if (NumAnimations > 1) { - printf ( "GMOD_READ - Fatal error!\n" ); - printf ( " GMOD files can only handle one animation.\n" ); - printf ( " This file contains %d.\n", NumAnimations ); - return ERROR; - } - - /* read the animation name */ - AnimationNameLen = gmod_read_w16(filein); - fread ( anim_name, sizeof(char), AnimationNameLen, filein); - anim_name[AnimationNameLen] = '\0'; - - /* get the number of frames of animation */ - NumFrames = gmod_read_w16(filein); - if (NumFrames > 1) - printf("GMOD_READ - Too many frames of animation (%d) in GMOD file - will only use 1.\n", NumFrames); - - /* go through all the vertices, reading each one */ - for (VertexCount = 0; VertexCount < cor3_num; VertexCount++) { - - /* read the vertex */ - cor3[0][VertexCount] = gmod_read_float(filein); - cor3[1][VertexCount] = gmod_read_float(filein); - cor3[2][VertexCount] = gmod_read_float(filein); - - /* read the normal */ - cor3_normal[0][VertexCount] = gmod_read_float(filein); - cor3_normal[1][VertexCount] = gmod_read_float(filein); - cor3_normal[2][VertexCount] = gmod_read_float(filein); - } - break; - - default: - continue; - } - } - -/* - Set some other stray info. -*/ - line_num = 0; - -/* - Check for sanity. -*/ - if ( MaxCor >= cor3_num ) { - printf ( "GMOD_READ - Maximum coordinate index (%d)\n", MaxCor ); - printf ( " exceeded number of coordinates (%d) in GMOD file.\n", cor3_num ); - return ERROR; - } - - return SUCCESS; -} -/******************************************************************************/ - -float gmod_read_float ( FILE *filein ) - -/******************************************************************************/ - -/* - Purpose: - - GMOD_READ_FLOAT reads a float from a Golgotha GMOD file. - - Modified: - - 19 May 1999 - - Author: - - Zik Saleeba (zik@zikzak.net) -*/ -{ - int endian = 1; - unsigned char *out_pos; - int i; - float Val; - - if (*(char *)&endian == 1) { - /* we're little-endian, which is native for GMOD floats */ - fread(&Val, sizeof(Val), 1, filein); - } - else { - /* we're big-endian, flip `em */ - out_pos = (unsigned char *)&Val; - for ( i = sizeof(Val)-1; i >= 0; i-- ) { - *(out_pos+i) = fgetc(filein); - } - } - - return Val; -} -/******************************************************************************/ - -unsigned short gmod_read_w16 ( FILE *filein ) - -/******************************************************************************/ - -/* - Purpose: - - GMOD_READ_W16 reads a 16 bit word from a Golgotha GMOD file. - - Modified: - - 19 May 1999 - - Author: - - Zik Saleeba (zik@zikzak.net) -*/ -{ - unsigned char Byte1; - unsigned char Byte2; - - Byte1 = fgetc ( filein ); - Byte2 = fgetc ( filein ); - - return Byte1 | (((unsigned short)Byte2) << 8); -} -/******************************************************************************/ - -unsigned long gmod_read_w32 ( FILE *filein ) - -/******************************************************************************/ - -/* - Purpose: - - GMOD_READ_W32 reads a 32 bit word from a Golgotha GMOD file. - - Modified: - - 19 May 1999 - - Author: - - Zik Saleeba (zik@zikzak.net) -*/ -{ - unsigned char Byte1, Byte2, Byte3, Byte4; - - Byte1 = fgetc(filein); - Byte2 = fgetc(filein); - Byte3 = fgetc(filein); - Byte4 = fgetc(filein); - - return Byte1 | - (((unsigned long)Byte2) << 8) | - (((unsigned long)Byte3) << 16) | - (((unsigned long)Byte4) << 24); -} - -/******************************************************************************/ - -int gmod_write ( FILE *fileout ) { - -/******************************************************************************/ - -/* - Purpose: - - GMOD_WRITE writes a Golgotha GMOD file. - - Modified: - - 19 May 1999 - - Author: - - Zik Saleeba (zik@zikzak.net) -*/ - static unsigned char MagicNumber[4] = { 0xf9, 0xfa, 0x63, 0x1e }; - unsigned long NumSections; - unsigned long SectionHeaderPos; - unsigned long TextureNameSectionPos; - unsigned long ModelSectionPos; - unsigned long VertexSectionPos; - - int VertexCount; - int FaceCount; - int TextureCount; - unsigned long SectionCount; - float Scale; - float Min[3]; - float Max[3]; - int CorNumber; - int DimensionCount; - float MaxWidth; -/* - Check if we can handle this architecture. -*/ - - if ( !gmod_arch_check() ) { - printf("GMOD_WRITE - This architecture not supported.\n"); - return ERROR; - } - -/* - Write the file header. -*/ - -/* - Write the magic number. -*/ - fwrite ( MagicNumber, sizeof(char), 4, fileout ); - -/* - Write the number of sections. -*/ - NumSections = 3; - gmod_write_w32 ( NumSections, fileout ); - -/* - Write a dummy section header which we'll overwrite later. -*/ - SectionHeaderPos = ftell ( fileout ); - for (SectionCount = 0; SectionCount < NumSections; SectionCount++) { - gmod_write_w32 ( 0, fileout ); - gmod_write_w32 ( 0, fileout ); - } -/* - Texture name section. -*/ - -/* - Take note of where we are in the file. -*/ - TextureNameSectionPos = ftell ( fileout ); - -/* - Write the number of textures. -*/ - - gmod_write_w16 ( ( unsigned short ) face_num, fileout ); -/* - Write the texture names. -*/ - for ( TextureCount = 0; TextureCount < face_num; TextureCount++ ) { - - gmod_write_w16 ( ( unsigned short ) strlen ( texture_name[TextureCount] ), - fileout ); - - fwrite ( texture_name[TextureCount], strlen ( texture_name[TextureCount] ), - 1, fileout ); - } - -/* - Model section. -*/ - -/* - Take note of where we are in the file. -*/ - - ModelSectionPos = ftell(fileout); - -/* - Write the number of faces. -*/ - - gmod_write_w16 ( ( unsigned short ) face_num, fileout ); - -/* - Write the information on each face. -*/ - - for ( FaceCount = 0; FaceCount < face_num; FaceCount++ ) { - - for (VertexCount = 0; VertexCount < ((face_order[FaceCount] < 4) ? face_order[FaceCount] : 4); VertexCount++) { - -/* - Write the vertex index. -*/ - gmod_write_w16 ( ( unsigned short ) face[VertexCount][FaceCount], fileout ); - -/* - Write the texture position. -*/ - - gmod_write_float ( vertex_tex_uv[0][VertexCount][FaceCount], fileout ); - gmod_write_float ( vertex_tex_uv[1][VertexCount][FaceCount], fileout ); - } - -/* - Write any extra vertices which are unused. -*/ - - for ( ; VertexCount < 4; VertexCount++ ) { - -/* - Write the vertex index. -*/ - gmod_write_w16 ( GMOD_UNUSED_VERTEX, fileout ); -/* - Write the texture position. -*/ - gmod_write_float ( vertex_tex_uv[0][VertexCount][FaceCount], fileout ); - - gmod_write_float ( vertex_tex_uv[1][VertexCount][FaceCount], fileout ); - } - -/* - Scale and flags. -*/ - -/* - Find the bounding box. -*/ - - for ( DimensionCount = 0; DimensionCount < 3; DimensionCount++ ) { - - CorNumber = face[0][FaceCount]; - Min[DimensionCount] = cor3[DimensionCount][CorNumber]; - Max[DimensionCount] = cor3[DimensionCount][CorNumber]; - - for (VertexCount = 1; VertexCount < ((face_order[FaceCount] < 4) ? face_order[FaceCount] : 4); VertexCount++) { - - CorNumber = face[VertexCount][FaceCount]; - - if (Min[DimensionCount] > cor3[DimensionCount][CorNumber]) - Min[DimensionCount] = cor3[DimensionCount][CorNumber]; - - if (Max[DimensionCount] < cor3[DimensionCount][CorNumber]) - Max[DimensionCount] = cor3[DimensionCount][CorNumber]; - } - } - -/* - The scale is the "width" of the face for mipmapping - - I just take the maximum bounding box dimension. -*/ - MaxWidth = Max[0] - Min[0]; - for ( DimensionCount = 1; DimensionCount < 3; DimensionCount++ ) { - - if ( MaxWidth < Max[DimensionCount] - Min[DimensionCount] ) - MaxWidth = Max[DimensionCount] - Min[DimensionCount]; - } - - Scale = MaxWidth; - fwrite ( &Scale, sizeof(Scale), 1, fileout ); - -/* - Flags are just nothing. -*/ - gmod_write_w16 ( 0, fileout ); -/* - Normal vector. -*/ - gmod_write_float ( face_normal[0][FaceCount], fileout ); - gmod_write_float ( face_normal[1][FaceCount], fileout ); - gmod_write_float ( face_normal[2][FaceCount], fileout ); - } - -/* - Vertex section. -*/ - -/* - Take note of where we are in the file. -*/ - - VertexSectionPos = ftell ( fileout ); - -/* - Write the number of vertices. -*/ - - gmod_write_w16 ( ( unsigned short ) cor3_num, fileout ); - -/* - Write the number of animations. -*/ - - gmod_write_w16 ( 1, fileout ); - -/* - Write the animation name. -*/ - - gmod_write_w16 ( 0, fileout ); - -/* - Write the number of frames of animation. -*/ - - gmod_write_w16 ( 1, fileout ); - -/* - Go through all the vertices, writing each one. -*/ - - for ( VertexCount = 0; VertexCount < cor3_num; VertexCount++ ) { - -/* - Write the vertex. -*/ - gmod_write_float ( cor3[0][VertexCount], fileout ); - gmod_write_float ( cor3[1][VertexCount], fileout ); - gmod_write_float ( cor3[2][VertexCount], fileout ); - -/* - Write the normal. -*/ - gmod_write_float ( cor3_normal[0][VertexCount], fileout ); - gmod_write_float ( cor3_normal[1][VertexCount], fileout ); - gmod_write_float ( cor3_normal[2][VertexCount], fileout ); - } -/* - Now rewrite the section header. -*/ - -/* - Go back to the section header. -*/ - fseek ( fileout, ( long int ) SectionHeaderPos, SEEK_SET ); - -/* - Write the texture name section header. -*/ - gmod_write_w32 ( G1_SECTION_MODEL_TEXTURE_NAMES, fileout ); - gmod_write_w32 ( TextureNameSectionPos, fileout ); - -/* - Write the model section header. -*/ - gmod_write_w32 ( G1_SECTION_MODEL_QUADS, fileout ); - gmod_write_w32 ( ModelSectionPos, fileout ); - -/* - Write the vertex section header. -*/ - gmod_write_w32 ( G1_SECTION_MODEL_VERT_ANIMATION, fileout ); - gmod_write_w32 ( VertexSectionPos, fileout ); - - return SUCCESS; -} - -/******************************************************************************/ - -void gmod_write_float ( float Val, FILE *fileout ) - -/******************************************************************************/ - -/* - Purpose: - - GMOD_WRITE_FLOAT writes a float to a Golgotha GMOD file. - - Modified: - - 19 May 1999 - - Author: - - Zik Saleeba (zik@zikzak.net) -*/ -{ - int endian = 1; - unsigned char *out_pos; - int i; - - if (*(char *)&endian == 1) { - /* we're little-endian, which is native for GMOD floats */ - fwrite ( &Val, sizeof(Val), 1, fileout ); - } - else { - /* we're big-endian, flip `em */ - out_pos = (unsigned char *)&Val; - for ( i = sizeof(Val)-1; i >= 0; i-- ) { - fputc(*(out_pos+i), fileout); - } - } -} -/******************************************************************************/ - -void gmod_write_w16 ( unsigned short Val, FILE *fileout ) - -/******************************************************************************/ - -/* - Purpose: - - GMOD_WRITE_W16 writes a 16 bit word to a Golgotha GMOD file. - - Modified: - - 13 September 2000 - - Author: - - Zik Saleeba (zik@zikzak.net) -*/ -{ - unsigned char OutByte[2]; - - OutByte[0] = (unsigned char)(Val & 0xff); - OutByte[1] = (unsigned char)(Val >> 8); - - fwrite ( OutByte, sizeof(unsigned char), 2, fileout ); -} -/******************************************************************************/ - -void gmod_write_w32 ( unsigned long Val, FILE *fileout ) - -/******************************************************************************/ - -/* - Purpose: - - GMOD_WRITE writes a 32 bit word to a Golgotha GMOD file. - - Modified: - - 19 May 1999 - - Author: - - Zik Saleeba (zik@zikzak.net) -*/ -{ - unsigned char OutByte[4]; - - OutByte[0] = (unsigned char)(Val & 0xff); - OutByte[1] = (unsigned char)((Val >> 8) & 0xff); - OutByte[2] = (unsigned char)((Val >> 16) & 0xff); - OutByte[3] = (unsigned char)((Val >> 24) & 0xff); - - fwrite ( OutByte, sizeof(unsigned char), 4, fileout ); -} - -/******************************************************************************/ - -void hello ( void ) - -/******************************************************************************/ -/* - Purpose: - - HELLO prints an explanatory header message. - - Modified: - - 04 July 2000 - - Author: - - John Burkardt -*/ -{ - printf ( "\n" ); - printf ( "Hello: This is IVCON,\n" ); - printf ( " for 3D graphics file conversion.\n" ); - printf ( "\n" ); - printf ( " \".3ds\" 3D Studio Max binary;\n" ); - printf ( " \".ase\" 3D Studio Max ASCII export;\n" ); - printf ( " \".byu\" Movie.BYU surface geometry;\n" ); - printf ( " \".dxf\" DXF;\n" ); - printf ( " \".gmod\" Golgotha model;\n" ); - printf ( " \".hrc\" SoftImage hierarchy;\n" ); - printf ( " \".iv\" SGI Open Inventor;\n" ); - printf ( " \".obj\" WaveFront Advanced Visualizer;\n" ); - printf ( " \".pov\" Persistence of Vision (output only);\n" ); - printf ( " \".smf\" Michael Garland's format;\n" ); - printf ( " \".stl\" ASCII StereoLithography;\n" ); - printf ( " \".stla\" ASCII StereoLithography;\n" ); - printf ( " \".stlb\" Binary StereoLithography;\n" ); - printf ( " \".tec\" TECPLOT (output only);\n" ); - printf ( " \".tri\" [Greg Hood ASCII triangle format];\n" ); - printf ( " \".tria\" [Greg Hood ASCII triangle format];\n" ); - printf ( " \".trib\" [Greg Hood binary triangle format];\n" ); - printf ( " \".txt\" Text (output only);\n" ); - printf ( " \".ucd\" AVS UCD file(output only);\n" ); - printf ( " \".vla\" VLA;\n" ); - printf ( " \".wrl\" VRML (Virtual Reality Modeling Language) (output only).\n" ); - printf ( " \".xgl\" XML/OpenGL format (output only);\n" ); - printf ( "\n" ); - printf ( " Current limits include:\n" ); - printf ( " %d faces;\n", FACE_MAX ); - printf ( " %d line items;\n", LINES_MAX ); - printf ( " %d points;\n", COR3_MAX ); - printf ( " %d face order;\n", ORDER_MAX ); - printf ( " %d materials;\n", MATERIAL_MAX); - printf ( " %d textures.\n", TEXTURE_MAX ); - printf ( "\n" ); - printf ( " Last modification: 04 July 2000.\n" ); - printf ( "\n" ); - printf ( " Send problem reports to burkardt@psc.edu.\n" ); - - return; -} -/******************************************************************************/ - -void help ( void ) - -/******************************************************************************/ - -/* - Purpose: - - HELP prints a list of the interactive commands. - - Modified: - - 26 May 1999 - - Author: - - John Burkardt -*/ -{ - printf ( "\n" ); - printf ( "Commands:\n" ); - printf ( "\n" ); - printf ( "< file Read data from input file;\n" ); - printf ( "<< file Append data in input file to current data;\n" ); - printf ( "> file Write output file;\n" ); - printf ( "B Switch the binary file byte-swapping mode;\n" ); - printf ( "D Switch the debugging mode;\n" ); - printf ( "F Print information about one face;\n" ); - printf ( "H Print this help list;\n" ); - printf ( "I Info, print out recent changes;\n" ); - printf ( "LINES Convert face information to lines;\n" ); - printf ( "N Recompute normal vectors;\n" ); - printf ( "P Set LINE_PRUNE option.\n" ); - printf ( "Q Quit;\n" ); - printf ( "R Reverse the normal vectors.\n" ); - printf ( "S Select face subset (NOT WORKING).\n" ); - printf ( "T Transform the data.\n" ); - printf ( "W Reverse the face node ordering.\n" ); - - return; -} -/******************************************************************************/ - -int hrc_read ( FILE *filein ) - -/******************************************************************************/ - -/* - Purpose: - - HRC_READ reads graphics information from a SoftImage HRC file. - - Examples: - - HRCH: Softimage 4D Creative Environment v3.00 - - - model - { - name "cube_10x10" - scaling 1.000 1.000 1.000 - rotation 0.000 0.000 0.000 - translation 0.000 0.000 0.000 - - mesh - { - flag ( PROCESS ) - discontinuity 60.000 - - vertices 8 - { - [0] position -5.000 -5.000 -5.000 - [1] position -5.000 -5.000 5.000 - [2] position -5.000 5.000 -5.000 - [3] position -5.000 5.000 5.000 - [4] position 5.000 -5.000 -5.000 - [5] position 5.000 -5.000 5.000 - [6] position 5.000 5.000 -5.000 - [7] position 5.000 5.000 5.000 - } - - polygons 6 - { - [0] nodes 4 - { - [0] vertex 0 - normal -1.000 0.000 0.000 - uvTexture 0.000 0.000 - vertexColor 255 178 178 178 - [1] vertex 1 - normal -1.000 0.000 0.000 - uvTexture 0.000 0.000 - vertexColor 255 178 178 178 - [2] vertex 3 - normal -1.000 0.000 0.000 - uvTexture 0.000 0.000 - vertexColor 255 178 178 178 - [3] vertex 2 - normal -1.000 0.000 0.000 - uvTexture 0.000 0.000 - vertexColor 255 178 178 178 - } - material 0 - [1] nodes 4 - { - [0] vertex 1 - normal 0.000 0.000 1.000 - uvTexture 0.000 0.000 - vertexColor 255 178 178 178 - [1] vertex 5 - - ...etc..... - - [5] nodes 4 - { - [0] vertex 2 - normal 0.000 1.000 0.000 - uvTexture 0.000 0.000 - vertexColor 255 178 178 178 - [1] vertex 3 - normal 0.000 1.000 0.000 - uvTexture 0.000 0.000 - vertexColor 255 178 178 178 - [2] vertex 7 - normal 0.000 1.000 0.000 - uvTexture 0.000 0.000 - vertexColor 255 178 178 178 - [3] vertex 6 - normal 0.000 1.000 0.000 - uvTexture 0.000 0.000 - vertexColor 255 178 178 178 - } - material 0 - } - - edges 12 - { - [1] vertices 3 2 - [2] vertices 2 0 - [3] vertices 0 1 - [4] vertices 1 3 - [5] vertices 7 3 - [6] vertices 1 5 - [7] vertices 5 7 - [8] vertices 6 7 - [9] vertices 5 4 - [10] vertices 4 6 - [11] vertices 2 6 - [12] vertices 4 0 - } - } - - material [0] - { - name "kazoo" - type PHONG - ambient 0.0 1.0 0.0 - diffuse 1.0 0.0 0.0 - specular 0.0 0.0 1.0 - exponent 50.0 - reflectivity 0.0 - transparency 0.0 - refracIndex 1.0 - glow 0 - coc 0.0 - } - - texture [0] - { - name "/usr/users/foss/HOUSE/PICTURES/mellon" - glbname "t2d1" - anim STATIC - method XY - repeat 1 1 - scaling 1.000 1.000 - offset 0.000 0.000 - pixelInterp - effect INTENSITY - blending 1.000 - ambient 0.977 - diffuse 1.000 - specular 0.966 - reflect 0.000 - transp 0.000 - roughness 0.000 - reflMap 1.000 - rotation 0.000 - txtsup_rot 0.000 0.000 0.000 - txtsup_trans 0.000 0.000 0.000 - txtsup_scal 1.000 1.000 1.000 - } - } - - Modified: - - 25 June 1999 - - Author: - - John Burkardt -*/ -{ - float b; - int count; - float g; - int i; - int icor3; - int ivert; - int iword; - int jval; - int level; - char *next; - int nlbrack; - int nrbrack; - int cor3_num_old; - float r; - float t; - float temp[3]; - int width; - char word[LINE_MAX_LEN]; - char word1[LINE_MAX_LEN]; - char word2[LINE_MAX_LEN]; - char wordm1[LINE_MAX_LEN]; - float x; - float y; - float z; - - level = 0; - strcpy ( level_name[0], "Top" ); - nlbrack = 0; - nrbrack = 0; - cor3_num_old = cor3_num; - strcpy ( word, " " ); - strcpy ( wordm1, " " ); -/* - Read a line of text from the file. -*/ - for ( ;; ) { - - if ( fgets ( input, LINE_MAX_LEN, filein ) == NULL ) { - break; - } - - text_num = text_num + 1; - next = input; - iword = 0; -/* - Read a word from the line. -*/ - for ( ;; ) { - - strcpy ( wordm1, word ); - - count = sscanf ( next, "%s%n", word2, &width ); - next = next + width; - - if ( count <= 0 ) { - break; - } - - strcpy ( word, word2 ); - - iword = iword + 1; - - if ( iword == 1 ) { - strcpy ( word1, word ); - } -/* - The first line of the file must be the header. -*/ - if ( text_num == 1 ) { - - if ( strcmp ( word1, "HRCH:" ) != 0 ) { - printf ( "\n" ); - printf ( "HRC_READ - Fatal error!\n" ); - printf ( " The input file has a bad header.\n" ); - return ERROR; - } - else { - comment_num = comment_num + 1; - } - break; - } -/* - If the word is a curly bracket, count it. -*/ - if ( strcmp ( word, "{" ) == 0 ) { - nlbrack = nlbrack + 1; - level = nlbrack - nrbrack; - strcpy ( level_name[level], wordm1 ); - if ( debug ) { - printf ( "New level: %s\n", level_name[level] ); - } - } - else if ( strcmp ( word, "}" ) == 0 ) { - nrbrack = nrbrack + 1; - - if ( nlbrack < nrbrack ) { - printf ( "\n" ); - printf ( "HRC_READ - Fatal error!\n" ); - printf ( " Extraneous right bracket on line %d.\n", text_num ); - printf ( " Currently processing field %s\n.", level_name[level] ); - return ERROR; - } - } -/* - CONTROLPOINTS -*/ - if ( strcmp ( level_name[level], "controlpoints" ) == 0 ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - - if ( line_num < LINES_MAX ) { - line_dex[line_num] = -1; - line_material[line_num] = 0; - } - line_num = line_num + 1; - level = nlbrack - nrbrack; - } - else if ( word[0] == '[' ) { - } - else if ( strcmp ( word, "position" ) == 0 ) { - - count = sscanf ( next, "%f%n", &x, &width ); - next = next + width; - - count = sscanf ( next, "%f%n", &y, &width ); - next = next + width; - - count = sscanf ( next, "%f%n", &z, &width ); - next = next + width; - - temp[0] = x; - temp[1] = y; - temp[2] = z; - - if ( cor3_num < 1000 ) { - icor3 = rcol_find ( cor3, 3, cor3_num, temp ); - } - else { - icor3 = -1; - } - - if ( icor3 == -1 ) { - - icor3 = cor3_num; - if ( cor3_num < COR3_MAX ) { - cor3[0][cor3_num] = x; - cor3[1][cor3_num] = y; - cor3[2][cor3_num] = z; - } - cor3_num = cor3_num + 1; - - } - else { - dup_num = dup_num + 1; - } - - if ( line_num < LINES_MAX ) { - line_dex[line_num] = icor3; - line_material[line_num] = 0; - } - line_num = line_num + 1; - } - else { - bad_num = bad_num + 1; - printf ( "CONTROLPOINTS: Bad data %s\n", word ); - return ERROR; - } - - } -/* - EDGES -*/ - else if ( strcmp ( level_name[level], "edges" ) == 0 ) { - - if ( strcmp( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( word[0] == '[' ) { - } - else if ( strcmp ( word, "vertices" ) == 0 ) { - - count = sscanf ( next, "%d%n", &jval, &width ); - next = next + width; - - if ( line_num < LINES_MAX ) { - line_dex[line_num] = jval + cor3_num_old; - line_material[line_num] = 0; - } - line_num = line_num + 1; - - count = sscanf ( next, "%d%n", &jval, &width ); - next = next + width; - - if ( line_num < LINES_MAX ) { - line_dex[line_num] = jval + cor3_num_old; - line_material[line_num] = 0; - } - line_num = line_num + 1; - - if ( line_num < LINES_MAX ) { - line_dex[line_num] = -1; - line_material[line_num] = -1; - } - line_num = line_num + 1; - - } - else { - bad_num = bad_num + 1; - printf ( "EDGES: Bad data %s\n", word ); - return ERROR; - } - - } -/* - MATERIAL -*/ - else if ( strcmp ( level_name[level], "material" ) == 0 ) { - - if ( strcmp ( word, "{" ) == 0 ) { - material_num = material_num + 1; - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( word[0] == '[' ) { - } - else if ( strcmp ( word, "ambient" ) == 0 ) { - } - else if ( strcmp ( word, "coc" ) == 0 ) { - } - else if ( strcmp ( word, "diffuse" ) == 0 ) { - - count = sscanf ( next, "%f%n", &r, &width ); - next = next + width; - material_rgba[0][material_num-1] = r; - - count = sscanf ( next, "%f%n", &g, &width ); - next = next + width; - material_rgba[0][material_num-1] = g; - - count = sscanf ( next, "%f%n", &b, &width ); - next = next + width; - material_rgba[0][material_num-1] = b; - - } - else if ( strcmp ( word, "exponent" ) == 0 ) { - } - else if ( strcmp ( word, "glow" ) == 0 ) { - } - else if ( strcmp ( word, "name" ) == 0 ) { - count = sscanf ( next, "%s%n", word, &width ); - next = next + width; - strcpy ( material_name[material_num-1], word ); - } - else if ( strcmp ( word, "reflectivity" ) == 0 ) { - } - else if ( strcmp ( word, "refracindex" ) == 0 ) { - } - else if ( strcmp ( word, "specular" ) == 0 ) { - } - else if ( strcmp ( word, "transparency" ) == 0 ) { - count = sscanf ( next, "%f%n", &t, &width ); - next = next + width; - material_rgba[3][material_num-1] = 1.0 - t; - } - else if ( strcmp ( word, "type" ) == 0 ) { - } - else { - bad_num = bad_num + 1; - printf ( "MATERIAL: Bad data %s\n", word ); - return ERROR; - } - } -/* - MESH -*/ - else if ( strcmp ( level_name[level], "mesh" ) == 0 ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( strcmp ( word, "discontinuity" ) == 0 ) { - break; - } - else if ( strcmp ( word, "edges" ) == 0 ) { - break; - } - else if ( strcmp ( word, "flag" ) == 0 ) { - break; - } - else if ( strcmp ( word, "polygons" ) == 0 ) { - break; - } - else if ( strcmp ( word, "vertices" ) == 0 ) { - break; - } - else { - bad_num = bad_num + 1; - printf ( "MESH: Bad data %s\n", word ); - return ERROR; - } - - } -/* - MODEL -*/ - else if ( strcmp ( level_name[level], "model" ) == 0 ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( strcmp ( word, "material" ) == 0 ) { - break; - } - else if ( strcmp ( word, "mesh" ) == 0 ) { - break; - } - else if ( strcmp ( word, "name" ) == 0 ) { - break; - } - else if ( strcmp ( word, "patch" ) == 0 ) { - break; - } - else if ( strcmp ( word, "rotation" ) == 0 ) { - break; - } - else if ( strcmp ( word, "scaling" ) == 0 ) { - break; - } - else if ( strcmp ( word, "spline" ) == 0 ) { - break; - } - else if ( strcmp ( word, "translation" ) == 0 ) { - break; - } - else { - bad_num = bad_num + 1; - printf ( "MODEL: Bad data %s\n", word ); - return ERROR; - } - - } -/* - NODES -*/ - else if ( strcmp ( level_name[level], "nodes" ) == 0 ) { - - if ( strcmp ( word, "{" ) == 0 ) { - ivert = 0; - face_order[face_num] = 0; - face_num = face_num + 1; - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( word[0] == '[' ) { - } - else if ( strcmp ( word, "normal" ) == 0 ) { - - count = sscanf ( next, "%f%n", &x, &width ); - next = next + width; - - count = sscanf ( next, "%f%n", &y, &width ); - next = next + width; - - count = sscanf ( next, "%f%n", &z, &width ); - next = next + width; - - if ( ivert < ORDER_MAX && face_num < FACE_MAX ) { - vertex_normal[0][ivert-1][face_num-1] = x; - vertex_normal[1][ivert-1][face_num-1] = y; - vertex_normal[2][ivert-1][face_num-1] = z; - } - - } - else if ( strcmp ( word, "uvTexture" ) == 0 ) { - - count = sscanf ( next, "%f%n", &x, &width ); - next = next + width; - - count = sscanf ( next, "%f%n", &y, &width ); - next = next + width; - - if ( ivert < ORDER_MAX && face_num < FACE_MAX ) { - vertex_tex_uv[0][ivert-1][face_num-1] = x; - vertex_tex_uv[1][ivert-1][face_num-1] = y; - } - } - else if ( strcmp ( word, "vertex" ) == 0 ) { - - count = sscanf ( next, "%d%n", &jval, &width ); - next = next + width; - - if ( ivert < ORDER_MAX && face_num < FACE_MAX ) { - face_order[face_num-1] = face_order[face_num-1] + 1; - face[ivert][face_num-1] = jval; - } - ivert = ivert + 1; - - } -/* - Right now, we don't do anything with the vertexColor information. -*/ - else if ( strcmp ( word, "vertexColor" ) == 0 ) { - - count = sscanf ( next, "%d%n", &jval, &width ); - next = next + width; - - count = sscanf ( next, "%d%n", &jval, &width ); - next = next + width; - - count = sscanf ( next, "%d%n", &jval, &width ); - next = next + width; - - count = sscanf ( next, "%d%n", &jval, &width ); - next = next + width; - } - else { - bad_num = bad_num + 1; - printf ( "NODES: Bad data %s\n", word ); - return ERROR; - } - - } -/* - PATCH - I don't know what to do with this yet. -*/ - else if ( strcmp ( level_name[level], "patch" ) == 0 ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( strcmp ( word, "approx_type" ) == 0 ) { - } - else if ( strcmp ( word, "controlpoints" ) == 0 ) { - } - else if ( strcmp ( word, "curv_u" ) == 0 ) { - } - else if ( strcmp ( word, "curv_v" ) == 0 ) { - } - else if ( strcmp ( word, "recmin" ) == 0 ) { - } - else if ( strcmp ( word, "recmax" ) == 0 ) { - } - else if ( strcmp ( word, "recursion" ) == 0 ) { - } - else if ( strcmp ( word, "spacial" ) == 0 ) { - } - else if ( strcmp ( word, "taggedpoints" ) == 0 ) { - } - else if ( strcmp ( word, "ucurve" ) == 0 ) { - } - else if ( strcmp ( word, "ustep" ) == 0 ) { - } - else if ( strcmp ( word, "utension" ) == 0 ) { - } - else if ( strcmp ( word, "utype" ) == 0 ) { - } - else if ( strcmp ( word, "vclose" ) == 0 ) { - } - else if ( strcmp ( word, "vcurve" ) == 0 ) { - } - else if ( strcmp ( word, "viewdep" ) == 0 ) { - } - else if ( strcmp ( word, "vpoint" ) == 0 ) { - } - else if ( strcmp ( word, "vstep" ) == 0 ) { - } - else if ( strcmp ( word, "vtension" ) == 0 ) { - } - else if ( strcmp ( word, "vtype" ) == 0 ) { - } - else { - bad_num = bad_num + 1; - printf ( "PATCH: Bad data %s\n", word ); - return ERROR; - } - } -/* - POLYGONS -*/ - else if ( strcmp ( level_name[level], "polygons" ) == 0 ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( word[0] == '[' ) { - } - else if ( strcmp ( word, "material" ) == 0 ) { - - count = sscanf ( next, "%d%n", &jval, &width ); - next = next + width; - - for ( ivert = 0; ivert < ORDER_MAX; ivert++ ) { - vertex_material[ivert][face_num-1] = jval; - } - - } - else if ( strcmp ( word, "nodes" ) == 0 ) { - count = sscanf ( next, "%s%n", word2, &width ); - next = next + width; - } - else { - bad_num = bad_num + 1; - printf ( "POLYGONS: Bad data %s\n", word ); - return ERROR; - } - - } -/* - SPLINE -*/ - else if ( strcmp ( level_name[level], "spline" ) == 0 ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( strcmp ( word, "controlpoints" ) == 0 ) { - break; - } -/* - WHY DON'T YOU READ IN THE OBJECT NAME HERE? -*/ - else if ( strcmp ( word, "name" ) == 0 ) { - break; - } - else if ( strcmp ( word, "nbKeys" ) == 0 ) { - break; - } - else if ( strcmp ( word, "step" ) == 0 ) { - break; - } - else if ( strcmp ( word, "tension" ) == 0 ) { - break; - } - else if ( strcmp ( word, "type" ) == 0 ) { - break; - } - else { - bad_num = bad_num + 1; - printf ( "SPLINE: Bad data %s\n", word ); - return ERROR; - } - - } -/* - TAGGEDPOINTS -*/ - else if ( strcmp ( level_name[level], "taggedpoints" ) == 0 ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( word[0] == '[' ) { - } - else if ( strcmp ( word, "tagged" ) == 0 ) { - } - else { - bad_num = bad_num + 1; - printf ( "TAGGEDPOINTS: Bad data %s\n", word ); - return ERROR; - } - - } -/* - TEXTURE -*/ - else if ( strcmp ( level_name[level], "texture" ) == 0 ) { - - if ( strcmp ( word, "{" ) == 0 ) { - texture_num = texture_num + 1; - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( word[0] == '[' ) { - } - else if ( strcmp ( word, "ambient" ) == 0 ) { - } - else if ( strcmp ( word, "anim" ) == 0 ) { - } - else if ( strcmp ( word, "blending" ) == 0 ) { - } - else if ( strcmp ( word, "diffuse" ) == 0 ) { - } - else if ( strcmp ( word, "effect" ) == 0 ) { - } - else if ( strcmp ( word, "glbname" ) == 0 ) { - } - else if ( strcmp ( word, "method" ) == 0 ) { - } - else if ( strcmp ( word, "name" ) == 0 ) { - count = sscanf ( next, "%s%n", word, &width ); - next = next + width; - strcpy ( texture_name[texture_num-1], word ); - } - else if ( strcmp ( word, "offset" ) == 0 ) { - } - else if ( strcmp ( word, "pixelinterp" ) == 0 ) { - } - else if ( strcmp ( word, "reflect" ) == 0 ) { - } - else if ( strcmp ( word, "reflmap" ) == 0 ) { - } - else if ( strcmp ( word, "repeat" ) == 0 ) { - } - else if ( strcmp ( word, "rotation" ) == 0 ) { - } - else if ( strcmp ( word, "roughness" ) == 0 ) { - } - else if ( strcmp ( word, "scaling" ) == 0 ) { - } - else if ( strcmp ( word, "specular" ) == 0 ) { - } - else if ( strcmp ( word, "transp" ) == 0 ) { - } - else if ( strcmp ( word, "txtsup_rot" ) == 0 ) { - } - else if ( strcmp ( word, "txtsup_scal" ) == 0 ) { - } - else if ( strcmp ( word, "txtsup_trans" ) == 0 ) { - } - else { - bad_num = bad_num + 1; - printf ( "TEXTURE: Bad data %s\n", word ); - return ERROR; - } - } -/* - VERTICES -*/ - else if ( strcmp ( level_name[level], "vertices" ) == 0 ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( word[0] == '[' ) { - } - else if ( strcmp ( word, "position" ) == 0 ) { - - count = sscanf ( next, "%f%n", &x, &width ); - next = next + width; - - count = sscanf ( next, "%f%n", &y, &width ); - next = next + width; - - count = sscanf ( next, "%f%n", &z, &width ); - next = next + width; - - if ( cor3_num < COR3_MAX ) { - cor3[0][cor3_num] = x; - cor3[1][cor3_num] = y; - cor3[2][cor3_num] = z; - } - cor3_num = cor3_num + 1; - } - else { - bad_num = bad_num + 1; - printf ( "VERTICES: Bad data %s\n", word ); - return ERROR; - } - } -/* - Any other word: -*/ - else { - - } - } - } - -/* - End of information in file. - - Check the "materials" defining a line. - - If COORDINDEX is -1, so should be the MATERIALINDEX. - If COORDINDEX is not -1, then the MATERIALINDEX shouldn"t be either. -*/ - for ( i = 0; i < line_num; i++ ) { - - if ( line_dex[i] == -1 ) { - line_material[i] = -1; - } - else if ( line_material[i] == -1 ) { - line_material[i] = 0; - } - - } - return SUCCESS; -} -/******************************************************************************/ - -int hrc_write ( FILE* fileout ) - -/******************************************************************************/ - -/* - Purpose: - - HRC_WRITE writes graphics data to an HRC SoftImage file. - - Examples: - - HRCH: Softimage 4D Creative Environment v3.00 - - - model - { - name "cube_10x10" - scaling 1.000 1.000 1.000 - rotation 0.000 0.000 0.000 - translation 0.000 0.000 0.000 - - mesh - { - flag ( PROCESS ) - discontinuity 60.000 - - vertices 8 - { - [0] position -5.000 -5.000 -5.000 - [1] position -5.000 -5.000 5.000 - [2] position -5.000 5.000 -5.000 - [3] position -5.000 5.000 5.000 - [4] position 5.000 -5.000 -5.000 - [5] position 5.000 -5.000 5.000 - [6] position 5.000 5.000 -5.000 - [7] position 5.000 5.000 5.000 - } - - polygons 6 - { - [0] nodes 4 - { - [0] vertex 0 - normal -1.000 0.000 0.000 - uvTexture 0.000 0.000 - vertexColor 255 178 178 178 - [1] vertex 1 - normal -1.000 0.000 0.000 - uvTexture 0.000 0.000 - vertexColor 255 178 178 178 - [2] vertex 3 - normal -1.000 0.000 0.000 - uvTexture 0.000 0.000 - vertexColor 255 178 178 178 - [3] vertex 2 - normal -1.000 0.000 0.000 - uvTexture 0.000 0.000 - vertexColor 255 178 178 178 - } - material 0 - [1] nodes 4 - { - [0] vertex 1 - normal 0.000 0.000 1.000 - uvTexture 0.000 0.000 - vertexColor 255 178 178 178 - [1] vertex 5 - - ...etc..... - - [5] nodes 4 - { - [0] vertex 2 - normal 0.000 1.000 0.000 - uvTexture 0.000 0.000 - vertexColor 255 178 178 178 - [1] vertex 3 - normal 0.000 1.000 0.000 - uvTexture 0.000 0.000 - vertexColor 255 178 178 178 - [2] vertex 7 - normal 0.000 1.000 0.000 - uvTexture 0.000 0.000 - vertexColor 255 178 178 178 - [3] vertex 6 - normal 0.000 1.000 0.000 - uvTexture 0.000 0.000 - vertexColor 255 178 178 178 - } - material 0 - } - - edges 12 - { - [1] vertices 3 2 - [2] vertices 2 0 - [3] vertices 0 1 - [4] vertices 1 3 - [5] vertices 7 3 - [6] vertices 1 5 - [7] vertices 5 7 - [8] vertices 6 7 - [9] vertices 5 4 - [10] vertices 4 6 - [11] vertices 2 6 - [12] vertices 4 0 - } - } - - material [0] - { - name "kazoo" - type PHONG - ambient 0.0 1.0 0.0 - diffuse 1.0 0.0 0.0 - specular 0.0 0.0 1.0 - exponent 50.0 - reflectivity 0.0 - transparency 0.0 - refracIndex 1.0 - glow 0 - coc 0.0 - } - - texture [0] - { - name "/usr/users/foss/HOUSE/PICTURES/mellon" - glbname "t2d1" - anim STATIC - method XY - repeat 1 1 - scaling 1.000 1.000 - offset 0.000 0.000 - pixelInterp - effect INTENSITY - blending 1.000 - ambient 0.977 - diffuse 1.000 - specular 0.966 - reflect 0.000 - transp 0.000 - roughness 0.000 - reflMap 1.000 - rotation 0.000 - txtsup_rot 0.000 0.000 0.000 - txtsup_trans 0.000 0.000 0.000 - txtsup_scal 1.000 1.000 1.000 - } - } - - Modified: - - 25 June 1998 - - Author: - - John Burkardt - -*/ -{ - int iface; - int ivert; - int j; - int jhi; - int jlo; - int jrel; - int k; - int npts; - int nseg; - int text_num; - - nseg = 0; - text_num = 0; - - fprintf ( fileout, "HRCH: Softimage 4D Creative Environment v3.00\n" ); - fprintf ( fileout, "\n" ); - fprintf ( fileout, "\n" ); - text_num = text_num + 3; - - fprintf ( fileout, "model\n" ); - fprintf ( fileout, "{\n" ); - fprintf ( fileout, " name \"%s\"\n", object_name ); - fprintf ( fileout, " scaling 1.000 1.000 1.000\n" ); - fprintf ( fileout, " rotation 0.000 0.000 0.000\n" ); - fprintf ( fileout, " translation 0.000 0.000 0.000\n" ); - text_num = text_num + 6; - - if ( face_num > 0 ) { - - fprintf ( fileout, "\n" ); - fprintf ( fileout, " mesh\n" ); - fprintf ( fileout, " {\n" ); - fprintf ( fileout, " flag ( PROCESS )\n" ); - fprintf ( fileout, " discontinuity 60.000\n" ); - text_num = text_num + 5; -/* - Point coordinates. -*/ - if ( cor3_num > 0 ) { - - fprintf ( fileout, "\n" ); - fprintf ( fileout, " vertices %d\n", cor3_num ); - fprintf ( fileout, " {\n" ); - text_num = text_num + 3; - - for ( j = 0; j < cor3_num; j++ ) { - - fprintf ( fileout, " [%d] position %f %f %f\n", j, cor3[0][j], - cor3[1][j], cor3[2][j] ); - text_num = text_num + 1; - } - fprintf ( fileout, " }\n" ); - text_num = text_num + 1; - } -/* - Faces. -*/ - fprintf ( fileout, "\n" ); - fprintf ( fileout, " polygons %d\n", face_num ); - fprintf ( fileout, " {\n" ); - text_num = text_num + 3; - - for ( iface = 0; iface < face_num; iface++ ) { - - fprintf ( fileout, " [%d] nodes %d\n", iface, face_order[iface] ); - fprintf ( fileout, " {\n" ); - text_num = text_num + 2; - - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - - fprintf ( fileout, " [%d] vertex %d\n", ivert, face[ivert][iface] ); - fprintf ( fileout, " normal %f %f %f\n", - vertex_normal[0][ivert][iface], - vertex_normal[1][ivert][iface], vertex_normal[2][ivert][iface] ); - fprintf ( fileout, " uvTexture %f %f\n", - vertex_tex_uv[0][ivert][iface], vertex_tex_uv[1][ivert][iface] ); - fprintf ( fileout, " vertexColor 255 178 178 178\n" ); - text_num = text_num + 4; - } - fprintf ( fileout, " }\n" ); - fprintf ( fileout, " material %d\n", face_material[iface] ); - text_num = text_num + 2; - } - fprintf ( fileout, " }\n" ); - fprintf ( fileout, " }\n" ); - text_num = text_num + 2; - } -/* - IndexedLineSet. -*/ - if ( line_num > 0 ) { - - nseg = 0; - - jhi = -1; - - for ( ;; ) { - - jlo = jhi + 1; -/* - Look for the next index JLO that is not -1. -*/ - while ( jlo < line_num ) { - if ( line_dex[jlo] != -1 ) { - break; - } - jlo = jlo + 1; - } - - if ( jlo >= line_num ) { - break; - } -/* - Look for the highest following index JHI that is not -1. -*/ - jhi = jlo + 1; - - while ( jhi < line_num ) { - if ( line_dex[jhi] == -1 ) { - break; - } - jhi = jhi + 1; - } - - jhi = jhi - 1; -/* - Our next line segment involves LINE_DEX indices JLO through JHI. -*/ - nseg = nseg + 1; - npts = jhi + 1 - jlo; - - fprintf ( fileout, "\n" ); - fprintf ( fileout, " spline\n" ); - fprintf ( fileout, " {\n" ); - fprintf ( fileout, " name \"spl%d\"\n", nseg ); - fprintf ( fileout, " type LINEAR\n" ); - fprintf ( fileout, " nbKeys %d\n", npts ); - fprintf ( fileout, " tension 0.000\n" ); - fprintf ( fileout, " step 1\n" ); - fprintf ( fileout, "\n" ); - text_num = text_num + 9; - - fprintf ( fileout, " controlpoints\n" ); - fprintf ( fileout, " {\n" ); - text_num = text_num + 2; - - for ( j = jlo; j <= jhi; j++ ) { - jrel = j - jlo; - k = line_dex[j]; - fprintf ( fileout, " [%d] position %f %f %f\n", jrel, - cor3[0][k], cor3[1][k], cor3[2][k] ); - text_num = text_num + 1; - } - - fprintf ( fileout, " }\n" ); - fprintf ( fileout, " }\n" ); - text_num = text_num + 2; - } - } -/* - MATERIALS -*/ - for ( i = 0; i < material_num; i++ ) { - - fprintf ( fileout, " material [%d]\n", i ); - fprintf ( fileout, " {\n" ); - fprintf ( fileout, " name \"%s\"\n", material_name[i] ); - fprintf ( fileout, " type PHONG\n" ); - fprintf ( fileout, " ambient %f %f %f\n", material_rgba[0][i], - material_rgba[1][i], material_rgba[2][i] ); - fprintf ( fileout, " diffuse %f %f %f\n", material_rgba[0][i], - material_rgba[1][i], material_rgba[2][i] ); - fprintf ( fileout, " specular %f %f %f\n", material_rgba[0][i], - material_rgba[1][i], material_rgba[2][i] ); - fprintf ( fileout, " exponent 50.0\n" ); - fprintf ( fileout, " reflectivity 0.0\n" ); - fprintf ( fileout, " transparency %f\n", 1.0 - material_rgba[3][i] ); - fprintf ( fileout, " refracIndex 1.0\n" ); - fprintf ( fileout, " glow 0\n" ); - fprintf ( fileout, " coc 0.0\n" ); - fprintf ( fileout, " }\n" ); - - text_num = text_num + 14; - - } -/* - TEXTURES -*/ - for ( i = 0; i < texture_num; i++ ) { - - fprintf ( fileout, " texture [%d]\n", i ); - fprintf ( fileout, " {\n" ); - fprintf ( fileout, " name \"%s\"\n", texture_name[i] ); - fprintf ( fileout, " glbname \"t2d1\"\n" ); - fprintf ( fileout, " anim STATIC\n" ); - fprintf ( fileout, " method XY\n" ); - fprintf ( fileout, " repeat 1 1\n" ); - fprintf ( fileout, " scaling 1.000 1.000\n" ); - fprintf ( fileout, " offset 0.000 0.000\n" ); - fprintf ( fileout, " pixelInterp\n" ); - fprintf ( fileout, " effect INTENSITY\n" ); - fprintf ( fileout, " blending 1.000\n" ); - fprintf ( fileout, " ambient 0.977\n" ); - fprintf ( fileout, " diffuse 1.000\n" ); - fprintf ( fileout, " specular 0.966\n" ); - fprintf ( fileout, " reflect 0.000\n" ); - fprintf ( fileout, " transp 0.000\n" ); - fprintf ( fileout, " roughness 0.000\n" ); - fprintf ( fileout, " reflMap 1.000\n" ); - fprintf ( fileout, " rotation 0.000\n" ); - fprintf ( fileout, " txtsup_rot 0.000 0.000 0.000\n" ); - fprintf ( fileout, " txtsup_trans 0.000 0.000 0.000\n" ); - fprintf ( fileout, " txtsup_scal 1.000 1.000 1.000\n" ); - fprintf ( fileout, " }\n" ); - - text_num = text_num + 25; - - } - fprintf ( fileout, "}\n" ); - text_num = text_num + 1; -/* - Report. -*/ - printf ( "\n" ); - printf ( "HRC_WRITE - Wrote %d text lines.\n", text_num ); - - return SUCCESS; -} -/******************************************************************************/ - -void init_program_data ( void ) - -/******************************************************************************/ - -/* - Purpose: - - INIT_PROGRAM_DATA initializes the internal program data. - - Modified: - - 26 May 1999 - - Author: - - John Burkardt -*/ -{ - byte_swap = FALSE; - debug = 0; - line_prune = 1; - color_num = 0; - cor3_num = 0; - face_num = 0; - line_num = 0; - - if ( debug ) { - printf ( "\n" ); - printf ( "INIT_PROGRAM_DATA: Program data initialized.\n" ); - } - - return; - -} -/******************************************************************************/ - -int interact ( void ) - -/******************************************************************************/ - -/* - Purpose: - - INTERACT carries on an interactive session with the user. - - Modified: - - 22 May 1999 - - Author: - - John Burkardt -*/ -{ - int i; - int icor3; - int ierror; - int iface; - int itemp; - int ivert; - int j; - int jvert; - int m; - char *next; - float temp; - float x; - float y; - float z; - - strcpy ( filein_name, "NO_IN_NAME" ); - strcpy ( fileout_name, "NO_OUT_NAME" ); - -/* - Say hello. -*/ - hello ( ); -/* - Get the next user command. -*/ - printf ( "\n" ); - printf ( "Enter command (H for help)\n" ); - - while ( fgets ( input, LINE_MAX_LEN, stdin ) != NULL ) { -/* - Advance to the first nonspace character in INPUT. -*/ - for ( next = input; *next != '\0' && isspace(*next); next++ ) { - } -/* - Skip blank lines and comments. -*/ - if ( *next == '\0' ) { - continue; - } -/* - Command: << FILENAME - Append new data to current graphics information. -*/ - if ( *next == '<' && *(next+1) == '<' ) { - - next = next + 2; - sscanf ( next, "%s", filein_name ); - - ierror = data_read ( ); - - if ( ierror == ERROR ) { - printf ( "\n" ); - printf ( "INTERACT - Fatal error!\n" ); - printf ( " DATA_READ failed to read input data.\n" ); - } - } -/* - Command: < FILENAME -*/ - else if ( *next == '<' ) { - - next = next + 1; - sscanf ( next, "%s", filein_name ); - - data_init ( ); - - ierror = data_read ( ); - - if ( ierror == ERROR ) { - printf ( "\n" ); - printf ( "INTERACT - Fatal error!\n" ); - printf ( " DATA_READ failed to read input data.\n" ); - } - } -/* - Command: > FILENAME -*/ - else if ( *next == '>' ) { - - next = next + 1; - sscanf ( next, "%s", fileout_name ); - - ierror = data_write ( ); - - if ( ierror == ERROR ) { - printf ( "\n" ); - printf ( "INTERACT - Fatal error!\n" ); - printf ( " OUTPUT_DATA failed to write output data.\n" ); - } - - } -/* - B: Switch byte swapping option. -*/ - else if ( *next == 'B' || *next == 'b' ) { - - if ( byte_swap == TRUE ) { - byte_swap = FALSE; - printf ( "Byte_swapping reset to FALSE.\n" ); - } - else { - byte_swap = TRUE; - printf ( "Byte_swapping reset to TRUE.\n" ); - } - - } -/* - D: Switch debug option. -*/ - else if ( *next == 'D' || *next == 'd' ) { - if ( debug ) { - debug = 0; - printf ( "Debug reset to FALSE.\n" ); - } - else { - debug = 1; - printf ( "Debug reset to TRUE.\n" ); - } - } -/* - F: Check a face. -*/ - else if ( *next == 'f' || *next == 'F' ) { - printf ( "\n" ); - printf ( " Enter a face index between 0 and %d:", face_num-1 ); - scanf ( "%d", &iface ); - face_print ( iface ); - } -/* - H: Help -*/ - else if ( *next == 'h' || *next == 'H' ) { - help ( ); - } -/* - I: Print change information. -*/ - else if ( *next == 'i' || *next == 'I') { - news ( ); - } -/* - LINES: - Convert face information to lines. -*/ - else if ( *next == 'l' || *next == 'L') { - - if ( face_num > 0 ) { - - printf ( "\n" ); - printf ( "INTERACT - Note:\n" ); - printf ( " Face information will be converted\n" ); - printf ( " to line information.\n" ); - - face_to_line ( ); - - if ( line_num > LINES_MAX ) { - - printf ( "\n" ); - printf ( "INTERACT - Note:\n" ); - printf ( " Some face information was lost.\n" ); - printf ( " The maximum number of lines is %d,\n", LINES_MAX ); - printf ( " but we would need at least %d.\n", line_num ); - - line_num = LINES_MAX; - - } - - face_num = 0; - } - else { - - printf ( "\n" ); - printf ( "INTERACT - Note:\n" ); - printf ( " There were no faces to convert.\n" ); - - } - - } -/* - N: Recompute normal vectors. -*/ - else if ( *next == 'n' || *next == 'N') { - - for ( iface = 0; iface < face_num; iface++ ) { - for ( i = 0; i < 3; i++ ) { - face_normal[i][iface] = 0.0; - } - } - - for ( iface = 0; iface < face_num; iface++ ) { - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - for ( i = 0; i < 3; i++ ) { - vertex_normal[i][ivert][iface] = 0.0; - } - } - } - - vertex_normal_set ( ); - - cor3_normal_set ( ); - - face_normal_ave ( ); - } -/* - P: Line pruning optiont -*/ - else if ( *next == 'p' || *next == 'P' ) { - - printf ( "\n" ); - printf ( "INTERACT - SET LINE PRUNING OPTION.\n" ); - printf ( "\n" ); - printf ( " LINE_PRUNE = 0 means no line pruning.\n" ); - printf ( " nonzero means line pruning.\n" ); - printf ( "\n" ); - printf ( " Current value is LINE_PRUNE = %d.\n", line_prune ); - printf ( "\n" ); - printf ( " Enter new value for LINE_PRUNE.\n" ); - - if ( fgets ( input, LINE_MAX_LEN, stdin ) == NULL ) { - printf ( " ??? Error trying to read input.\n" ); - } - else { - sscanf ( input, "%d", &line_prune ); - printf ( " New value is LINE_PRUNE = %d.\n", line_prune ); - } - } -/* - Q: Quit -*/ - else if ( *next == 'q' || *next == 'Q' ) { - printf ( "\n" ); - printf ( "INTERACT - Normal end of execution.\n" ); - return SUCCESS; - } -/* - R: Reverse normal vectors. -*/ - else if ( *next == 'r' || *next == 'R' ) { - - for ( icor3 = 0; icor3 < cor3_num; icor3++ ) { - for ( i = 0; i < 3; i++ ) { - cor3_normal[i][icor3] = - cor3_normal[i][icor3]; - } - } - - for ( iface = 0; iface < face_num; iface++ ) { - for ( i = 0; i < 3; i++ ) { - face_normal[i][iface] = - face_normal[i][iface]; - } - } - - for ( iface = 0; iface < face_num; iface++ ) { - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - for ( i = 0; i < 3; i++ ) { - vertex_normal[i][ivert][iface] = - - vertex_normal[i][ivert][iface]; - } - } - } - printf ( "\n" ); - printf ( "INTERACT - Note:\n" ); - printf ( " Reversed node, face and vertex normals.\n" ); - } -/* - S: Select a few faces, discard the rest. -*/ - else if ( *next == 's' || *next == 'S' ) { - face_subset ( ); - } -/* - T: Transform the data. -*/ - else if ( *next == 't' || *next == 'T' ) { - - printf ( "\n" ); - printf ( "For now, we only offer point scaling.\n" ); - printf ( "Enter X, Y, Z scale factors:\n" ); - - scanf ( "%f %f %f", &x, &y, &z ); - - for ( j = 0; j < cor3_num; j++ ) { - cor3[0][j] = x * cor3[0][j]; - cor3[1][j] = y * cor3[1][j]; - cor3[2][j] = z * cor3[2][j]; - } - - for ( iface = 0; iface < face_num; iface++ ) { - for ( i = 0; i < 3; i++ ) { - face_normal[i][iface] = 0.0; - } - } - - for ( iface = 0; iface < face_num; iface++ ) { - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - for ( i = 0; i < 3; i++ ) { - vertex_normal[i][ivert][iface] = 0.0; - } - } - } - - vertex_normal_set ( ); - - cor3_normal_set ( ); - - face_normal_ave ( ); - } -/* - U: Renumber faces, count objects: -*/ - else if ( *next == 'u' || *next == 'U' ) { - } -/* - V: Convert polygons to triangles: -*/ - else if ( *next == 'v' || *next == 'V' ) { - } -/* - W: Reverse the face node ordering. -*/ - else if ( *next == 'w' || *next == 'W' ) { - - if ( face_num > 0 ) { - - for ( iface = 0; iface < face_num; iface++ ) { - - m = face_order[iface]; - - for ( ivert = 0; ivert < m/2; ivert++ ) { - - jvert = m - ivert - 1; - - itemp = face[ivert][iface]; - face[ivert][iface] = face[jvert][iface]; - face[jvert][iface] = itemp; - - itemp = vertex_material[ivert][iface]; - vertex_material[ivert][iface] = vertex_material[jvert][iface]; - vertex_material[jvert][iface] = itemp; - - for ( i = 0; i < 3; i++ ) { - temp = vertex_normal[i][ivert][iface]; - vertex_normal[i][ivert][iface] = - vertex_normal[i][jvert][iface]; - vertex_normal[i][jvert][iface] = temp; - } - } - } - printf ( "\n" ); - printf ( "INTERACT - Note:\n" ); - printf ( " Reversed face node ordering.\n" ); - } - } -/* - Command: ??? -*/ - else { - printf ( "\n" ); - printf ( "INTERACT: Warning!\n" ); - printf ( " Your command was not recognized.\n" ); - } - - printf ( "\n" ); - printf ( "Enter command (H for help)\n" ); - - } - return SUCCESS; -} -/******************************************************************************/ - -int iv_read ( FILE *filein ) - -/******************************************************************************/ - -/* - Purpose: - - IV_READ reads graphics information from an Inventor file. - - Example: - - #Inventor V2.0 ascii - - Separator { - Info { - string "Inventor file generated by IVCON. - Original data in file cube.iv." - } - Separator { - LightModel { - model PHONG - } - MatrixTransform { matrix - 0.9 0.0 0.0 0.0 - 0.0 -0.9 0.0 0.0 - 0.0 0.0 -1.5 0.0 - 0.0 0.0 0.0 1.0 - } - Material { - ambientColor 0.2 0.2 0.2 - diffuseColor [ - 0.8 0.8 0.8, - 0.7 0.1 0.1, - 0.1 0.8 0.2, - ] - emissiveColor 0.0 0.0 0.0 - specularColor 0.0 0.0 0.0 - shininess 0.2 - transparency [ - 0.0, 0.5, 1.0, - ] - } - Texture2 { - filename "fred.rgb" - wrapS REPEAT - wrapT REPEAT - model MODULATE - blendColor 0.0 0.0 0.0 - } - - MaterialBinding { - value PER_VERTEX_INDEXED - } - NormalBinding { - value PER_VERTEX_INDEXED - } - TextureCoordinateBinding { - value PER_VERTEX_INDEXED - } - - ShapeHints { - vertexOrdering COUNTERCLOCKWISE - shapeType UNKNOWN_SHAPE_TYPE - faceType CONVEX - creaseAngle 6.28319 - } - - Coordinate3 { - point [ - 8.59816 5.55317 -3.05561, - 8.59816 2.49756 0.000000E+00, - ...etc... - 2.48695 2.49756 -3.05561, - ] - } - - Normal { - vector [ - 0.71 0.71 0.0, - ...etc... - 0.32 0.32 0.41, - ] - } - - TextureCoordinate2 { - point [ - 0.0 1.0, - 0.1, 0.8, - ...etc... - 0.4 0.7, - ] - } - - IndexedLineSet { - coordIndex [ - 0, 1, 2, -1, - 3, 4, 5, -1, - 7, 8, 9, -1, - ...etc... - 189, 190, 191, -1, - ] - materialIndex [ - 0, 0, 0, -1, - 1, 1, 1, -1, - 2, 2, 2, -1, - ...etc... - 64, 64, 64, -1, - ] - } - - IndexedFaceSet { - coordIndex [ - 0, 1, 2, -1, - 3, 4, 5, -1, - 7, 8, 9, -1, - ...etc... - 189, 190, 191, -1, - ] - materialIndex [ - 0, 0, 0, -1, - 1, 1, 1, -1, - 2, 2, 2, -1, - ...etc... - 64, 64, 64, -1, - ] - normalIndex [ - 0, 0, 0, -1, - 1, 1, 1, -1, - 2, 2, 2, -1, - ...etc... - 64, 64, 64, -1, - ] - textureCoordIndex [ - 0, 0, 0, -1, - 1, 1, 1, -1, - 2, 2, 2, -1, - ...etc... - 64, 64, 64, -1, - ] - } - - IndexedTriangleStripSet { - vertexProperty VertexProperty { - vertex [ x y z, - ... - x y z ] - normal [ x y z, - ... - x y z ] - materialBinding OVERALL - normalBinding PER_VERTEX_INDEXED - } - coordIndex [ - i, j, k, l, m, -1, - n, o, p, q, r, s, t, u, -1, - v, w, x, -1 - ..., -1 ] - normalIndex -1 - } - - } - } - - Modified: - - 01 July 1999 - - Author: - - John Burkardt -*/ -{ - char c; - int count; - int i; - int icol; - int icolor; - int icface; - int inormface; - int iface_num; - int irow; - int iuv; - int ivert; - int iword; - int ix; - int ixyz; - int iy; - int iz; - int j; - int jval; - int level; - char *next; - int nlbrack; - int nrbrack; - int nu; - int null_index; - int cor3_num_old; - int line_num2; - int face_num2; - int normal_num_temp; - int text_numure_temp; - int nv; - int result; - float rval; - int width; - char word[LINE_MAX_LEN]; - char word1[LINE_MAX_LEN]; - char wordm1[LINE_MAX_LEN]; - float xvec[3]; - - icface = 0; - icol = -1; - inormface = 0; - iface_num = face_num; - irow = 0; - ix = 0; - ixyz = 0; - iy = 0; - iz = 0; - jval = 0; - level = 0; - strcpy ( level_name[0], "Top" ); - nlbrack = 0; - nrbrack = 0; - nu = 0; - cor3_num_old = cor3_num; - face_num2 = face_num; - line_num2 = line_num; - normal_num_temp = 0; - text_numure_temp = 0; - nv = 0; - rval = 0.0; - strcpy ( word, " " ); - strcpy ( wordm1, " " ); -/* - Read the next line of text from the input file. -*/ - for ( ;; ) { - - if ( fgets ( input, LINE_MAX_LEN, filein ) == NULL ) { - break; - } - - text_num = text_num + 1; - next = input; - iword = 0; -/* - Remove all commas from the line, so we can use SSCANF to read - numeric items. -*/ - i = 0; - while ( input[i] != '\0' ) { - if ( input[i] == ',' ) { - input[i] = ' '; - } - i++; - } -/* - Force brackets and braces to be buffered by spaces. -*/ - i = 0; - while ( input[i] != '\0' ) { - i++; - } - null_index = i; - - i = 0; - while ( input[i] != '\0' && i < LINE_MAX_LEN ) { - - if ( input[i] == '[' || input[i] == ']' || - input[i] == '{' || input[i] == '}' ) { - - result = char_pad ( &i, &null_index, input, LINE_MAX_LEN ); - if ( result == ERROR ) { - break; - } - } - else { - i++; - } - } -/* - Read a word from the line. -*/ - for ( ;; ) { - - strcpy ( wordm1, word ); - strcpy ( word, " " ); - - count = sscanf ( next, "%s%n", word, &width ); - next = next + width; - - if ( count <= 0 ) { - break; - } - - iword = iword + 1; - - if ( iword == 1 ) { - strcpy ( word1, word ); - } -/* - The first line of the file must be the header. -*/ - if ( text_num == 1 ) { - - if ( leqi ( word1, "#Inventor" ) != TRUE ) { - printf ( "\n" ); - printf ( "IV_READ - Fatal error!\n" ); - printf ( " The input file has a bad header.\n" ); - return ERROR; - } - else { - comment_num = comment_num + 1; - } - break; - } -/* - A comment begins anywhere with '#'. - Skip the rest of the line. -*/ - if ( word[1] == '#' ) { - comment_num = comment_num + 1; - break; - } -/* - If the word is a curly or square bracket, count it. - If the word is a left bracket, the previous word is the name of a node. -*/ - if ( strcmp ( word, "{" ) == 0 || strcmp ( word, "[" ) == 0 ) { - nlbrack = nlbrack + 1; - level = nlbrack - nrbrack; - strcpy ( level_name[level], wordm1 ); - if ( debug ) { - printf ( "Begin level: %s\n", wordm1 ); - } - } - else if ( strcmp ( word, "}" ) == 0 || strcmp ( word, "]" ) == 0 ) { - nrbrack = nrbrack + 1; - - if ( nlbrack < nrbrack ) { - printf ( "\n" ); - printf ( "IV_READ - Fatal error!\n" ); - printf ( " Extraneous right bracket on line %d.\n", text_num ); - printf ( " Currently processing field %s\n.", level_name[level] ); - return ERROR; - } - } -/* - BASECOLOR -*/ - if ( leqi ( level_name[level], "BASECOLOR" ) == TRUE ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( leqi ( word, "RGB" ) == TRUE ) { - } - else { - bad_num = bad_num + 1; - printf ( "Bad data %s\n", word ); - } - } -/* - COORDINATE3 -*/ - else if ( leqi ( level_name[level], "COORDINATE3" ) == TRUE ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( leqi ( word, "POINT" ) == TRUE ) { - } - else { - bad_num = bad_num + 1; - printf ( "COORDINATE3: Bad data %s\n", word ); - } - } -/* - COORDINATE4 -*/ - else if ( leqi ( level_name[level], "COORDINATE4" ) == TRUE ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( leqi ( word, "POINT" ) == TRUE ) { - } - else { - bad_num = bad_num + 1; - printf ( "COORDINATE4: Bad data %s\n", word ); - } - } -/* - COORDINDEX -*/ - else if ( leqi ( level_name[level], "COORDINDEX" ) == TRUE ) { - - if ( strcmp ( word, "[" ) == 0 ) { - ivert = 0; - } - else if ( strcmp ( word, "]" ) == 0 ) { - level = nlbrack - nrbrack; - } -/* - (indexedlineset) COORDINDEX -*/ - else if ( leqi ( level_name[level-1], "INDEXEDLINESET" ) == TRUE ) { - - count = sscanf ( word, "%d%n", &jval, &width ); - - if ( count > 0 ) { - - if ( jval < -1 ) { - bad_num = bad_num + 1; - } - else { - if ( line_num < LINES_MAX ) { - if ( jval != -1 ) { - jval = jval + cor3_num_old; - } - line_dex[line_num] = jval; - } - line_num = line_num + 1; - } - } - else { - bad_num = bad_num + 1; - } - } -/* - (indexedfaceset) COORDINDEX - Warning: If the list of indices is not terminated with a final -1, then - the last face won't get counted. -*/ - else if ( leqi ( level_name[level-1], "INDEXEDFACESET" ) == TRUE ) { - - count = sscanf ( word, "%d%n", &jval, &width ); - - if ( count > 0 ) { - if ( jval == -1 ) { - ivert = 0; - face_num = face_num + 1; - } - else { - if ( ivert == 0 ) { - if ( face_num < FACE_MAX ) { - face_order[face_num] = 0; - } - } - if ( face_num < FACE_MAX ) { - face_order[face_num] = face_order[face_num] + 1; - face[ivert][face_num] = jval + cor3_num_old; - ivert = ivert + 1; - } - } - } - } -/* - (indexednurbssurface) COORDINDEX -*/ - else if ( leqi ( level_name[level-1], "INDEXEDNURBSSURFACE" ) == TRUE ) { - } -/* - (indexedtrianglestripset) COORDINDEX - - First three coordinate indices I1, I2, I3 define a triangle. - Next triangle is defined by I2, I3, I4 (actually, I4, I3, I2 - to stay with same counterclockwise sense). - Next triangle is defined by I3, I4, I5 ( do not need to reverse - odd numbered triangles) and so on. - List is terminated with -1. -*/ - else if ( leqi ( level_name[level-1], "INDEXEDTRIANGLESTRIPSET" ) == TRUE ) { - - count = sscanf ( word, "%d%n", &jval, &width ); - - if ( count > 0 ) { - - if ( jval == -1 ) { - ivert = 0; - } - else { - - ix = iy; - iy = iz; - iz = jval + cor3_num_old; - - if ( ivert == 0 ) { - if ( face_num < FACE_MAX ) { - face[ivert][face_num] = jval + cor3_num_old; - face_order[face_num] = 3; - } - } - else if ( ivert == 1 ) { - if ( face_num < FACE_MAX ) { - face[ivert][face_num] = jval + cor3_num_old; - } - } - else if ( ivert == 2 ) { - if ( face_num < FACE_MAX ) { - face[ivert][face_num] = jval + cor3_num_old; - } - face_num = face_num + 1; - } - else { - - if ( face_num < FACE_MAX ) { - face_order[face_num] = 3; - if ( ( ivert % 2 ) == 0 ) { - face[0][face_num] = ix; - face[1][face_num] = iy; - face[2][face_num] = iz; - } - else { - face[0][face_num] = iz; - face[1][face_num] = iy; - face[2][face_num] = ix; - } - } - face_num = face_num + 1; - } - ivert = ivert + 1; -/* - Very very tentative guess as to how indices into the normal - vector array are set up... -*/ - if ( face_num < FACE_MAX && ivert > 2 ) { - for ( i = 0; i < 3; i++ ) { - face_normal[i][face_num] = normal_temp[i][ix]; - } - } - } - } - } - } -/* - INDEXEDFACESET -*/ - else if ( leqi ( level_name[level], "INDEXEDFACESET" ) == TRUE ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( leqi ( word, "COORDINDEX" ) == TRUE ) { - ivert = 0; - } - else if ( leqi ( word, "MATERIALINDEX" ) == TRUE ) { - } - else if ( leqi ( word, "NORMALINDEX" ) == TRUE ) { - } - else if ( leqi ( word, "TEXTURECOORDINDEX" ) == TRUE ) { - if ( texture_num <= 0 ) { - texture_num = 1; - strcpy ( texture_name[0], "Texture_0000" ); - } - } - else { - bad_num = bad_num + 1; - printf ( "Bad data %s\n", word ); - } - } -/* - INDEXEDLINESET -*/ - else if ( leqi ( level_name[level], "INDEXEDLINESET" ) == TRUE ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( leqi ( word, "COORDINDEX" ) == TRUE ) { - } - else if ( leqi ( word, "MATERIALINDEX" ) == TRUE ) { - } - else { - bad_num = bad_num + 1; - printf ( "Bad data %s\n", word ); - } - } -/* - INDEXEDNURBSSURFACE -*/ - else if ( leqi ( level_name[level], "INDEXEDNURBSSURFACE" ) == TRUE ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( leqi ( word, "NUMUCONTROLPOINTS") == TRUE ) { - - count = sscanf ( word, "%d%n", &jval, &width ); - - if ( count > 0 ) { - nu = jval; - if ( debug ) { - printf ( "NU = %d\n", nu ); - } - } - else { - nu = 0; - bad_num = bad_num + 1; - printf ( "Bad data %s\n", word ); - } - } - else if ( leqi ( word, "NUMVCONTROLPOINTS" ) == TRUE ) { - - count = sscanf ( word, "%d%n", &jval, &width ); - - if ( count > 0 ) { - nv = jval; - if ( debug ) { - printf ( "NV = %d\n", nv ); - } - } - else { - nv = 0; - bad_num = bad_num + 1; - } - } - else if ( leqi ( word, "COORDINDEX" ) == TRUE ) { - } - else if ( leqi ( word, "UKNOTVECTOR" ) == TRUE ) { - } - else if ( leqi ( word, "VKNOTVECTOR" ) == TRUE ) { - } - else { - bad_num = bad_num + 1; - printf ( "Bad data %s\n", word ); - } - } -/* - INDEXEDTRIANGLESTRIPSET -*/ - else if ( leqi ( level_name[level], "INDEXEDTRIANGLESTRIPSET" ) == TRUE ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( leqi ( word, "VERTEXPROPERTY" ) == TRUE ) { - count = sscanf ( next, "%s%n", word, &width ); - next = next + width; - } - else if ( leqi ( word, "COORDINDEX" ) == TRUE ) { - ivert = 0; - } - else if ( leqi ( word, "NORMALINDEX" ) == TRUE ) { - count = sscanf ( next, "%s%n", word, &width ); - next = next + width; - } - else { - bad_num = bad_num + 1; - printf ( "Bad data %s\n", word ); - } - } -/* - INFO -*/ - else if ( leqi ( level_name[level], "INFO" ) == TRUE ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( leqi ( word, "STRING" ) == TRUE ) { - } - else if ( strcmp ( word, "\"" ) == 0 ) { - } - else { - } - } -/* - LIGHTMODEL - Read, but ignore. -*/ - else if ( leqi ( level_name[level], "LIGHTMODEL" ) == TRUE ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( leqi ( word, "model" ) == TRUE ) { - } - else { - } - } -/* - MATERIAL - Read, but ignore. -*/ - else if ( leqi ( level_name[level],"MATERIAL" ) == TRUE ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( leqi ( word, "AMBIENTCOLOR" ) == TRUE ) { - } - else if ( leqi ( word, "EMISSIVECOLOR" ) == TRUE ) { - } - else if ( leqi ( word, "DIFFUSECOLOR" ) == TRUE ) { - } - else if ( leqi ( word, "SHININESS" ) == TRUE ) { - } - else if ( leqi ( word, "SPECULARCOLOR" ) == TRUE ) { - } - else if ( leqi ( word, "TRANSPARENCY" ) == TRUE ) { - } - else { - } - } -/* - MATERIALBINDING - Read, but ignore -*/ - else if ( leqi ( level_name[level], "MATERIALBINDING" ) == TRUE ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( leqi ( word, "VALUE" ) == TRUE ) { - count = sscanf ( next, "%s%n", material_binding, &width ); - next = next + width; - } - else { - count = sscanf ( next, "%f%n", &rval, &width ); - next = next + width; - - if ( count > 0 ) { - } - else { - bad_num = bad_num + 1; - printf ( "Bad data %s\n", word ); - } - } - } -/* - MATERIALINDEX -*/ - else if ( leqi ( level_name[level], "MATERIALINDEX" ) == TRUE ) { - - if ( strcmp ( word, "[" ) == 0 ) { - ivert = 0; - } - else if ( strcmp ( word, "]" ) == 0 ) { - level = nlbrack - nrbrack; - } -/* - (indexedfaceset) MATERIALINDEX -*/ - else if ( leqi ( level_name[level-1], "INDEXEDFACESET" ) == TRUE ) { - - count = sscanf ( word, "%d%n", &jval, &width ); - - if ( count > 0 ) { - - if ( jval == -1 ) { - ivert = 0; - face_num2 = face_num2 + 1; - } - else { - - if ( face_num2 < FACE_MAX ) { - if ( jval != -1 ) { - jval = jval + cor3_num_old; - } - vertex_material[ivert][face_num2] = jval; - ivert = ivert + 1; - } - } - } - else { - bad_num = bad_num + 1; - printf ( "Bad data %s\n", word ); - } - } -/* - (indexedlineset) MATERIALINDEX -*/ - else if ( leqi ( level_name[level-1], "INDEXEDLINESET" ) == TRUE ) { - - count = sscanf ( word, "%d%n", &jval, &width ); - - if ( count > 0 ) { - - if ( line_num2 < LINES_MAX ) { - if ( jval != -1 ) { - jval = jval + cor3_num_old; - } - line_material[line_num2] = jval; - line_num2 = line_num2 + 1; - } - } - else { - bad_num = bad_num + 1; - printf ( "Bad data %s\n", word ); - } - } - else { - count = sscanf ( word, "%d%n", &jval, &width ); - - if ( count > 0 ) { - } - else { - bad_num = bad_num + 1; - printf ( "Bad data %s\n", word ); - } - } - } -/* - MATRIXTRANSFORM. -*/ - else if ( leqi ( level_name[level], "MATRIXTRANSFORM" ) == TRUE ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( leqi ( word, "MATRIX" ) == TRUE ) { - icol = -1; - irow = 0; - } - else { - - count = sscanf ( word, "%f%n", &rval, &width ); - - if ( count > 0 ) { - - icol = icol + 1; - if ( icol > 3 ) { - icol = 0; - irow = irow + 1; - if ( irow > 3 ) { - irow = 0; - } - } - - transform_matrix[irow][icol] = rval; - } - - } - } -/* - NORMAL - The field "VECTOR" may be followed by three numbers, - (handled here), or by a square bracket, and sets of three numbers. -*/ - else if ( leqi ( level_name[level], "NORMAL" ) == TRUE ) { -/* - (vertexproperty) NORMAL -*/ - if ( leqi ( level_name[level-1], "VERTEXPROPERTY" ) == TRUE ) { - - if ( strcmp ( word, "[" ) == 0 ) { - ixyz = 0; - } - else if ( strcmp ( word, "]" ) == 0 ) { - level = nlbrack - nrbrack; - } - else { - - count = sscanf ( word, "%f%n", &rval, &width ); - - if ( count > 0 ) { - - if ( inormface < FACE_MAX ) { - face_normal[ixyz][inormface] = rval; - } - - ixyz = ixyz + 1; - if ( ixyz > 2 ) { - ixyz = 0; - inormface = inormface + 1; - } - } - } - } -/* - (anythingelse) NORMAL -*/ - else { - - if ( strcmp ( word, "{" ) == 0 ) { - ixyz = 0; - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( leqi ( word, "VECTOR" ) == TRUE ) { - } - else { - - count = sscanf ( word, "%f%n", &rval, &width ); - - if ( count > 0 ) { - -/* COMMENTED OUT - - if ( nfnorm < FACE_MAX ) { - normal[ixyz][nfnorm] = rval; - } - -*/ - ixyz = ixyz + 1; - if ( ixyz > 2 ) { - ixyz = 0; - } - } - else { - bad_num = bad_num + 1; - printf ( "Bad data %s\n", word ); - } - } - } - } -/* - NORMALBINDING - Read, but ignore -*/ - else if ( leqi ( level_name[level], "NORMALBINDING" ) == TRUE ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( leqi ( word, "VALUE" ) == TRUE ) { - count = sscanf ( next, "%s%n", normal_binding, &width ); - next = next + width; - } - else { - count = sscanf ( word, "%f%n", &rval, &width ); - - if ( count > 0 ) { - } - else { - bad_num = bad_num + 1; - printf ( "Bad data %s\n", word ); - } - } - } -/* - NORMALINDEX -*/ - else if ( leqi ( level_name[level], "NORMALINDEX" ) == TRUE ) { -/* - (indexedtrianglestripset) NORMALINDEX -*/ - if ( leqi ( level_name[level-1], "INDEXEDTRIANGLESTRIPSET" ) == TRUE ) { - count = sscanf ( word, "%d%n", &jval, &width ); - - if ( count > 0 ) { - } - else if ( strcmp ( word, "[" ) == 0 ) { - } - else if ( strcmp ( word, "]" ) == 0 ) { - } - } -/* - (anythingelse) NORMALINDEX -*/ - else { - - if ( strcmp ( word, "[" ) == 0 ) { - ivert = 0; - } - else if ( strcmp ( word, "]" ) == 0 ) { - level = nlbrack - nrbrack; - } - else { - - count = sscanf ( word, "%d%n", &jval, &width ); - - if ( count > 0 ) { - if ( jval == -1 ) { - ivert = 0; - iface_num = iface_num + 1; - } - else { - if ( iface_num < FACE_MAX ) { - for ( i = 0; i < 3; i++ ){ - vertex_normal[i][ivert][iface_num] = normal_temp[i][jval]; - } - ivert = ivert + 1; - } - } - } - else { - bad_num = bad_num + 1; - printf ( "Bad data %s\n", word ); - } - } - } - } -/* - (coordinate3) POINT -*/ - else if ( leqi ( level_name[level], "POINT" ) == TRUE ) { - - if ( leqi ( level_name[level-1], "COORDINATE3" ) == TRUE ) { - - if ( strcmp ( word, "[" ) == 0 ) { - ixyz = 0; - cor3_num_old = cor3_num; - } - else if ( strcmp ( word, "]" ) == 0 ) { - level = nlbrack - nrbrack; - } - else { - - count = sscanf ( word, "%f%n", &rval, &width ); - - if ( count > 0 ) { - - if ( cor3_num < COR3_MAX ) { - xvec[ixyz] = rval; - } - - ixyz = ixyz + 1; - - if ( ixyz == 3 ) { - - ixyz = 0; - - tmat_mxp ( transform_matrix, xvec, xvec ); - - cor3[0][cor3_num] = xvec[0]; - cor3[1][cor3_num] = xvec[1]; - cor3[2][cor3_num] = xvec[2]; - - cor3_num = cor3_num + 1; - - continue; - } - } - else { - bad_num = bad_num + 1; - break; - } - } - } -/* - (texturecoodinate2) POINT -*/ - else if ( leqi ( level_name[level-1], "TEXTURECOORDINATE2" ) == TRUE ) { - - if ( strcmp ( word, "[" ) == 0 ) { - iuv = 0; - text_numure_temp = 0; - } - else if ( strcmp ( word, "]" ) == 0 ) { - level = nlbrack - nrbrack; - } - else { - - count = sscanf ( word, "%f%n", &rval, &width ); - - if ( count > 0 ) { - - texture_temp[iuv][text_numure_temp] = rval; - - iuv = iuv + 1; - if ( iuv == 2 ) { - iuv = 0; - text_numure_temp = text_numure_temp + 1; - } - } - else { - printf ( "TextureCoordinate2 { Point [: Bad data\n" ); - bad_num = bad_num + 1; - break; - } - } - } - } -/* - RGB -*/ - else if ( leqi ( level_name[level],"RGB" ) == TRUE ) { -/* - (basecolor) RGB -*/ - if ( leqi ( level_name[level-1], "BASECOLOR" ) == TRUE ) { - - if ( strcmp ( word, "[" ) == 0 ) { - icolor = 0; - } - else if ( strcmp ( word, "]" ) == 0 ) { - level = nlbrack - nrbrack; - } - else { - - count = sscanf ( word, "%f%n", &rval, &width ); - - if ( count > 0 ) { - - rgbcolor[icolor][color_num] = rval; - icolor = icolor + 1; - - if ( icolor == 3 ) { - icolor = 0; - color_num = color_num + 1; - } - } - else { - bad_num = bad_num + 1; - printf ( "Bad data %s\n", word ); - } - } - } -/* - (anythingelse RGB) -*/ - else { - - printf ( "HALSBAND DES TODES!\n" ); - - if ( strcmp ( word, "[" ) == 0 ) { - icolor = 0; - ivert = 0; - } - else if ( strcmp ( word, "]" ) == 0 ) { - level = nlbrack - nrbrack; - } - else { - - count = sscanf ( word, "%f%n", &rval, &width ); - - if ( count > 0 ) { - - if ( icface < FACE_MAX ) { - - vertex_rgb[icolor][ivert][icface] = rval; - - icolor = icolor + 1; - if ( icolor == 3 ) { - icolor = 0; - color_num = color_num + 1; - ivert = ivert + 1; - if ( ivert == face_order[icface] ) { - ivert = 0; - icface = icface + 1; - } - } - } - } - else { - bad_num = bad_num + 1; - printf ( "Bad data %s\n", word ); - } - } - } - - } -/* - SEPARATOR -*/ - else if ( leqi ( level_name[level], "SEPARATOR" ) == TRUE ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else { - } - } -/* - SHAPEHINTS - Read, but ignore. -*/ - else if ( leqi ( level_name[level], "SHAPEHINTS" ) == TRUE ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( leqi ( word, "CREASEANGLE" ) == TRUE ) { - - count = sscanf ( next, "%f%n", &rval, &width ); - next = next + width; - - if ( count <= 0 ) { - bad_num = bad_num + 1; - printf ( "Bad data %s\n", word ); - } - } - else if ( leqi ( word, "FACETYPE" ) == TRUE ) { - count = sscanf ( next, "%s%n", word, &width ); - next = next + width; - } - else if ( leqi ( word, "SHAPETYPE" ) == TRUE ) { - count = sscanf ( next, "%s%n", word, &width ); - next = next + width; - } - else if ( leqi ( word, "VERTEXORDERING" ) == TRUE ) { - count = sscanf ( next, "%s%n", word, &width ); - next = next + width; - } - else { - bad_num = bad_num + 1; - printf ( "Bad data %s\n", word ); - } - } -/* - TEXTURE2 -*/ - else if ( leqi ( level_name[level], "TEXTURE2" ) == TRUE ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - texture_num = texture_num + 1; - } - else if ( leqi ( word, "BLENDCOLOR" ) == TRUE ) { - } -/* - NEED TO REMOVE QUOTES SURROUNDING TEXTURE NAME. -*/ - else if ( leqi ( word, "FILENAME" ) == TRUE ) { - - count = sscanf ( next, "%s%n", word, &width ); - next = next + width; - - strcpy ( texture_name[texture_num], word ); - - i = 0; - j = 0; - do { - c = texture_name[texture_num][i]; - i = i + 1; - if ( c != '"' ) { - texture_name[texture_num][j] = c; - j = j + 1; - } - } while ( c != '\0' ); - - } - else if ( leqi ( word, "IMAGE" ) == TRUE ) { - } - else if ( leqi ( word, "MODEL" ) == TRUE ) { - count = sscanf ( next, "%s%n", word, &width ); - next = next + width; - } - else if ( leqi ( word, "WRAPS" ) == TRUE ) { - count = sscanf ( next, "%s%n", word, &width ); - next = next + width; - } - else if ( leqi ( word, "WRAPT" ) == TRUE ) { - count = sscanf ( next, "%s%n", word, &width ); - next = next + width; - } - else { - } - } -/* - TEXTURECOORDINATE2 -*/ - else if ( leqi ( level_name[level], "TEXTURECOORDINATE2" ) == TRUE ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( leqi ( word, "POINT" ) == TRUE ) { - } - else { - bad_num = bad_num + 1; - printf ( "TEXTURECOORDINATE2: Bad data %s\n", word ); - } - } -/* - TEXTURECOORDINATEBINDING -*/ - else if ( leqi ( level_name[level], "TEXTURECOORDINATEBINDING" ) == TRUE ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( leqi ( word, "VALUE" ) == TRUE ) { - count = sscanf ( next, "%s%n", texture_binding, &width ); - next = next + width; - } - else { - bad_num = bad_num + 1; - printf ( "Bad data %s\n", word ); - } - } -/* - TEXTURECOORDINDEX -*/ - else if ( leqi ( level_name[level], "TEXTURECOORDINDEX" ) == TRUE ) { - - if ( strcmp ( word, "[" ) == 0 ) { - ivert = 0; - iface_num = 0; - } - else if ( strcmp ( word, "]" ) == 0 ) { - level = nlbrack - nrbrack; - } - else { - - count = sscanf ( word, "%d%n", &jval, &width ); - - if ( count > 0 ) { - - if ( jval == - 1 ) { - ivert = 0; - } - else { - - if ( iface_num < FACE_MAX ) { - vertex_tex_uv[0][ivert][iface_num] = texture_temp[0][jval]; - vertex_tex_uv[1][ivert][iface_num] = texture_temp[1][jval]; - } - - ivert = ivert + 1; - - if ( ivert == face_order[iface_num] ) { - ivert = 0; - iface_num = iface_num + 1; - } - } - - } - else { - bad_num = bad_num + 1; - printf ( "Bad data %s\n", word ); - } - - } - } -/* - UKNOTVECTOR -*/ - else if ( leqi ( level_name[level], "UKNOTVECTOR" ) == TRUE ) { - - if ( strcmp ( word, "[" ) == 0 ) { - continue; - } - else if ( strcmp ( word, "]" ) == 0 ) { - level = nlbrack - nrbrack; - continue; - } - else { - count = sscanf ( word, "%d%n", &jval, &width ); - } - } -/* - VECTOR -*/ - else if ( leqi ( level_name[level], "VECTOR" ) == TRUE ) { - if ( strcmp ( word, "[" ) == 0 ) { - } - else if ( strcmp ( word, "]" ) == 0 ) { - level = nlbrack - nrbrack; - } -/* - (normal) VECTOR -*/ - else if ( leqi ( level_name[level-1], "NORMAL" ) == TRUE ) { - - count = sscanf ( word, "%f%n", &rval, &width ); - - if ( count > 0 ) { - - if ( normal_num_temp < ORDER_MAX * FACE_MAX ) { - normal_temp[ixyz][normal_num_temp] = rval; - ixyz = ixyz + 1; - if ( ixyz == 3 ) { - ixyz = 0; - normal_num_temp = normal_num_temp + 1; - } - } - } - else { - bad_num = bad_num + 1; - printf ( "NORMAL VECTOR: bad data %s\n", word ); - } - } - } -/* - (vertexproperty) VERTEX -*/ - else if ( leqi ( level_name[level], "VERTEX" ) == TRUE ) { - - if ( leqi ( level_name[level-1], "VERTEXPROPERTY" ) == TRUE ) { - - if ( strcmp ( word, "[" ) == 0 ) { - ixyz = 0; - cor3_num_old = cor3_num; - } - else if ( strcmp ( word, "]" ) == 0 ) { - level = nlbrack - nrbrack; - } - else { - count = sscanf ( word, "%f%n", &rval, &width ); - - if ( count > 0 ) { - - if ( cor3_num < COR3_MAX ) { - cor3[ixyz][cor3_num] = rval; - } - ixyz = ixyz + 1; - if ( ixyz == 3 ) { - ixyz = 0; - cor3_num = cor3_num + 1; - } - - } - else { - bad_num = bad_num + 1; - printf ( "Bad data %s\n", word ); - } - } - } - } -/* - (indexedtrianglestripset) VERTEXPROPERTY -*/ - else if ( leqi ( level_name[level], "VERTEXPROPERTY" ) == TRUE ) { - - if ( strcmp ( word, "{" ) == 0 ) { - } - else if ( strcmp ( word, "}" ) == 0 ) { - level = nlbrack - nrbrack; - } - else if ( leqi ( word, "VERTEX" ) == TRUE ) { - } - else if ( leqi ( word, "NORMAL" ) == TRUE ) { - ixyz = 0; - } - else if ( leqi ( word, "MATERIALBINDING" ) == TRUE ) { - count = sscanf ( next, "%s%n", word, &width ); - next = next + width; - } - else if ( leqi ( word, "NORMALBINDING" ) == TRUE ) { - count = sscanf ( next, "%s%n", word, &width ); - next = next + width; - } - else { - bad_num = bad_num + 1; - printf ( "Bad data %s\n", word ); - } - } -/* - VKNOTVECTOR -*/ - else if ( leqi ( level_name[level], "VKNOTVECTOR" ) == TRUE ) { - - if ( strcmp ( word, "[" ) == 0 ) { - continue; - } - else if ( strcmp ( word, "]" ) == 0 ) { - level = nlbrack - nrbrack; - continue; - } - else { - count = sscanf ( word, "%d%n", &jval, &width ); - } - } -/* - Any other word: -*/ - else { - } - } - } -/* - Reset the transformation matrix to the identity, - because, presumably, we've applied it by now. -*/ - tmat_init ( transform_matrix ); - - return SUCCESS; -} -/******************************************************************************/ - -int iv_write ( FILE *fileout ) - -/******************************************************************************/ - -/* - Purpose: - - IV_WRITE writes graphics information to an Inventor file. - - Modified: - - 29 June 1999 - - Author: - - John Burkardt -*/ -{ - int icor3; - int iface; - int itemp; - int ivert; - int j; - int length; - int text_num; - - text_num = 0; - - fprintf ( fileout, "#Inventor V2.0 ascii\n" ); - fprintf ( fileout, "\n" ); - fprintf ( fileout, "Separator {\n" ); - fprintf ( fileout, " Info {\n" ); - fprintf ( fileout, " string \"%s generated by IVCON.\"\n", fileout_name ); - fprintf ( fileout, " string \"Original data in file %s.\"\n", filein_name ); - fprintf ( fileout, " }\n" ); - fprintf ( fileout, " Separator {\n" ); - text_num = text_num + 8; -/* - LightModel: - - BASE_COLOR ignores light sources, and uses only diffuse color - and transparency. Even without normal vector information, - the object will show up. However, you won't get shadow - and lighting effects. - - PHONG uses the Phong lighting model, accounting for light sources - and surface orientation. This is the default. I believe - you need accurate normal vector information in order for this - option to produce nice pictures. - - DEPTH ignores light sources, and calculates lighting based on - the location of the object within the near and far planes - of the current camera's view volume. -*/ - fprintf ( fileout, " LightModel {\n" ); - fprintf ( fileout, " model PHONG\n" ); - fprintf ( fileout, " }\n" ); - text_num = text_num + 3; -/* - Transformation matrix. -*/ - fprintf ( fileout, " MatrixTransform { matrix\n" ); - fprintf ( fileout, " %f %f %f %f\n", transform_matrix[0][0], - transform_matrix[0][1], transform_matrix[0][2], transform_matrix[0][3] ); - fprintf ( fileout, " %f %f %f %f\n", transform_matrix[1][0], - transform_matrix[1][1], transform_matrix[1][2], transform_matrix[1][3] ); - fprintf ( fileout, " %f %f %f %f\n", transform_matrix[2][0], - transform_matrix[2][1], transform_matrix[2][2], transform_matrix[2][3] ); - fprintf ( fileout, " %f %f %f %f\n", transform_matrix[3][0], - transform_matrix[3][1], transform_matrix[3][2], transform_matrix[3][3] ); - fprintf ( fileout, " }\n" ); - text_num = text_num + 6; -/* - Material. -*/ - fprintf ( fileout, " Material {\n" ); - fprintf ( fileout, " ambientColor 0.2 0.2 0.2\n" ); - fprintf ( fileout, " diffuseColor 0.8 0.8 0.8\n" ); - fprintf ( fileout, " emissiveColor 0.0 0.0 0.0\n" ); - fprintf ( fileout, " specularColor 0.0 0.0 0.0\n" ); - fprintf ( fileout, " shininess 0.2\n" ); - fprintf ( fileout, " transparency 0.0\n" ); - fprintf ( fileout, " }\n" ); - text_num = text_num + 8; -/* - MaterialBinding -*/ - fprintf ( fileout, " MaterialBinding {\n" ); - fprintf ( fileout, " value PER_VERTEX_INDEXED\n" ); - fprintf ( fileout, " }\n" ); - text_num = text_num + 3; -/* - NormalBinding - - PER_VERTEX promises that we will write a list of normal vectors - in a particular order, namely, the normal vectors for the vertices - of the first face, then the second face, and so on. - - PER_VERTEX_INDEXED promises that we will write a list of normal vectors, - and then, as part of the IndexedFaceSet, we will give a list of - indices referencing this normal vector list. -*/ - fprintf ( fileout, " NormalBinding {\n" ); - fprintf ( fileout, " value PER_VERTEX_INDEXED\n" ); - fprintf ( fileout, " }\n" ); - text_num = text_num + 3; -/* - Texture2. - - FLAW: We can only handle on texture right now. -*/ - if ( texture_num > 0 ) { - fprintf ( fileout, " Texture2 {\n" ); - fprintf ( fileout, " filename \"%s\"\n", texture_name[0] ); - fprintf ( fileout, " wrapS REPEAT\n" ); - fprintf ( fileout, " wrapT REPEAT\n" ); - fprintf ( fileout, " model MODULATE\n" ); - fprintf ( fileout, " blendColor 0.0 0.0 0.0\n" ); - fprintf ( fileout, " }\n" ); - text_num = text_num + 7; - } -/* - TextureCoordinateBinding -*/ - fprintf ( fileout, " TextureCoordinateBinding {\n" ); - fprintf ( fileout, " value PER_VERTEX_INDEXED\n" ); - fprintf ( fileout, " }\n" ); - text_num = text_num + 3; -/* - ShapeHints -*/ - fprintf ( fileout, " ShapeHints {\n" ); - fprintf ( fileout, " vertexOrdering COUNTERCLOCKWISE\n" ); - fprintf ( fileout, " shapeType UNKNOWN_SHAPE_TYPE\n" ); - fprintf ( fileout, " faceType CONVEX\n" ); - fprintf ( fileout, " creaseAngle 6.28319\n" ); - fprintf ( fileout, " }\n" ); - text_num = text_num + 6; -/* - Point coordinates. -*/ - fprintf ( fileout, " Coordinate3 {\n" ); - fprintf ( fileout, " point [\n" ); - text_num = text_num + 2; - - for ( j = 0; j < cor3_num; j++ ) { - fprintf ( fileout, " %f %f %f,\n", cor3[0][j], cor3[1][j], cor3[2][j] ); - text_num = text_num + 1; - } - fprintf ( fileout, " ]\n" ); - fprintf ( fileout, " }\n" ); - text_num = text_num + 2; -/* - Texture coordinates. -*/ - fprintf ( fileout, " TextureCoordinate2 {\n" ); - fprintf ( fileout, " point [\n" ); - text_num = text_num + 2; - - for ( iface = 0; iface < face_num; iface++ ) { - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - fprintf ( fileout, " %f %f,\n", vertex_tex_uv[0][ivert][iface], - vertex_tex_uv[1][ivert][iface] ); - text_num = text_num + 1; - } - } - fprintf ( fileout, " ]\n" ); - fprintf ( fileout, " }\n" ); - text_num = text_num + 2; -/* - BaseColor. -*/ - if ( color_num > 0 ) { - - fprintf ( fileout, " BaseColor {\n" ); - fprintf ( fileout, " rgb [\n" ); - text_num = text_num + 2; - - for ( j = 0; j < color_num; j++ ) { - fprintf ( fileout, " %f %f %f,\n", rgbcolor[0][j], rgbcolor[1][j], - rgbcolor[2][j] ); - text_num = text_num + 1; - } - - fprintf ( fileout, " ]\n" ); - fprintf ( fileout, " }\n" ); - text_num = text_num + 2; - } -/* - Normal vectors. - Use the normal vectors associated with nodes. -*/ - if ( face_num > 0 ) { - - fprintf ( fileout, " Normal { \n" ); - fprintf ( fileout, " vector [\n" ); - text_num = text_num + 2; - - for ( icor3 = 0; icor3 < cor3_num; icor3++ ) { - fprintf ( fileout, " %f %f %f,\n", - cor3_normal[0][icor3], - cor3_normal[1][icor3], - cor3_normal[2][icor3] ); - text_num = text_num + 1; - } - - fprintf ( fileout, " ]\n" ); - fprintf ( fileout, " }\n" ); - text_num = text_num + 2; - } -/* - IndexedLineSet -*/ - if ( line_num > 0 ) { - - fprintf ( fileout, " IndexedLineSet {\n" ); -/* - IndexedLineSet coordIndex -*/ - fprintf ( fileout, " coordIndex [\n" ); - text_num = text_num + 2; - - length = 0; - - for ( j = 0; j < line_num; j++ ) { - - if ( length == 0 ) { - fprintf ( fileout, " " ); - } - - fprintf ( fileout, " %d,", line_dex[j] ); - length = length + 1; - - if ( line_dex[j] == -1 || length >= 10 || j == line_num-1 ) { - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - length = 0; - } - } - - fprintf ( fileout, " ]\n" ); - text_num = text_num + 1; -/* - IndexedLineSet materialIndex. -*/ - fprintf ( fileout, " materialIndex [\n" ); - text_num = text_num + 1; - - length = 0; - - for ( j = 0; j < line_num; j++ ) { - - if ( length == 0 ) { - fprintf ( fileout, " " ); - } - - fprintf ( fileout, " %d,", line_material[j] ); - length = length + 1; - - if ( line_material[j] == -1 || length >= 10 || j == line_num-1 ) { - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - length = 0; - } - } - - fprintf ( fileout, " ]\n" ); - fprintf ( fileout, " }\n" ); - text_num = text_num + 2; - } -/* - IndexedFaceSet. -*/ - if ( face_num > 0 ) { - - fprintf ( fileout, " IndexedFaceSet {\n" ); - fprintf ( fileout, " coordIndex [\n" ); - text_num = text_num + 2; - - for ( iface = 0; iface < face_num; iface++ ) { - - fprintf ( fileout, " " ); - - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - fprintf ( fileout, " %d,", face[ivert][iface] ); - } - fprintf ( fileout, " -1,\n" ); - text_num = text_num + 1; - } - - fprintf ( fileout, " ]\n" ); - text_num = text_num + 1; -/* - IndexedFaceSet normalIndex -*/ - fprintf ( fileout, " normalIndex [\n" ); - text_num = text_num + 1; - - for ( iface = 0; iface < face_num; iface++ ) { - - fprintf ( fileout, " " ); - - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - fprintf ( fileout, " %d,", face[ivert][iface] ); - } - fprintf ( fileout, " -1,\n" ); - text_num = text_num + 1; - } - fprintf ( fileout, " ]\n" ); - text_num = text_num + 1; -/* - IndexedFaceSet materialIndex -*/ - fprintf ( fileout, " materialIndex [\n" ); - text_num = text_num + 1; - - for ( iface = 0; iface < face_num; iface++ ) { - - fprintf ( fileout, " " ); - - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - fprintf ( fileout, " %d,", vertex_material[ivert][iface] ); - } - fprintf ( fileout, " -1,\n" ); - text_num = text_num + 1; - } - - fprintf ( fileout, " ]\n" ); - text_num = text_num + 1; -/* - IndexedFaceSet textureCoordIndex -*/ - fprintf ( fileout, " textureCoordIndex [\n" ); - text_num = text_num + 1; - - itemp = 0; - - for ( iface = 0; iface < face_num; iface++ ) { - - fprintf ( fileout, " " ); - - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - fprintf ( fileout, " %d,", itemp ); - itemp = itemp + 1; - } - fprintf ( fileout, " -1,\n" ); - text_num = text_num + 1; - } - - fprintf ( fileout, " ]\n" ); - - fprintf ( fileout, " }\n" ); - text_num = text_num + 2; - } -/* - Close up the Separator nodes. -*/ - fprintf ( fileout, " }\n" ); - fprintf ( fileout, "}\n" ); - text_num = text_num + 2; -/* - Report. -*/ - printf ( "\n" ); - printf ( "IV_WRITE - Wrote %d text lines;\n", text_num ); - - return SUCCESS; -} -/******************************************************************************/ - -int ivec_max ( int n, int *a ) - -/******************************************************************************/ - -/* - Purpose: - - IVEC_MAX returns the maximum element in an integer array. - - Modified: - - 09 October 1998 - - Author: - - John Burkardt -*/ -{ - int i; - int *ia; - int imax; - - if ( n <= 0 ) { - imax = 0; - } - else { - ia = a; - imax = *ia; - for ( i = 1; i < n; i++ ) { - ia = ia + 1; - if ( imax < *ia ) { - imax = *ia; - } - } - } - return imax; -} -/******************************************************************************/ - -int leqi ( char* string1, char* string2 ) - -/******************************************************************************/ - -/* - Purpose: - - LEQI compares two strings for equality, disregarding case. - - Modified: - - 15 September 1998 - - Author: - - John Burkardt -*/ -{ - int i; - int nchar; - int nchar1; - int nchar2; - - nchar1 = strlen ( string1 ); - nchar2 = strlen ( string2 ); - - if ( nchar1 < nchar2 ) { - nchar = nchar1; - } - else { - nchar = nchar2; - } -/* - The strings are not equal if they differ over their common length. -*/ - for ( i = 0; i < nchar; i++ ) { - - if ( toupper ( string1[i] ) != toupper ( string2[i] ) ) { - return FALSE; - } - } -/* - The strings are not equal if the longer one includes nonblanks - in the tail. -*/ - if ( nchar1 > nchar ) { - for ( i = nchar; i < nchar1; i++ ) { - if ( string1[i] != ' ' ) { - return FALSE; - } - } - } - else if ( nchar2 > nchar ) { - for ( i = nchar; i < nchar2; i++ ) { - if ( string2[i] != ' ' ) { - return FALSE; - } - } - } - return TRUE; -} -/******************************************************************************/ - -long int long_int_read ( FILE *filein ) - -/******************************************************************************/ - -/* - Purpose: - - LONG_INT_READ reads a long int from a binary file. - - Modified: - - 24 May 1999 - - Author: - - John Burkardt -*/ -{ - union { - long int yint; - char ychar[4]; - } y; - - if ( byte_swap == TRUE ) { - y.ychar[3] = fgetc ( filein ); - y.ychar[2] = fgetc ( filein ); - y.ychar[1] = fgetc ( filein ); - y.ychar[0] = fgetc ( filein ); - } - else { - y.ychar[0] = fgetc ( filein ); - y.ychar[1] = fgetc ( filein ); - y.ychar[2] = fgetc ( filein ); - y.ychar[3] = fgetc ( filein ); - } - - return y.yint; -} -/******************************************************************************/ - -int long_int_write ( FILE *fileout, long int int_val ) - -/******************************************************************************/ - -/* - Purpose: - - LONG_INT_WRITE writes a long int to a binary file. - - Modified: - - 14 October 1998 - - Author: - - John Burkardt -*/ -{ - union { - long int yint; - char ychar[4]; - } y; - - y.yint = int_val; - - if ( byte_swap == TRUE ) { - fputc ( y.ychar[3], fileout ); - fputc ( y.ychar[2], fileout ); - fputc ( y.ychar[1], fileout ); - fputc ( y.ychar[0], fileout ); - } - else { - fputc ( y.ychar[0], fileout ); - fputc ( y.ychar[1], fileout ); - fputc ( y.ychar[2], fileout ); - fputc ( y.ychar[3], fileout ); - } - - return 4; -} -/******************************************************************************/ - -void news ( void ) - -/******************************************************************************/ - -/* - Purpose: - - NEWS reports the program change history. - - Modified: - - 26 September 1999 - - Author: - - John Burkardt -*/ -{ - printf ( "\n" ); - printf ( "Recent changes:\n" ); - printf ( "\n" ); - printf ( " 04 July 2000\n" ); - printf ( " Added preliminary XGL_WRITE.\n" ); - printf ( " 26 September 1999\n" ); - printf ( " After ASE_READ, call NODE_TO_VERTEX_MAT and VERTEX_TO_FACE_MATERIAL.\n" ); - printf ( " 27 July 1999\n" ); - printf ( " Corrected TMAT_ROT_VECTOR.\n" ); - printf ( " 17 July 1999\n" ); - printf ( " Added null edge and face deletion.\n" ); - printf ( " Corrected a string problem in SMF_READ.\n" ); - printf ( " 03 July 1999\n" ); - printf ( " Fixed a problem with BINDING variables in SMF_READ.\n" ); - printf ( " 02 July 1999\n" ); - printf ( " Added limited texture support in 3DS/IV.\n" ); - printf ( " 26 June 1999\n" ); - printf ( " BYU_READ added.\n" ); - printf ( " 25 June 1999\n" ); - printf ( " BYU_WRITE added.\n" ); - printf ( " 22 June 1999\n" ); - printf ( " TRIB_READ added.\n" ); - printf ( " 16 June 1999\n" ); - printf ( " TRIB_WRITE Greg Hood binary triangle output routine added.\n" ); - printf ( " 10 June 1999\n" ); - printf ( " TRIA_WRITE Greg Hood ASCII triangle output routine added.\n" ); - printf ( " 09 June 1999\n" ); - printf ( " TEC_WRITE TECPLOT output routine added.\n" ); - printf ( " IV_READ and IV_WRITE use TRANSFORM_MATRIX now.\n" ); - printf ( " 26 May 1999\n" ); - printf ( " LINE_PRUNE option added for VLA_WRITE.\n" ); - printf ( " 24 May 1999\n" ); - printf ( " Added << command to append new graphics data to old.\n" ); - printf ( " Stuck in first draft STLB_READ/STLB_WRITE routines.\n" ); - printf ( " STLA_WRITE and STLB_WRITE automatically decompose \n" ); - printf ( " non-triangular faces before writing.\n" ); - printf ( " 23 May 1999\n" ); - printf ( " Stuck in first draft WRL_WRITE routine.\n" ); - printf ( " 22 May 1999\n" ); - printf ( " Faces converted to lines before calling VLA_WRITE.\n" ); - printf ( " Added UCD_WRITE.\n" ); - printf ( " Added MATERIAL/PATCH/TAGGEDPOINTS fields in HRC_READ.\n" ); - printf ( " 17 May 1999\n" ); - printf ( " Updated SMF_WRITE, SMF_READ to match code in IVREAD.\n" ); - printf ( " Added transformation matrix routines.\n" ); - printf ( " 16 May 1999\n" ); - printf ( " Zik Saleeba improved DXF support to handle polygons.\n" ); - printf ( " 15 April 1999\n" ); - printf ( " Zik Saleeba added Golgotha GMOD file format support.\n" ); - printf ( " 03 December 1998\n" ); - printf ( " Set up simple hooks in TDS_READ_MATERIAL_SECTION.\n" ); - printf ( " 02 December 1998\n" ); - printf ( " Set up simple hooks for texture map names.\n" ); - printf ( " 19 November 1998\n" ); - printf ( " IV_WRITE uses PER_VERTEX normal binding.\n" ); - printf ( " 18 November 1998\n" ); - printf ( " Added node normals.\n" ); - printf ( " Finally added the -RN option.\n" ); - printf ( " 17 November 1998\n" ); - printf ( " Added face node ordering reversal option.\n" ); - printf ( " 20 October 1998\n" ); - printf ( " Added DATA_REPORT.\n" ); - printf ( " 19 October 1998\n" ); - printf ( " SMF_READ and SMF_WRITE added.\n" ); - printf ( " 16 October 1998\n" ); - printf ( " Fixing a bug in IV_READ that chokes on ]} and other\n" ); - printf ( " cases where brackets aren't properly spaced.\n" ); - printf ( " 11 October 1998\n" ); - printf ( " Added face subset selection option S.\n" ); - printf ( " 09 October 1998\n" ); - printf ( " Reworking normal vector treatments.\n" ); - printf ( " Synchronizing IVREAD and IVCON.\n" ); - printf ( " POV_WRITE added.\n" ); - printf ( " 02 October 1998\n" ); - printf ( " IVCON reproduces BOX.3DS and CONE.3DS exactly.\n" ); - printf ( " 30 September 1998\n" ); - printf ( " IVCON compiled on the PC.\n" ); - printf ( " Interactive BYTE_SWAP option added for binary files.\n" ); - printf ( " 25 September 1998\n" ); - printf ( " OBJECT_NAME made available to store object name.\n" ); - printf ( " 23 September 1998\n" ); - printf ( " 3DS binary files can be written.\n" ); - printf ( " 15 September 1998\n" ); - printf ( " 3DS binary files can be read.\n" ); - printf ( " 01 September 1998\n" ); - printf ( " COR3_RANGE, FACE_NORMAL_AVE added.\n" ); - printf ( " Major modifications to normal vectors.\n" ); - printf ( " 24 August 1998\n" ); - printf ( " HRC_READ added.\n" ); - printf ( " 21 August 1998\n" ); - printf ( " TXT_WRITE improved.\n" ); - printf ( " 20 August 1998\n" ); - printf ( " HRC_WRITE can output lines as linear splines.\n" ); - printf ( " 19 August 1998\n" ); - printf ( " Automatic normal computation for OBJ files.\n" ); - printf ( " Added normal vector computation.\n" ); - printf ( " HRC_WRITE is working.\n" ); - printf ( " 18 August 1998\n" ); - printf ( " IV_READ/IV_WRITE handle BASECOLOR RGB properly now.\n" ); - printf ( " Improved treatment of face materials and normals.\n" ); - printf ( " 17 August 1998\n" ); - printf ( " ORDER_MAX increased to 35.\n" ); - printf ( " FACE_PRINT routine added.\n" ); - printf ( " INIT_DATA routine added.\n" ); - printf ( " 14 August 1998\n" ); - printf ( " IV_READ is working.\n" ); - printf ( " 13 August 1998\n" ); - printf ( " ASE_WRITE is working.\n" ); - printf ( " IV_WRITE is working.\n" ); - printf ( " 12 August 1998\n" ); - printf ( " ASE_READ is working.\n" ); - printf ( " 10 August 1998\n" ); - printf ( " DXF_WRITE is working.\n" ); - printf ( " DXF_READ is working.\n" ); - printf ( " 27 July 1998\n" ); - printf ( " Interactive mode is working.\n" ); - printf ( " OBJ_READ is working.\n" ); - printf ( " 25 July 1998\n" ); - printf ( " OBJ_WRITE is working.\n" ); - printf ( " 24 July 1998\n" ); - printf ( " DATA_CHECK checks the input data.\n" ); - printf ( " VLA_READ is working.\n" ); - printf ( " VLA_WRITE is working.\n" ); - printf ( " 23 July 1998\n" ); - printf ( " STL_WRITE is working.\n" ); - printf ( " 22 July 1998\n" ); - printf ( " STL_READ is working.\n" ); - printf ( " TXT_WRITE is working.\n" ); -} -/**********************************************************************/ - -void node_to_vertex_material ( void ) - -/**********************************************************************/ - -/* - Purpose: - - NODE_TO_VERTEX_MAT extends node material definitions to vertices. - - Discussion: - - A NODE is a point in space. - A VERTEX is a node as used in a particular face. - One node may be used as a vertex in several faces, or none. - - Modified: - - 22 May 1999 - - Author: - - John Burkardt -*/ -{ - int iface; - int ivert; - int node; - - for ( iface = 0; iface < face_num; iface++ ) { - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - node = face[ivert][iface]; - vertex_material[ivert][iface] = cor3_material[node]; - } - } - - return; -} -/******************************************************************************/ - -int obj_read ( FILE *filein ) - -/******************************************************************************/ - -/* - Purpose: - - OBJ_READ reads a Wavefront OBJ file. - - Example: - - # magnolia.obj - - mtllib ./vp.mtl - - g - v -3.269770 -39.572201 0.876128 - v -3.263720 -39.507999 2.160890 - ... - v 0.000000 -9.988540 0.000000 - g stem - s 1 - usemtl brownskn - f 8 9 11 10 - f 12 13 15 14 - ... - f 788 806 774 - - Modified: - - 20 October 1998 - - Author: - - John Burkardt -*/ -{ - int count; - int i; - int ivert; - char *next; - char *next2; - char *next3; - int node; - int vertex_normal_num; - float r1; - float r2; - float r3; - char token[LINE_MAX_LEN]; - char token2[LINE_MAX_LEN]; - int width; -/* - Initialize. -*/ - vertex_normal_num = 0; -/* - Read the next line of the file into INPUT. -*/ - while ( fgets ( input, LINE_MAX_LEN, filein ) != NULL ) { - - text_num = text_num + 1; -/* - Advance to the first nonspace character in INPUT. -*/ - for ( next = input; *next != '\0' && isspace(*next); next++ ) { - } -/* - Skip blank lines and comments. -*/ - - if ( *next == '\0' ) { - continue; - } - - if ( *next == '#' || *next == '$' ) { - comment_num = comment_num + 1; - continue; - } -/* - Extract the first word in this line. -*/ - sscanf ( next, "%s%n", token, &width ); -/* - Set NEXT to point to just after this token. -*/ - - next = next + width; -/* - BEVEL - Bevel interpolation. -*/ - if ( leqi ( token, "BEVEL" ) == TRUE ) { - continue; - } -/* - BMAT - Basis matrix. -*/ - else if ( leqi ( token, "BMAT" ) == TRUE ) { - continue; - } -/* - C_INTERP - Color interpolation. -*/ - else if ( leqi ( token, "C_INTERP" ) == TRUE ) { - continue; - } -/* - CON - Connectivity between free form surfaces. -*/ - else if ( leqi ( token, "CON" ) == TRUE ) { - continue; - } -/* - CSTYPE - Curve or surface type. -*/ - else if ( leqi ( token, "CSTYPE" ) == TRUE ) { - continue; - } -/* - CTECH - Curve approximation technique. -*/ - else if ( leqi ( token, "CTECH" ) == TRUE ) { - continue; - } -/* - CURV - Curve. -*/ - else if ( leqi ( token, "CURV" ) == TRUE ) { - continue; - } -/* - CURV2 - 2D curve. -*/ - else if ( leqi ( token, "CURV2" ) == TRUE ) { - continue; - } -/* - D_INTERP - Dissolve interpolation. -*/ - else if ( leqi ( token, "D_INTERP" ) == TRUE ) { - continue; - } -/* - DEG - Degree. -*/ - else if ( leqi ( token, "DEG" ) == TRUE ) { - continue; - } -/* - END - End statement. -*/ - else if ( leqi ( token, "END" ) == TRUE ) { - continue; - } -/* - F V1 V2 V3 - or - F V1/VT1/VN1 V2/VT2/VN2 ... - or - F V1//VN1 V2//VN2 ... - - Face. - A face is defined by the vertices. - Optionally, slashes may be used to include the texture vertex - and vertex normal indices. - - OBJ line node indices are 1 based rather than 0 based. - So we have to decrement them before loading them into FACE. -*/ - - else if ( leqi ( token, "F" ) == TRUE ) { - - ivert = 0; - face_order[face_num] = 0; -/* - Read each item in the F definition as a token, and then - take it apart. -*/ - for ( ;; ) { - - count = sscanf ( next, "%s%n", token2, &width ); - next = next + width; - - if ( count != 1 ) { - break; - } - - count = sscanf ( token2, "%d%n", &node, &width ); - next2 = token2 + width; - - if ( count != 1 ) { - break; - } - - if ( ivert < ORDER_MAX && face_num < FACE_MAX ) { - face[ivert][face_num] = node-1; - vertex_material[ivert][face_num] = 0; - face_order[face_num] = face_order[face_num] + 1; - } -/* - If there's a slash, skip to the next slash, and extract the - index of the normal vector. -*/ - if ( *next2 == '/' ) { - - for ( next3 = next2 + 1; next3 < token2 + LINE_MAX_LEN; next3++ ) { - - if ( *next3 == '/' ) { - next3 = next3 + 1; - count = sscanf ( next3, "%d%n", &node, &width ); - - node = node - 1; - if ( 0 <= node && node < vertex_normal_num ) { - for ( i = 0; i < 3; i++ ) { - vertex_normal[i][ivert][face_num] = normal_temp[i][node]; - } - } - break; - } - } - } - ivert = ivert + 1; - } - face_num = face_num + 1; - } - -/* - G - Group name. -*/ - - else if ( leqi ( token, "G" ) == TRUE ) { - continue; - } -/* - HOLE - Inner trimming hole. -*/ - else if ( leqi ( token, "HOLE" ) == TRUE ) { - continue; - } -/* - L - I believe OBJ line node indices are 1 based rather than 0 based. - So we have to decrement them before loading them into LINE_DEX. -*/ - - else if ( leqi ( token, "L" ) == TRUE ) { - - for ( ;; ) { - - count = sscanf ( next, "%d%n", &node, &width ); - next = next + width; - - if ( count != 1 ) { - break; - } - - if ( line_num < LINES_MAX ) { - line_dex[line_num] = node-1; - line_material[line_num] = 0; - } - line_num = line_num + 1; - - } - - if ( line_num < LINES_MAX ) { - line_dex[line_num] = -1; - line_material[line_num] = -1; - } - line_num = line_num + 1; - - } - -/* - LOD - Level of detail. -*/ - else if ( leqi ( token, "LOD" ) == TRUE ) { - continue; - } -/* - MG - Merging group. -*/ - else if ( leqi ( token, "MG" ) == TRUE ) { - continue; - } -/* - MTLLIB - Material library. -*/ - - else if ( leqi ( token, "MTLLIB" ) == TRUE ) { - continue; - } -/* - O - Object name. -*/ - else if ( leqi ( token, "O" ) == TRUE ) { - continue; - } -/* - P - Point. -*/ - else if ( leqi ( token, "P" ) == TRUE ) { - continue; - } -/* - PARM - Parameter values. -*/ - else if ( leqi ( token, "PARM" ) == TRUE ) { - continue; - } -/* - S - Smoothing group -*/ - else if ( leqi ( token, "S" ) == TRUE ) { - continue; - } -/* - SCRV - Special curve. -*/ - else if ( leqi ( token, "SCRV" ) == TRUE ) { - continue; - } -/* - SHADOW_OBJ - Shadow casting. -*/ - else if ( leqi ( token, "SHADOW_OBJ" ) == TRUE ) { - continue; - } -/* - SP - Special point. -*/ - else if ( leqi ( token, "SP" ) == TRUE ) { - continue; - } -/* - STECH - Surface approximation technique. -*/ - else if ( leqi ( token, "STECH" ) == TRUE ) { - continue; - } -/* - STEP - Stepsize. -*/ - else if ( leqi ( token, "CURV" ) == TRUE ) { - continue; - } -/* - SURF - Surface. -*/ - else if ( leqi ( token, "SURF" ) == TRUE ) { - continue; - } -/* - TRACE_OBJ - Ray tracing. -*/ - else if ( leqi ( token, "TRACE_OBJ" ) == TRUE ) { - continue; - } -/* - TRIM - Outer trimming loop. -*/ - else if ( leqi ( token, "TRIM" ) == TRUE ) { - continue; - } -/* - USEMTL - Material name. -*/ - else if ( leqi ( token, "USEMTL" ) == TRUE ) { - continue; - } - -/* - V X Y Z W - Geometric vertex. - W is optional, a weight for rational curves and surfaces. - The default for W is 1. -*/ - - else if ( leqi ( token, "V" ) == TRUE ) { - - sscanf ( next, "%e %e %e", &r1, &r2, &r3 ); - - if ( cor3_num < COR3_MAX ) { - cor3[0][cor3_num] = r1; - cor3[1][cor3_num] = r2; - cor3[2][cor3_num] = r3; - } - - cor3_num = cor3_num + 1; - - } -/* - VN - Vertex normals. -*/ - - else if ( leqi ( token, "VN" ) == TRUE ) { - - sscanf ( next, "%e %e %e", &r1, &r2, &r3 ); - - if ( vertex_normal_num < ORDER_MAX * FACE_MAX ) { - normal_temp[0][vertex_normal_num] = r1; - normal_temp[1][vertex_normal_num] = r2; - normal_temp[2][vertex_normal_num] = r3; - } - - vertex_normal_num = vertex_normal_num + 1; - - } -/* - VT - Vertex texture. -*/ - else if ( leqi ( token, "VT" ) == TRUE ) { - continue; - } -/* - VP - Parameter space vertices. -*/ - else if ( leqi ( token, "VP" ) == TRUE ) { - continue; - } -/* - Unrecognized -*/ - else { - bad_num = bad_num + 1; - } - - } - return SUCCESS; -} -/******************************************************************************/ - -int obj_write ( FILE *fileout ) - -/******************************************************************************/ - -/* - Purpose: - - OBJ_WRITE writes a Wavefront OBJ file. - - Example: - - # magnolia.obj - - mtllib ./vp.mtl - - g - v -3.269770 -39.572201 0.876128 - v -3.263720 -39.507999 2.160890 - ... - v 0.000000 -9.988540 0.000000 - g stem - s 1 - usemtl brownskn - f 8 9 11 10 - f 12 13 15 14 - ... - f 788 806 774 - - Modified: - - 01 September 1998 - - Author: - - John Burkardt -*/ -{ - int i; - int iface; - int indexvn; - int ivert; - int k; - int new; - int text_num; - float w; -/* - Initialize. -*/ - text_num = 0; - w = 1.0; - - fprintf ( fileout, "# %s created by IVCON.\n", fileout_name ); - fprintf ( fileout, "# Original data in %s.\n", filein_name ); - fprintf ( fileout, "\n" ); - fprintf ( fileout, "g %s\n", object_name ); - fprintf ( fileout, "\n" ); - - text_num = text_num + 5; -/* - V: vertex coordinates. -*/ - for ( i = 0; i < cor3_num; i++ ) { - fprintf ( fileout, "v %f %f %f\n", - cor3[0][i], cor3[1][i], cor3[2][i]); - text_num = text_num + 1; - } - -/* - VN: Vertex face normal vectors. -*/ - if ( face_num > 0 ) { - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - } - - for ( iface = 0; iface < face_num; iface++ ) { - - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - - fprintf ( fileout, "vn %f %f %f\n", vertex_normal[0][ivert][iface], - vertex_normal[1][ivert][iface], vertex_normal[2][ivert][iface] ); - text_num = text_num + 1; - } - } -/* - F: faces. -*/ - if ( face_num > 0 ) { - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - } - - indexvn = 0; - - for ( iface = 0; iface < face_num; iface++ ) { - - fprintf ( fileout, "f" ); - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - indexvn = indexvn + 1; - fprintf ( fileout, " %d//%d", face[ivert][iface]+1, indexvn ); - } - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - } -/* - L: lines. -*/ - if ( line_num > 0 ) { - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - } - - new = TRUE; - - for ( i = 0; i < line_num; i++ ) { - - k = line_dex[i]; - - if ( k == -1 ) { - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - new = TRUE; - } - else { - if ( new == TRUE ) { - fprintf ( fileout, "l" ); - new = FALSE; - } - fprintf ( fileout, " %d", k+1 ); - } - - } - - fprintf ( fileout, "\n" ); - text_num = text_num + 1; -/* - Report. -*/ - printf ( "\n" ); - printf ( "OBJ_WRITE - Wrote %d text lines.\n", text_num ); - - return SUCCESS; -} -/******************************************************************************/ - -int pov_write ( FILE *fileout ) - -/******************************************************************************/ - -/* - Purpose: - - POV_WRITE writes graphics information to a POV file. - - Example: - - // cone.pov created by IVCON. - // Original data in cone.iv - - #version 3.0 - #include "colors.inc" - #include "shapes.inc" - global_settings { assumed_gamma 2.2 } - - camera { - right < 4/3, 0, 0> - up < 0, 1, 0 > - sky < 0, 1, 0 > - angle 20 - location < 0, 0, -300 > - look_at < 0, 0, 0> - } - - light_source { < 20, 50, -100 > color White } - - background { color SkyBlue } - - #declare RedText = texture { - pigment { color rgb < 0.8, 0.2, 0.2> } - finish { ambient 0.2 diffuse 0.5 } - } - - #declare BlueText = texture { - pigment { color rgb < 0.2, 0.2, 0.8> } - finish { ambient 0.2 diffuse 0.5 } - } - mesh { - smooth_triangle { - < 0.29, -0.29, 0.0>, < 0.0, 0.0, -1.0 >, - < 38.85, 10.03, 0.0>, < 0.0, 0.0, -1.0 >, - < 40.21, -0.29, 0.0>, < 0.0, 0.0, -1.0 > - texture { RedText } } - ... - smooth_triangle { - < 0.29, -0.29, 70.4142 >, < 0.0, 0.0, 1.0 >, - < 8.56, -2.51, 70.4142 >, < 0.0, 0.0, 1.0 >, - < 8.85, -0.29, 70.4142 >, < 0.0, 0.0, 1.0 > - texture { BlueText } } - } - - Modified: - - 08 October 1998 - - Author: - - John Burkardt -*/ -{ - int i; - int j; - int jj; - int jlo; - int k; - int text_num; - - text_num = 0; - fprintf ( fileout, "// %s created by IVCON.\n", fileout_name ); - fprintf ( fileout, "// Original data in %s.\n", filein_name ); - text_num = text_num + 2; -/* - Initial declarations. -*/ - fprintf ( fileout, "\n" ); - fprintf ( fileout, "#version 3.0\n" ); - fprintf ( fileout, "#include \"colors.inc\"\n" ); - fprintf ( fileout, "#include \"shapes.inc\"\n" ); - fprintf ( fileout, "global_settings { assumed_gamma 2.2 }\n" ); - fprintf ( fileout, "\n" ); - fprintf ( fileout, "camera {\n" ); - fprintf ( fileout, " right < 4/3, 0, 0>\n" ); - fprintf ( fileout, " up < 0, 1, 0 >\n" ); - fprintf ( fileout, " sky < 0, 1, 0 >\n" ); - fprintf ( fileout, " angle 20\n" ); - fprintf ( fileout, " location < 0, 0, -300 >\n" ); - fprintf ( fileout, " look_at < 0, 0, 0>\n" ); - fprintf ( fileout, "}\n" ); - fprintf ( fileout, "\n" ); - fprintf ( fileout, "light_source { < 20, 50, -100 > color White }\n" ); - fprintf ( fileout, "\n" ); - fprintf ( fileout, "background { color SkyBlue }\n" ); - - text_num = text_num + 15; -/* - Declare RGB textures. -*/ - fprintf ( fileout, "\n" ); - fprintf ( fileout, "#declare RedText = texture {\n" ); - fprintf ( fileout, " pigment { color rgb < 0.8, 0.2, 0.2> }\n" ); - fprintf ( fileout, " finish { ambient 0.2 diffuse 0.5 }\n" ); - fprintf ( fileout, "}\n" ); - fprintf ( fileout, "\n" ); - fprintf ( fileout, "#declare GreenText = texture {\n" ); - fprintf ( fileout, " pigment { color rgb < 0.2, 0.8, 0.2> }\n" ); - fprintf ( fileout, " finish { ambient 0.2 diffuse 0.5 }\n" ); - fprintf ( fileout, "}\n" ); - fprintf ( fileout, "\n" ); - fprintf ( fileout, "#declare BlueText = texture {\n" ); - fprintf ( fileout, " pigment { color rgb < 0.2, 0.2, 0.8> }\n" ); - fprintf ( fileout, " finish { ambient 0.2 diffuse 0.5 }\n" ); - fprintf ( fileout, "}\n" ); -/* - Write one big object. -*/ - fprintf ( fileout, "mesh {\n" ); - text_num = text_num + 1; -/* - Do the next face. -*/ - for ( i = 0; i < face_num; i++ ) { -/* - Break the face up into triangles, anchored at node 1. -*/ - for ( jlo = 0; jlo < face_order[i] - 2; jlo++ ) { - fprintf ( fileout, " smooth_triangle {\n" ); - text_num = text_num + 1; - - for ( j = jlo; j < jlo + 3; j++ ) { - - if ( j == jlo ) { - jj = 0; - } - else { - jj = j; - } - - k = face[jj][i]; - - fprintf ( fileout, "<%f, %f, %f>, <%f, %f, %f>", - cor3[0][k], cor3[1][k], cor3[2][k], - vertex_normal[0][jj][i], - vertex_normal[1][jj][i], - vertex_normal[2][jj][i] ); - - if ( j < jlo + 2 ) { - fprintf ( fileout, ",\n" ); - } - else { - fprintf ( fileout, "\n" ); - } - text_num = text_num + 1; - - } - - if (i%6 == 1 ) { - fprintf ( fileout, "texture { RedText } }\n" ); - } - else if ( i%2 == 0 ) { - fprintf ( fileout, "texture { BlueText } }\n" ); - } - else { - fprintf ( fileout, "texture { GreenText } }\n" ); - } - text_num = text_num + 1; - - } - - } - - fprintf ( fileout, "}\n" ); - text_num = text_num + 1; -/* - Report. -*/ - printf ( "\n" ); - printf ( "POV_WRITE - Wrote %d text lines.\n", text_num ); - - return SUCCESS; -} -/******************************************************************************/ - -int rcol_find ( float a[][COR3_MAX], int m, int n, float r[] ) - -/******************************************************************************/ - -/* - Purpose: - - RCOL_FIND finds if a vector occurs in a table. - - Comment: - - Explicitly forcing the second dimension to be COR3_MAX is a kludge. - I have to figure out how to do this as pointer references. - - Also, since the array is not sorted, this routine should not be carelessly - called repeatedly for really big values of N, because you'll waste a - lot of time. - - Modified: - - 27 April 1999 - - Author: - - John Burkardt -*/ -{ - int i; - int icol; - int j; - - icol = -1; - - for ( j = 0; j < n; j++ ) { - for ( i = 0; i < m; i++ ) { - if ( a[i][j] != r[i] ) { - break; - } - if ( i == m-1 ) { - return j; - } - } - } - - return icol; -} -/**********************************************************************/ - -float rgb_to_hue ( float r, float g, float b ) - -/**********************************************************************/ - -/* - Purpose: - - RGB_TO_HUE converts (R,G,B) colors to a hue value between 0 and 1. - - Discussion: - - The hue computed here should be the same as the H value computed - for HLS and HSV, except that it ranges from 0 to 1 instead of - 0 to 360. - - A monochromatic color ( white, black, or a shade of gray) does not - have a hue. This routine will return a special value of H = -1 - for such cases. - - Examples: - - Color R G B H - - red 1.0 0.0 0.0 0.00 - yellow 1.0 1.0 0.0 0.16 - green 0.0 1.0 0.0 0.33 - cyan 0.0 1.0 1.0 0.50 - blue 0.0 0.0 1.0 0.67 - magenta 1.0 0.0 1.0 0.83 - - black 0.0 0.0 0.0 -1.00 - gray 0.5 0.5 0.5 -1.00 - white 1.0 1.0 1.0 -1.00 - - Modified: - - 22 May 1999 - - Author: - - John Burkardt - - Parameters: - - Input, float R, G, B, the red, green and blue values of the color. - These values should be between 0 and 1. - - Output, float RGB_TO_HUE, the corresponding hue of the color, or -1.0 if - the color is monochromatic. -*/ -{ - float h; - float rgbmax; - float rgbmin; -/* - Make sure the colors are between 0 and 1. -*/ - if ( r < 0.0 ) { - r = 0.0; - } - else if ( r > 1.0 ) { - r = 1.0; - } - - if ( g < 0.0 ) { - g = 0.0; - } - else if ( g > 1.0 ) { - g = 1.0; - } - - if ( b < 0.0 ) { - b = 0.0; - } - else if ( b > 1.0 ) { - b = 1.0; - } -/* - Compute the minimum and maximum of R, G and B. -*/ - rgbmax = r; - if ( g > rgbmax ) { - rgbmax = g; - } - if ( b > rgbmax ) { - rgbmax = b; - } - - rgbmin = r; - if ( g < rgbmin ) { - rgbmin = g; - } - if ( b < rgbmin ) { - rgbmin = b; - } -/* - If RGBMAX = RGBMIN, { the color has no hue. -*/ - if ( rgbmax == rgbmin ) { - h = - 1.0; - } -/* - Otherwise, we need to determine the dominant color. -*/ - else { - - if ( r == rgbmax ) { - h = ( g - b ) / ( rgbmax - rgbmin ); - } - else if ( g == rgbmax ) { - h = 2.0 + ( b - r ) / ( rgbmax - rgbmin ); - } - else if ( b == rgbmax ) { - h = 4.0 + ( r - g ) / ( rgbmax - rgbmin ); - } - - h = h / 6.0; -/* - Make sure H lies between 0 and 1.0. -*/ - if ( h < 0.0 ) { - h = h + 1.0; - } - else if ( h > 1.0 ) { - h = h - 1.0; - } - - } - - return h; -} -/******************************************************************************/ - -short int short_int_read ( FILE *filein ) - -/******************************************************************************/ -/* - Purpose: - - SHORT_INT_READ reads a short int from a binary file. - - Modified: - - 14 October 1998 - - Author: - - John Burkardt -*/ -{ - unsigned char c1; - unsigned char c2; - short int ival; - - c1 = fgetc ( filein ); - c2 = fgetc ( filein ); - - ival = c1 | ( c2 << 8 ); - - return ival; -} -/******************************************************************************/ - -int short_int_write ( FILE *fileout, short int short_int_val ) - -/******************************************************************************/ - -/* - Purpose: - - SHORT_INT_WRITE writes a short int to a binary file. - - Modified: - - 14 October 1998 - - Author: - - John Burkardt -*/ -{ - union { - short int yint; - char ychar[2]; - } y; - - y.yint = short_int_val; - - if ( byte_swap == TRUE ) { - fputc ( y.ychar[1], fileout ); - fputc ( y.ychar[0], fileout ); - } - else { - fputc ( y.ychar[0], fileout ); - fputc ( y.ychar[1], fileout ); - } - - return 2; -} -/******************************************************************************/ - -int smf_read ( FILE *filein ) - -/******************************************************************************/ - -/* - Purpose: - - SMF_READ reads an SMF file. - - Example: - - #SMF2.0 - # cube_face.smf - # This example demonstrates how an RGB color can be assigned to - # each face of an object. - # - # First, define the geometry of the cube. - # - v 0.0 0.0 0.0 - v 1.0 0.0 0.0 - v 0.0 1.0 0.0 - v 1.0 1.0 0.0 - v 0.0 0.0 1.0 - v 1.0 0.0 1.0 - v 0.0 1.0 1.0 - v 1.0 1.0 1.0 - f 1 4 2 - f 1 3 4 - f 5 6 8 - f 5 8 7 - f 1 2 6 - f 1 6 5 - f 2 4 8 - f 2 8 6 - f 4 3 7 - f 4 7 8 - f 3 1 5 - f 3 5 7 - # - # Colors will be bound 1 per face. - # - bind c face - c 1.0 0.0 0.0 - c 1.0 0.0 0.0 - c 0.0 1.0 0.0 - c 0.0 1.0 0.0 - c 0.0 0.0 1.0 - c 0.0 0.0 1.0 - c 1.0 1.0 0.0 - c 1.0 1.0 0.0 - c 0.0 1.0 1.0 - c 0.0 1.0 1.0 - c 1.0 0.0 1.0 - c 1.0 0.0 1.0 - # - # Normal vectors will be bound 1 per face. - # - bind n face - n 0.0 0.0 -1.0 - n 0.0 0.0 -1.0 - n 0.0 0.0 1.0 - n 0.0 0.0 1.0 - n 0.0 -1.0 0.0 - n 0.0 -1.0 0.0 - n 1.0 0.0 0.0 - n 1.0 0.0 0.0 - n 0.0 1.0 0.0 - n 0.0 1.0 0.0 - n -1.0 0.0 0.0 - n -1.0 0.0 0.0 - # - # Texture coordinate pairs will be bound 1 per face. - # - bind r face - r 0.0 0.0 - r 0.0 0.1 - r 0.0 0.2 - r 0.0 0.3 - r 0.1 0.0 - r 0.1 0.1 - r 0.1 0.2 - r 0.1 0.3 - r 0.2 0.0 - r 0.2 0.1 - r 0.2 0.2 - r 0.2 0.3 - - Modified: - - 03 July 1999 - - Author: - - John Burkardt -*/ -{ - float angle; - char axis; - float b; - char cnr[LINE_MAX_LEN]; - int count; - float dx; - float dy; - int face_count; - float g; - int icor3_normal; - int icor3_tex_uv; - int iface_normal; - int iface_tex_uv; - int imat; - int ivert; - int level; - char *next; - int node; - int node_count; - float r; - float r1; - float r2; - float r3; - float rgba[4]; - char *string; - float sx; - float sy; - float sz; - char token[LINE_MAX_LEN]; - char token2[LINE_MAX_LEN]; - char type[LINE_MAX_LEN]; - float u; - float v; - int vertex_base; - int vertex_correction; - int width; - float x; - float xvec[3]; - float y; - float z; - - face_count = 0; - icor3_normal = 0; - icor3_tex_uv = 0; - iface_normal = 0; - iface_tex_uv = 0; - level = 0; - node_count = 0; - vertex_base = 0; - vertex_correction = 0; -/* - Read the next line of the file into INPUT. -*/ - while ( fgets ( input, LINE_MAX_LEN, filein ) != NULL ) { - - text_num = text_num + 1; - - if ( debug ) { - printf ( "SMF_READ: DEBUG: Reading line #%d\n", text_num ); - } -/* - Advance to the first nonspace character in INPUT. -*/ - for ( next = input; *next != '\0' && isspace(*next); next++ ) { - } -/* - Skip blank lines. -*/ - - if ( *next == '\0' ) { - continue; - } -/* - Skip comment lines. -*/ - if ( *next == '#' || *next == '$' ) { - comment_num = comment_num + 1; - continue; - } -/* - Extract the first word in this line. -*/ - sscanf ( next, "%s%n", token, &width ); -/* - Set NEXT to point to just after this token. -*/ - next = next + width; -/* - BEGIN - Reset the transformation matrix to identity. - Node numbering starts at zero again. (Really, this is level based) - (Really should define a new transformation matrix, and concatenate.) - (Also, might need to keep track of level.) -*/ - if ( leqi ( token, "BEGIN" ) == TRUE ) { - - level = level + 1; - - vertex_base = cor3_num; - group_num = group_num + 1; - tmat_init ( transform_matrix ); - - } -/* - BIND [c|n|r] [vertex|face] - Specify the binding for RGB color, Normal, or Texture. - Options are "vertex" or "face" -*/ - else if ( leqi ( token, "BIND" ) == TRUE ) { - - sscanf ( next, "%s%n", cnr, &width ); - next = next + width; - - if ( debug ) { - printf ( "CNR = %s\n", cnr ); - } - - sscanf ( next, "%s%n", type, &width ); - next = next + width; - - if ( debug ) { - printf ( "TYPE = %s\n", type ); - } - - if ( leqi ( cnr, "C" ) == TRUE ) { - - if ( leqi ( type, "VERTEX" ) == TRUE ) { - strcpy ( material_binding, "PER_VERTEX" ); - } - else if ( leqi ( type, "FACE" ) == TRUE ) { - strcpy ( material_binding, "PER_FACE" ); - } - - } - else if ( leqi ( cnr, "N" ) == TRUE ) { - - if ( leqi ( type, "VERTEX" ) == TRUE ) { - strcpy ( normal_binding, "PER_VERTEX" ); - } - else if ( leqi ( type, "FACE" ) == TRUE ) { - strcpy ( normal_binding, "PER_FACE" ); - } - - } - else if ( leqi ( cnr, "R" ) == TRUE ) { - - if ( leqi ( type, "VERTEX" ) == TRUE ) { - strcpy ( texture_binding, "PER_VERTEX" ); - } - else if ( leqi ( type, "FACE" ) == TRUE ) { - strcpy ( texture_binding, "PER_FACE" ); - } - - } - - } -/* - C - Specify an RGB color, with R, G, B between 0.0 and 1.0. -*/ - else if ( leqi ( token, "C" ) == TRUE ) { - - sscanf ( next, "%f%n", &r, &width ); - next = next + width; - - sscanf ( next, "%f%n", &g, &width ); - next = next + width; - - sscanf ( next, "%f%n", &b, &width ); - next = next + width; -/* - Set up a temporary material (R,G,B,1.0). - Add the material to the material database, or find the index of - a matching material already in. - Assign the material of the node or face to this index. -*/ - rgba[0] = r; - rgba[1] = g; - rgba[2] = b; - rgba[3] = 1.0; - - if ( material_num < MATERIAL_MAX ) { - - for ( k = 0; k < 4; k++ ) { - material_rgba[k][material_num] = rgba[k]; - } - - imat = material_num; - material_num = material_num + 1; - - } - else { - - imat = 0; - - } - - if ( leqi ( material_binding, "PER_FACE" ) == TRUE ) { - - face_count = face_count + 1; - face_material[face_count] = imat; - - } - else if ( leqi ( material_binding, "PER_VERTEX" ) == TRUE ) { - - node_count = node_count + 1; - cor3_material[node_count] = imat; - - } - else { - - printf ( "\n" ); - printf ( "SMF_READ - Fatal error!\n" ); - printf ( " Material binding undefined!\n" ); - return ERROR; - - } - - } -/* - END - Drop down a level. -*/ - else if ( leqi ( token, "END" ) == TRUE ) { - - level = level - 1; - - if ( level < 0 ) { - printf ( "\n" ); - printf ( "SMF_READ - Fatal error!\n" ); - printf ( " More END statements than BEGINs!\n" ); - return ERROR; - } - } -/* - F V1 V2 V3 - - Face. - A face is defined by the vertices. - Node indices are 1 based rather than 0 based. - So we have to decrement them before loading them into FACE. - Note that vertex indices start back at 0 each time a BEGIN is entered. - The strategy here won't handle nested BEGIN's, just one at a time. -*/ - - else if ( leqi ( token, "F" ) == TRUE ) { - - ivert = 0; - face_order[face_num] = 0; -/* - Read each item in the F definition as a token, and then - take it apart. -*/ - for ( ;; ) { - - count = sscanf ( next, "%s%n", token2, &width ); - next = next + width; - - if ( count != 1 ) { - break; - } - - count = sscanf ( token2, "%d%n", &node, &width ); - - if ( count != 1 ) { - break; - } - - if ( ivert < ORDER_MAX && face_num < FACE_MAX ) { - face[ivert][face_num] = node - 1 + vertex_base; - vertex_material[ivert][face_num] = 0; - face_order[face_num] = face_order[face_num] + 1; - } - ivert = ivert + 1; - } - face_num = face_num + 1; - } -/* - N - Specify a normal vector. -*/ - else if ( leqi ( token, "N" ) == TRUE ) { - - sscanf ( next, "%f%n", &x, &width ); - next = next + width; - - sscanf ( next, "%f%n", &y, &width ); - next = next + width; - - sscanf ( next, "%f%n", &z, &width ); - next = next + width; - - if ( leqi ( normal_binding, "PER_FACE" ) == TRUE ) { - - face_normal[0][iface_normal] = x; - face_normal[1][iface_normal] = y; - face_normal[2][iface_normal] = z; - - iface_normal = iface_normal + 1; - - } - else if ( leqi ( normal_binding, "PER_VERTEX" ) == TRUE ) { - - cor3_normal[0][icor3_normal] = x; - cor3_normal[1][icor3_normal] = y; - cor3_normal[2][icor3_normal] = z; - - icor3_normal = icor3_normal + 1; - - } - else { - - printf ( "\n" ); - printf ( "SMF_READ - Fatal error!\n" ); - printf ( " Normal binding undefined!\n" ); - return ERROR; - - } - } -/* - R - Specify a texture coordinate. -*/ - else if ( leqi ( token, "R" ) == TRUE ) { - - sscanf ( next, "%f%n", &u, &width ); - next = next + width; - - sscanf ( next, "%f%n", &v, &width ); - next = next + width; - - if ( leqi ( texture_binding, "PER_FACE" ) == TRUE ) { - - face_tex_uv[0][iface_tex_uv] = u; - face_tex_uv[1][iface_tex_uv] = v; - - icor3_tex_uv = icor3_tex_uv + 1; - - } - else if ( leqi ( texture_binding, "PER_VERTEX" ) == TRUE ) { - - cor3_tex_uv[0][icor3_tex_uv] = u; - cor3_tex_uv[1][icor3_tex_uv] = v; - - icor3_tex_uv = icor3_tex_uv + 1; - } - else { - printf ( "\n" ); - printf ( "SMF_READ - Fatal error!\n" ); - printf ( " Texture binding undefined!\n" ); - return ERROR; - } - - } -/* - ROT [x|y|z] -*/ - else if ( leqi ( token, "ROT" ) == TRUE ) { - - sscanf ( next, "%c%n", &axis, &width ); - next = next + width; - - sscanf ( next, "%f%n", &angle, &width ); - next = next + width; - - tmat_rot_axis ( transform_matrix, transform_matrix, angle, axis ); - - } -/* - SCALE -*/ - else if ( leqi ( token, "SCALE" ) == TRUE ) { - - sscanf ( next, "%f%n", &sx, &width ); - next = next + width; - - sscanf ( next, "%f%n", &sy, &width ); - next = next + width; - - sscanf ( next, "%f%n", &sz, &width ); - next = next + width; - - tmat_scale ( transform_matrix, transform_matrix, sx, sy, sz ); - } -/* - SET VERTEX_CORRECTION - Specify increment to add to vertex indices in file. -*/ - else if ( leqi ( token, "SET" ) == TRUE ) { - - sscanf ( next, "%s%n", cnr, &width ); - next = next + width; - - sscanf ( next, "%d%n", &vertex_correction, &width ); - next = next + width; - - } -/* - T_SCALE - Specify a scaling to texture coordinates. -*/ - else if ( leqi ( token, "T_SCALE" ) == TRUE ) { - - sscanf ( next, "%f%n", &dx, &width ); - next = next + width; - - sscanf ( next, "%f%n", &dy, &width ); - next = next + width; - - } -/* - T_TRANS - Specify a translation to texture coordinates. -*/ - else if ( leqi ( token, "T_TRANS" ) == TRUE ) { - - sscanf ( next, "%f%n", &dx, &width ); - next = next + width; - - sscanf ( next, "%f%n", &dy, &width ); - next = next + width; - - } -/* - TEX - Specify a filename containing the texture. - (ANY CHANCE THIS IS RIGHT?) -*/ - else if ( leqi ( token, "TEX" ) == TRUE ) { - - sscanf ( next, "%s%n", string, &width ); - - for ( i = 0; i < LINE_MAX_LEN; i++ ) { - texture_name[texture_num][i] = string[i]; - if ( string[i] == '\0' ) { - break; - } - } - - texture_num = texture_num + 1; - - } -/* - TRANS -*/ - else if ( leqi ( token, "TRANS" ) == TRUE ) { - - sscanf ( next, "%f%n", &x, &width ); - next = next + width; - - sscanf ( next, "%f%n", &y, &width ); - next = next + width; - - sscanf ( next, "%f%n", &z, &width ); - next = next + width; - - tmat_trans ( transform_matrix, transform_matrix, x, y, z ); - } -/* - V X Y Z - Geometric vertex. -*/ - else if ( leqi ( token, "V" ) == TRUE ) { - - sscanf ( next, "%e %e %e", &r1, &r2, &r3 ); - - xvec[0] = r1; - xvec[1] = r2; - xvec[2] = r3; -/* - Apply current transformation matrix. - Right now, we can only handle one matrix, not a stack of - matrices representing nested BEGIN/END's. -*/ - tmat_mxp ( transform_matrix, xvec, xvec ); - - if ( cor3_num < COR3_MAX ) { - for ( i = 0; i < 3; i++ ) { - cor3[i][cor3_num] = xvec[i]; - } - } - - cor3_num = cor3_num + 1; - - } -/* - Unrecognized keyword. -*/ - else { - - bad_num = bad_num + 1; - - if ( bad_num <= 10 ) { - printf ( "\n" ); - printf ( "SMF_READ: Bad data on line %d.\n", text_num ); - } - } - - } -/* - Extend the material definition - * from the face to the vertices and nodes, or - * from the vertices to the faces and nodes. -*/ - if ( strcmp ( material_binding, "PER_FACE" ) == 0 ) { - - face_to_vertex_material ( ); - - vertex_to_node_material ( ); - - } - else if ( strcmp ( material_binding, "PER_VERTEX" ) == 0 ) { - - node_to_vertex_material ( ); - - vertex_to_face_material ( ); - - } - - return SUCCESS; -} -/******************************************************************************/ - -int smf_write ( FILE *fileout ) - -/******************************************************************************/ - -/* - Purpose: - - SMF_WRITE writes graphics information to an SMF file. - - Example: - - #SMF2.0 - # cube_face.smf - # This example demonstrates how an RGB color can be assigned to - # each face of an object. - # - # First, define the geometry of the cube. - # - v 0.0 0.0 0.0 - v 1.0 0.0 0.0 - v 0.0 1.0 0.0 - v 1.0 1.0 0.0 - v 0.0 0.0 1.0 - v 1.0 0.0 1.0 - v 0.0 1.0 1.0 - v 1.0 1.0 1.0 - f 1 4 2 - f 1 3 4 - f 5 6 8 - f 5 8 7 - f 1 2 6 - f 1 6 5 - f 2 4 8 - f 2 8 6 - f 4 3 7 - f 4 7 8 - f 3 1 5 - f 3 5 7 - # - # Colors will be bound 1 per face. - # - bind c face - c 1.0 0.0 0.0 - c 1.0 0.0 0.0 - c 0.0 1.0 0.0 - c 0.0 1.0 0.0 - c 0.0 0.0 1.0 - c 0.0 0.0 1.0 - c 1.0 1.0 0.0 - c 1.0 1.0 0.0 - c 0.0 1.0 1.0 - c 0.0 1.0 1.0 - c 1.0 0.0 1.0 - c 1.0 0.0 1.0 - # - # Normal vectors will be bound 1 per face. - # - bind n face - n 0.0 0.0 -1.0 - n 0.0 0.0 -1.0 - n 0.0 0.0 1.0 - n 0.0 0.0 1.0 - n 0.0 -1.0 0.0 - n 0.0 -1.0 0.0 - n 1.0 0.0 0.0 - n 1.0 0.0 0.0 - n 0.0 1.0 0.0 - n 0.0 1.0 0.0 - n -1.0 0.0 0.0 - n -1.0 0.0 0.0 - # - # Texture coordinate pairs will be bound 1 per face. - # - bind r face - r 0.0 0.0 - r 0.0 0.1 - r 0.0 0.2 - r 0.0 0.3 - r 0.1 0.0 - r 0.1 0.1 - r 0.1 0.2 - r 0.1 0.3 - r 0.2 0.0 - r 0.2 0.1 - r 0.2 0.2 - r 0.2 0.3 - - Modified: - - 05 July 1999 - - Author: - - John Burkardt -*/ -{ - int i; - int icor3; - int iface; - int imat; - int ivert; - int text_num; -/* - Initialize. -*/ - text_num = 0; - - fprintf ( fileout, "#$SMF 2.0\n" ); - fprintf ( fileout, "#$vertices %d\n", cor3_num ); - fprintf ( fileout, "#$faces %d\n", face_num ); - fprintf ( fileout, "#\n" ); - fprintf ( fileout, "# %s created by IVCON.\n", fileout_name ); - fprintf ( fileout, "# Original data in %s.\n", filein_name ); - fprintf ( fileout, "#\n" ); - - text_num = text_num + 7; -/* - V: vertex coordinates. -*/ - for ( i = 0; i < cor3_num; i++ ) { - fprintf ( fileout, "v %f %f %f\n", - cor3[0][i], cor3[1][i], cor3[2][i] ); - text_num = text_num + 1; - } -/* - F: faces. -*/ - if ( face_num > 0 ) { - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - } - - for ( iface = 0; iface < face_num; iface++ ) { - - fprintf ( fileout, "f" ); - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - fprintf ( fileout, " %d", face[ivert][iface]+1 ); - } - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - } -/* - Material binding. -*/ - fprintf ( fileout, "bind c vertex\n" ); - text_num = text_num + 1; -/* - Material RGB values at each node. -*/ - for ( icor3 = 0; icor3 < cor3_num; icor3++ ) { - - imat = cor3_material[icor3]; - - fprintf ( fileout, "c %f %f %f\n", material_rgba[0][imat], - material_rgba[1][imat], material_rgba[2][imat] ); - - text_num = text_num + 1; - } -/* - Normal binding. -*/ - fprintf ( fileout, "bind n vertex\n" ); - text_num = text_num + 1; -/* - Normal vector at each node. -*/ - for ( icor3 = 0; icor3 < cor3_num; icor3++ ) { - - fprintf ( fileout, "n %f %f %f\n", cor3_normal[0][icor3], - cor3_normal[1][icor3], cor3_normal[2][icor3] ); - - text_num = text_num + 1; - } - - if ( texture_num > 0 ) { -/* - Texture filename. -*/ - fprintf ( fileout, "tex %s\n", texture_name[0] ); - text_num = text_num + 1; -/* - Texture binding. -*/ - fprintf ( fileout, "bind r vertex\n" ); - text_num = text_num + 1; -/* - Texture coordinates at each node. -*/ - for ( icor3 = 0; icor3 < cor3_num; icor3++ ) { - fprintf ( fileout, "r %f %f\n", cor3_tex_uv[0][icor3], - cor3_tex_uv[1][icor3] ); - text_num = text_num + 1; - } - - } -/* - Report. -*/ - printf ( "\n" ); - printf ( "SMF_WRITE - Wrote %d text lines.\n", text_num ); - - return SUCCESS; -} -/******************************************************************************/ - -int stla_read ( FILE *filein ) - -/******************************************************************************/ - -/* - Purpose: - - STLA_READ reads an ASCII STL (stereolithography) file. - - Examples: - - solid MYSOLID - facet normal 0.4 0.4 0.2 - outerloop - vertex 1.0 2.1 3.2 - vertex 2.1 3.7 4.5 - vertex 3.1 4.5 6.7 - endloop - endfacet - ... - facet normal 0.2 0.2 0.4 - outerloop - vertex 2.0 2.3 3.4 - vertex 3.1 3.2 6.5 - vertex 4.1 5.5 9.0 - endloop - endfacet - endsolid MYSOLID - - Modified: - - 20 October 1998 - - Author: - - John Burkardt -*/ -{ - int count; - int i; - int icor3; - int ivert; - char *next; - float r1; - float r2; - float r3; - float r4; - float temp[3]; - char token[LINE_MAX_LEN]; - int width; -/* - Read the next line of the file into INPUT. -*/ - while ( fgets ( input, LINE_MAX_LEN, filein ) != NULL ) { - - text_num = text_num + 1; -/* - Advance to the first nonspace character in INPUT. -*/ - for ( next = input; *next != '\0' && isspace(*next); next++ ) { - } -/* - Skip blank lines and comments. -*/ - if ( *next == '\0' || *next == '#' || *next == '!' || *next == '$' ) { - continue; - } -/* - Extract the first word in this line. -*/ - sscanf ( next, "%s%n", token, &width ); -/* - Set NEXT to point to just after this token. -*/ - next = next + width; -/* - FACET -*/ - if ( leqi ( token, "facet" ) == TRUE ) { -/* - Get the XYZ coordinates of the normal vector to the face. -*/ - sscanf ( next, "%*s %e %e %e", &r1, &r2, &r3 ); - - if ( face_num < FACE_MAX ) { - face_normal[0][face_num] = r1; - face_normal[1][face_num] = r2; - face_normal[2][face_num] = r3; - } - - fgets ( input, LINE_MAX_LEN, filein ); - text_num = text_num + 1; - - ivert = 0; - - for ( ;; ) { - - fgets ( input, LINE_MAX_LEN, filein ); - text_num = text_num + 1; - - count = sscanf ( input, "%*s %e %e %e", &r1, &r2, &r3 ); - - if ( count != 3 ) { - break; - } - - temp[0] = r1; - temp[1] = r2; - temp[2] = r3; - - if ( cor3_num < 1000 ) { - icor3 = rcol_find ( cor3, 3, cor3_num, temp ); - } - else { - icor3 = -1; - } - - if ( icor3 == -1 ) { - - icor3 = cor3_num; - - if ( cor3_num < COR3_MAX ) { - for ( i = 0; i < 3; i++ ) { - cor3[i][cor3_num] = temp[i]; - } - } - cor3_num = cor3_num + 1; - } - else { - dup_num = dup_num + 1; - } - - if ( ivert < ORDER_MAX && face_num < FACE_MAX ) { - face[ivert][face_num] = icor3; - vertex_material[ivert][face_num] = 0; - for ( i = 0; i < 3; i++ ) { - vertex_normal[i][ivert][face_num] = face_normal[i][face_num]; - } - } - - ivert = ivert + 1; - } - - fgets ( input, LINE_MAX_LEN, filein ); - text_num = text_num + 1; - - if ( face_num < FACE_MAX ) { - face_order[face_num] = ivert; - } - - face_num = face_num + 1; - - } -/* - COLOR -*/ - - else if ( leqi ( token, "color" ) == TRUE ) { - sscanf ( next, "%*s %f %f %f %f", &r1, &r2, &r3, &r4 ); - } -/* - SOLID -*/ - else if ( leqi ( token, "solid" ) == TRUE ) { - object_num = object_num + 1; - } -/* - ENDSOLID -*/ - else if ( leqi ( token, "endsolid" ) == TRUE ) { - } -/* - Unexpected or unrecognized. -*/ - else { - printf ( "\n" ); - printf ( "STLA_READ - Fatal error!\n" ); - printf ( " Unrecognized first word on line.\n" ); - return ERROR; - } - - } - return SUCCESS; -} -/******************************************************************************/ - -int stla_write ( FILE *fileout ) - -/******************************************************************************/ - -/* - Purpose: - - STLA_WRITE writes an ASCII STL (stereolithography) file. - - Examples: - - solid MYSOLID - facet normal 0.4 0.4 0.2 - outerloop - vertex 1.0 2.1 3.2 - vertex 2.1 3.7 4.5 - vertex 3.1 4.5 6.7 - endloop - endfacet - ... - facet normal 0.2 0.2 0.4 - outerloop - vertex 2.0 2.3 3.4 - vertex 3.1 3.2 6.5 - vertex 4.1 5.5 9.0 - endloop - endfacet - endsolid - - Discussion: - - The polygons in an STL file should only be triangular. This routine - will try to automatically decompose higher-order polygonal faces into - suitable triangles, without actually modifying the internal graphics - data. - - Modified: - - 01 September 1998 - - Author: - - John Burkardt -*/ -{ - int icor3; - int iface; - int jvert; - int face_num2; - int text_num; -/* - Initialize. -*/ - text_num = 0; - face_num2 = 0; - - fprintf ( fileout, "solid MYSOLID created by IVCON, original data in %s\n", - filein_name ); - - text_num = text_num + 1; - - for ( iface = 0; iface < face_num; iface++ ) { - - for ( jvert = 2; jvert < face_order[iface]; jvert++ ) { - - face_num2 = face_num2 + 1; - - fprintf ( fileout, " facet normal %f %f %f\n", - face_normal[0][iface], face_normal[1][iface], face_normal[2][iface] ); - - fprintf ( fileout, " outer loop\n" ); - - icor3 = face[0][iface]; - fprintf ( fileout, " vertex %f %f %f\n", - cor3[0][icor3], cor3[1][icor3], cor3[2][icor3] ); - - icor3 = face[jvert-1][iface]; - fprintf ( fileout, " vertex %f %f %f\n", - cor3[0][icor3], cor3[1][icor3], cor3[2][icor3] ); - - icor3 = face[jvert][iface]; - fprintf ( fileout, " vertex %f %f %f\n", - cor3[0][icor3], cor3[1][icor3], cor3[2][icor3] ); - - fprintf ( fileout, " endloop\n" ); - fprintf ( fileout, " endfacet\n" ); - text_num = text_num + 7; - } - } - - fprintf ( fileout, "endsolid MYSOLID\n" ); - text_num = text_num + 1; -/* - Report. -*/ - printf ( "\n" ); - printf ( "STLA_WRITE - Wrote %d text lines.\n", text_num ); - - if ( face_num != face_num2 ) { - printf ( " Number of faces in original data was %d.\n", face_num ); - printf ( " Number of triangular faces in decomposed data is %d.\n", - face_num2 ); - } - - return SUCCESS; -} -/******************************************************************************/ - -int stlb_read ( FILE *filein ) - -/******************************************************************************/ - -/* - Purpose: - - STLB_READ reads a binary STL (stereolithography) file. - - Example: - - 80 byte string = header containing nothing in particular - - 4 byte int = number of faces - - For each face: - - 3 4-byte floats = components of normal vector to face; - 3 4-byte floats = coordinates of first node; - 3 4-byte floats = coordinates of second node; - 3 4-byte floats = coordinates of third and final node; - 2-byte int = attribute, whose value is 0. - - Modified: - - 24 May 1999 - - Author: - - John Burkardt -*/ -{ - short int attribute = 0; - char c; - float cvec[3]; - int icor3; - int i; - int iface; - int ivert; -/* - 80 byte Header. -*/ - for ( i = 0; i < 80; i++ ) { - c = char_read ( filein ); - if ( debug ) { - printf ( "%d\n", c ); - } - bytes_num = bytes_num + 1; - } -/* - Number of faces. -*/ - face_num = long_int_read ( filein ); - bytes_num = bytes_num + 4; -/* - For each (triangular) face, - components of normal vector, - coordinates of three vertices, - 2 byte "attribute". -*/ - for ( iface = 0; iface < face_num; iface++ ) { - - face_order[iface] = 3; - face_material[iface] = 0; - - for ( i = 0; i < 3; i++ ) { - face_normal[i][iface] = float_read ( filein ); - bytes_num = bytes_num + 4; - } - - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - - for ( i = 0; i < 3; i++ ) { - cvec[i] = float_read ( filein ); - bytes_num = bytes_num + 4; - } - - if ( cor3_num < 1000 ) { - icor3 = rcol_find ( cor3, 3, cor3_num, cvec ); - } - else { - icor3 = -1; - } - - if ( icor3 == -1 ) { - icor3 = cor3_num; - if ( cor3_num < COR3_MAX ) { - cor3[0][cor3_num] = cvec[0]; - cor3[1][cor3_num] = cvec[1]; - cor3[2][cor3_num] = cvec[2]; - } - cor3_num = cor3_num + 1; - } - else { - dup_num = dup_num + 1; - } - - face[ivert][iface] = icor3; - - } - attribute = short_int_read ( filein ); - if ( debug ) { - printf ( "ATTRIBUTE = %d\n", attribute ); - } - bytes_num = bytes_num + 2; - } - - return SUCCESS; -} -/******************************************************************************/ - -int stlb_write ( FILE *fileout ) - -/******************************************************************************/ - -/* - Purpose: - - STLB_WRITE writes a binary STL (stereolithography) file. - - Example: - - 80 byte string = header containing nothing in particular - - 4 byte int = number of faces - - For each face: - - 3 4-byte floats = components of normal vector to face; - 3 4-byte floats = coordinates of first node; - 3 4-byte floats = coordinates of second node; - 3 4-byte floats = coordinates of third and final node; - 2-byte int = attribute, whose value is 0. - - Discussion: - - The polygons in an STL file should only be triangular. This routine - will try to automatically decompose higher-order polygonal faces into - suitable triangles, without actually modifying the internal graphics - data. - - Modified: - - 24 May 1999 - - Author: - - John Burkardt -*/ -{ - short int attribute = 0; - char c; - int i; - int icor3; - int iface; - int jvert; - int face_num2; -/* - 80 byte Header. -*/ - for ( i = 0; i < 80; i++ ) { - c = ' '; - bytes_num = bytes_num + char_write ( fileout, c ); - } -/* - Number of faces. -*/ - face_num2 = 0; - for ( iface = 0; iface < face_num; iface++ ) { - face_num2 = face_num2 + face_order[iface] - 2; - } - - bytes_num = bytes_num + long_int_write ( fileout, face_num2 ); -/* - For each (triangular) face, - components of normal vector, - coordinates of three vertices, - 2 byte "attribute". -*/ - for ( iface = 0; iface < face_num; iface++ ) { - - for ( jvert = 2; jvert < face_order[iface]; jvert++ ) { - - for ( i = 0; i < 3; i++ ) { - bytes_num = bytes_num + float_write ( fileout, face_normal[i][iface] ); - } - - icor3 = face[0][iface]; - for ( i = 0; i < 3; i++ ) { - bytes_num = bytes_num + float_write ( fileout, cor3[i][icor3] ); - } - - icor3 = face[jvert-1][iface]; - for ( i = 0; i < 3; i++ ) { - bytes_num = bytes_num + float_write ( fileout, cor3[i][icor3] ); - } - - icor3 = face[jvert][iface]; - for ( i = 0; i < 3; i++ ) { - bytes_num = bytes_num + float_write ( fileout, cor3[i][icor3] ); - } - - bytes_num = bytes_num + short_int_write ( fileout, attribute ); - - } - - } -/* - Report. -*/ - printf ( "\n" ); - printf ( "STLB_WRITE - Wrote %d bytes.\n", bytes_num ); - - if ( face_num != face_num2 ) { - printf ( " Number of faces in original data was %d.\n", face_num ); - printf ( " Number of triangular faces in decomposed data is %d.\n", - face_num2 ); - } - - return SUCCESS; -} -/******************************************************************************/ - -void tds_pre_process ( void ) - -/******************************************************************************/ - -/* - Purpose: - - TDS_PRE_PROCESS divides the monolithic object into acceptably small pieces. - - Note: - - The 3DS binary format allows an unsigned short int for the number of - points, and number of faces in an object. This limits such quantities - to 65535. We have at least one interesting object with more faces - than that. So we need to tag faces and nodes somehow. - - Modified: - - 14 October 1998 - - Author: - - John Burkardt -*/ -{ -/* static unsigned short int BIG = 60000; */ - - return; -} -/******************************************************************************/ - -int tds_read ( FILE *filein ) - -/******************************************************************************/ - -/* - Purpose: - - TDS_READ reads a 3D Studio MAX binary 3DS file. - - Modified: - - 20 October 1998 - - Author: - - John Burkardt -*/ -{ - unsigned long int chunk_begin; - unsigned long int chunk_end; - unsigned long int chunk_length; - unsigned long int chunk_length2; - unsigned long int position; - unsigned short int temp_int; - int version; - int views_read; -/* - Initialize. -*/ - views_read = 0; - - temp_int = tds_read_u_short_int ( filein ); - - if ( temp_int == 0x4d4d ) { - - if ( debug ) { - printf ( "TDS_READ: DEBUG: Read magic number %0X.\n", temp_int ); - } -/* - Move to 28 bytes from the beginning of the file. -*/ - position = 28; - fseek ( filein, ( long ) position, SEEK_SET ); - version = fgetc ( filein ); - - if ( version < 3 ) { - printf ( "\n" ); - printf ( "TDS_READ - Fatal error!\n" ); - printf ( " This routine can only read 3DS version 3 or later.\n" ); - printf ( " The input file is version %d.\n" ,version ); - return ERROR; - } - - if ( debug ) { - printf ( "TDS_READ: DEBUG: Version number is %d.\n", version ); - } -/* - Move to 2 bytes from the beginning of the file. - Set CURRENT_POINTER to the first byte of the chunk. - Set CHUNK_LENGTH to the number of bytes in the chunk. -*/ - chunk_begin = 0; - position = 2; - fseek ( filein, ( long ) position, SEEK_SET ); - - chunk_length = tds_read_u_long_int ( filein ); - position = 6; - - chunk_end = chunk_begin + chunk_length; - - if ( debug ) { - printf ( "TDS_READ:\n" ); - printf ( " Chunk begin = %lu.\n", chunk_begin ); - printf ( " Chunk length = %lu.\n", chunk_length ); - printf ( " Chunk end = %lu.\n", chunk_end ); - } - - while ( position + 2 < chunk_end ) { - - temp_int = tds_read_u_short_int ( filein ); - position = position + 2; - - if ( debug ) { - printf ( "TDS_READ: Short int = %0X, position = %lu.\n", temp_int, position ); - } - - if ( temp_int == 0x0002 ) { - if ( debug ) { - printf ( "TDS_READ: Read_Initial_Section:\n" ); - } - chunk_length2 = tds_read_u_long_int ( filein ); - position = position + 4; - position = position - 6 + chunk_length2; - fseek ( filein, ( long ) position, SEEK_SET ); - } - else if ( temp_int == 0x3d3d ) { - if ( debug ) { - printf ( "TDS_READ: Read_Edit_Section:\n" ); - } - position = position - 2; - position = position + tds_read_edit_section ( filein, &views_read ); - } - else if ( temp_int == 0xb000 ) { - if ( debug ) { - printf ( "TDS_READ: Read_Keyframe_Section:\n" ); - } - - position = position - 2; - position = position + tds_read_keyframe_section ( filein, &views_read ); - } - else { - printf ( "\n" ); - printf ( "TDS_READ - Fatal error!\n" ); - printf ( " Unexpected input, position = %lu.\n", position ); - printf ( " TEMP_INT = %hux\n", temp_int ); - return ERROR; - } - } - position = chunk_begin + chunk_length; - fseek ( filein, ( long ) position, SEEK_SET ); - } - else { - printf ( "\n" ); - printf ( "TDS_READ - Fatal error!\n" ); - printf ( " Could not find the main section tag.\n" ); - return ERROR; - } - - return SUCCESS; -} -/******************************************************************************/ - -unsigned long tds_read_ambient_section ( FILE *filein ) - -/******************************************************************************/ - -{ - unsigned long int current_pointer; - unsigned char end_found = FALSE; - int i; - long int pointer; - float rgb_val[3]; - unsigned short int temp_int; - unsigned long int temp_pointer; - unsigned long int teller; - unsigned char true_c_val[3]; - - current_pointer = ftell ( filein ) - 2; - temp_pointer = tds_read_u_long_int ( filein ); - teller = 6; - - while ( end_found == FALSE ) { - - temp_int = tds_read_u_short_int ( filein ); - teller = teller + 2; - - switch ( temp_int ) { - case 0x0010: - if ( debug ) { - printf ( " COLOR_F color definition section tag of %0X\n", - temp_int ); - } - for ( i = 0; i < 3; i++ ) { - rgb_val[i] = float_read ( filein ); - } - if ( debug ) { - printf ( "RGB_VAL = %f %f %f\n", rgb_val[0], rgb_val[1], rgb_val[2] ); - } - teller = teller + 3 * sizeof ( float ); - break; - case 0x0011: - if ( debug ) { - printf ( " COLOR_24 24 bit color definition section tag of %0X\n", - temp_int ); - } - - for ( i = 0; i < 3; i++ ) { - true_c_val[i] = fgetc ( filein ); - } - if ( debug ) { - printf ( "TRUE_C_VAL = %d %d %d\n", true_c_val[0], true_c_val[1], - true_c_val[2] ); - } - teller = teller + 3; - break; - default: - break; - } - - if ( teller >= temp_pointer ) { - end_found = TRUE; - } - - } - - pointer = ( long ) ( current_pointer + temp_pointer ); - fseek ( filein, pointer, SEEK_SET ); - - return ( temp_pointer ); -} -/******************************************************************************/ - -unsigned long tds_read_background_section ( FILE *filein ) - -/******************************************************************************/ - -{ - unsigned long int current_pointer; - unsigned char end_found = FALSE; - int i; - long int pointer; - float rgb_val[3]; - unsigned short int temp_int; - unsigned long int temp_pointer; - unsigned long int teller; - unsigned char true_c_val[3]; - - current_pointer = ftell ( filein ) - 2; - temp_pointer = tds_read_u_long_int ( filein ); - teller = 6; - - while ( end_found == FALSE ) { - - temp_int = tds_read_u_short_int ( filein ); - teller = teller + 2; - - switch ( temp_int ) { - case 0x0010: - if ( debug ) { - printf ( " COLOR_F RGB color definition section tag of %0X\n", - temp_int ); - } - for ( i = 0; i < 3; i++ ) { - rgb_val[i] = float_read ( filein ); - } - if ( debug ) { - printf ( "RGB_VAL = %f %f %f\n", rgb_val[0], rgb_val[1], rgb_val[2] ); - } - teller = teller + 3 * sizeof ( float ); - break; - case 0x0011: - if ( debug ) { - printf ( " COLOR_24 24 bit color definition section tag of %0X\n", - temp_int ); - } - - for ( i = 0; i < 3; i++ ) { - true_c_val[i] = fgetc ( filein ); - } - if ( debug ) { - printf ( "TRUE_C_VAL = %d %d %d\n", true_c_val[0], true_c_val[1], - true_c_val[2] ); - } - teller = teller + 3; - break; - default: - break; - } - - if ( teller >= temp_pointer ) { - end_found = TRUE; - } - - } - - pointer = ( long ) ( current_pointer + temp_pointer ); - fseek ( filein, pointer, SEEK_SET ); - - return ( temp_pointer ); -} -/******************************************************************************/ - -unsigned long tds_read_boolean ( unsigned char *boolean, FILE *filein ) - -/******************************************************************************/ - -{ - unsigned long current_pointer; - long int pointer; - unsigned long temp_pointer; - - current_pointer = ftell ( filein ) - 2; - temp_pointer = tds_read_u_long_int ( filein ); - - *boolean = fgetc ( filein ); - - pointer = ( long ) ( current_pointer + temp_pointer ); - fseek ( filein, pointer, SEEK_SET ); - - return ( temp_pointer ); -} -/******************************************************************************/ - -unsigned long tds_read_camera_section ( FILE *filein ) - -/******************************************************************************/ -{ - float camera_eye[3]; - float camera_focus[3]; - unsigned long int current_pointer; - float lens; - long int pointer; - float rotation; - unsigned long int temp_pointer; - unsigned short int u_short_int_val; - - current_pointer = ftell ( filein ) - 2; - temp_pointer = tds_read_u_long_int ( filein ); - - camera_eye[0] = float_read ( filein ); - camera_eye[1] = float_read ( filein ); - camera_eye[2] = float_read ( filein ); - - camera_focus[0] = float_read ( filein ); - camera_focus[1] = float_read ( filein ); - camera_focus[2] = float_read ( filein ); - - rotation = float_read ( filein ); - lens = float_read ( filein ); - - if ( debug ) { - printf ( " Found camera viewpoint at XYZ = %f %f %f.\n", - camera_eye[0], camera_eye[1], camera_eye[2] ); - printf ( " Found camera focus coordinates at XYZ = %f %f %f.\n", - camera_focus[0], camera_focus[1], camera_focus[2] ); - printf ( " Rotation of camera is: %f.\n", rotation ); - printf ( " Lens in used camera is: %f mm.\n", lens ); - } - - if ( ( temp_pointer-38 ) > 0 ) { - - if ( debug ) { - printf ( " Found extra camera sections.\n" ); - } - - u_short_int_val = tds_read_u_short_int ( filein ); - - if ( u_short_int_val == 0x4710 ) { - if ( debug ) { - printf ( " CAM_SEE_CONE.\n" ); - } - tds_read_unknown_section ( filein ); - } - - u_short_int_val = tds_read_u_short_int ( filein ); - - if ( u_short_int_val == 0x4720 ) { - if ( debug ) { - printf ( " CAM_RANGES.\n" ); - } - tds_read_unknown_section ( filein ); - } - - } - - pointer = ( long ) ( current_pointer + temp_pointer ); - fseek ( filein, pointer, SEEK_SET ); - - return ( temp_pointer ); -} -/******************************************************************************/ - -unsigned long tds_read_edit_section ( FILE *filein, int *views_read ) - -/******************************************************************************/ - -/* - Modified: - - 18 September 1998 -*/ -{ - unsigned long int chunk_length; - unsigned long int current_pointer; - unsigned char end_found = FALSE; - long int pointer; - unsigned long int teller; - unsigned short int temp_int; - - current_pointer = ftell ( filein ) - 2; - chunk_length = tds_read_u_long_int ( filein ); - teller = 6; - - while ( end_found == FALSE ) { - - temp_int = tds_read_u_short_int ( filein ); - teller = teller + 2; - - if ( debug ) { - printf ( " TDS_READ_EDIT_SECTION processing tag %0X\n", temp_int ); - } - - switch ( temp_int ) { - case 0x1100: - if ( debug ) { - printf ( " BIT_MAP section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0x1201: - if ( debug ) { - printf ( " USE_SOLID_BGND section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0x1300: - if ( debug ) { - printf ( " V_GRADIENT section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0x1400: - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0x1420: - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0x1450: - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0x1500: - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0x2200: - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0x2201: - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0x2210: - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0x2300: - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0x2302: - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0x3000: - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0x2100: - if ( debug ) { - printf ( " AMBIENT_LIGHT section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_ambient_section ( filein ); - break; - case 0x1200: - if ( debug ) { - printf ( " SOLID_BGND section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_background_section ( filein ); - break; - case 0x0100: - if ( debug ) { - printf ( " MASTER_SCALE section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0x3d3e: - if ( debug ) { - printf ( " MESH_VERSION section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xafff: - if ( debug ) { - printf ( " MAT_ENTRY section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_material_section ( filein ); - break; - case 0x4000: - if ( debug ) { - printf ( " NAMED_OBJECT section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_object_section ( filein ); - break; - case 0x7001: - if ( debug ) { - printf ( " VIEWPORT_LAYOUT section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_view_section ( filein, views_read ); - break; - case 0x7012: - if ( debug ) { - printf ( " VIEWPORT_DATA_3 section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0x7011: - if ( debug ) { - printf ( " VIEWPORT_DATA section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0x7020: - if ( debug ) { - printf ( " VIEWPORT_SIZE section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - default: - if ( debug ) { - printf ( " Junk.\n" ); - } - break; - } - - if ( teller >= chunk_length ) { - end_found = TRUE; - } - - } - - pointer = ( long ) ( current_pointer + chunk_length ); - - fseek ( filein, pointer, SEEK_SET ); - - return ( chunk_length ); -} -/******************************************************************************/ - -unsigned long tds_read_keyframe_section ( FILE *filein, int *views_read ) - -/******************************************************************************/ -{ - unsigned long int current_pointer; - unsigned char end_found = FALSE; - long int pointer; - unsigned short int temp_int; - unsigned long int temp_pointer; - unsigned long int teller; - - current_pointer = ftell ( filein ) - 2; - temp_pointer = tds_read_u_long_int ( filein ); - teller = 6; - - while ( end_found == FALSE ) { - - temp_int = tds_read_u_short_int ( filein ); - teller = teller + 2; - - switch ( temp_int ) { - case 0x7001: - if ( debug ) { - printf ( " VIEWPORT_LAYOUT main definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_view_section ( filein, views_read ); - break; - case 0xb008: - if ( debug ) { - printf ( " KFSEG frames section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xb002: - if ( debug ) { - printf ( " OBJECT_NODE_TAG object description section tag of %0X\n", - temp_int); - } - teller = teller + tds_read_keyframe_objdes_section ( filein ); - break; - case 0xb009: - if ( debug ) { - printf ( " KFCURTIME section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xb00a: - if ( debug ) { - printf ( " KFHDR section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - default: - break; - } - - if ( teller >= temp_pointer ) { - end_found = TRUE; - } - - } - - pointer = ( long ) ( current_pointer + temp_pointer ); - fseek ( filein, pointer, SEEK_SET ); - - return ( temp_pointer ); -} -/******************************************************************************/ - -unsigned long tds_read_keyframe_objdes_section ( FILE *filein ) - -/******************************************************************************/ - -/* - Modified: - - 21 September 1998 -*/ -{ - unsigned long int chunk_size; - unsigned long int current_pointer; - unsigned char end_found = FALSE; - long int pointer; - unsigned short int temp_int; - unsigned long int temp_pointer; - unsigned long int teller; - unsigned long int u_long_int_val; - unsigned short int u_short_int_val; - - current_pointer = ftell ( filein ) - 2; - temp_pointer = tds_read_u_long_int ( filein ); - teller = 6; - - while ( end_found == FALSE ) { - - temp_int = tds_read_u_short_int ( filein ); - teller = teller + 2; - - switch ( temp_int ) { - case 0xb011: - if ( debug ) { - printf ( " INSTANCE_NAME section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xb010: - if ( debug ) { - printf ( " NODE_HDR section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xb020: - if ( debug ) { - printf ( " POS_TRACK_TAG section tag of %0X\n", temp_int ); - } - chunk_size = tds_read_u_long_int ( filein ); - if ( debug ) { - printf ( " chunk_size = %d\n", chunk_size ); - } - u_short_int_val = tds_read_u_short_int ( filein ); - u_short_int_val = tds_read_u_short_int ( filein ); - u_short_int_val = tds_read_u_short_int ( filein ); - u_short_int_val = tds_read_u_short_int ( filein ); - u_short_int_val = tds_read_u_short_int ( filein ); - u_short_int_val = tds_read_u_short_int ( filein ); - u_short_int_val = tds_read_u_short_int ( filein ); - u_short_int_val = tds_read_u_short_int ( filein ); - u_long_int_val = tds_read_u_long_int ( filein ); - if ( debug ) { - printf ( "u_short_int_val = %d\n", u_short_int_val ); - printf ( "u_long_int_val = %d\n", u_long_int_val ); - } - origin[0] = float_read ( filein ); - origin[1] = float_read ( filein ); - origin[2] = float_read ( filein ); - teller = teller + 32; - break; - case 0xb013: - if ( debug ) { - printf ( " PIVOT section tag of %0X\n", temp_int ); - } - chunk_size = tds_read_u_long_int ( filein ); - pivot[0] = float_read ( filein ); - pivot[1] = float_read ( filein ); - pivot[2] = float_read ( filein ); - teller = teller + 12; - break; - case 0xb014: - if ( debug ) { - printf ( " BOUNDBOX section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xb015: - if ( debug ) { - printf ( " MORPH_SMOOTH section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xb021: - if ( debug ) { - printf ( " ROT_TRACK_TAG section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xb022: - if ( debug ) { - printf ( " SCL_TRACK_TAG section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xb030: - if ( debug ) { - printf ( " NODE_ID section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - default: - break; - } - - if ( teller >= temp_pointer ) { - end_found = TRUE; - } - - } - - pointer = ( long ) ( current_pointer+temp_pointer ); - fseek ( filein, pointer, SEEK_SET ); - - return ( temp_pointer ); -} -/******************************************************************************/ - -unsigned long tds_read_light_section ( FILE *filein ) - -/******************************************************************************/ -{ - unsigned char boolean; - unsigned long int current_pointer; - unsigned char end_found = FALSE; - int i; - float light_coors[3]; - long int pointer; - float rgb_val[3]; - unsigned long int teller; - unsigned short int temp_int; - unsigned long int temp_pointer; - unsigned char true_c_val[3]; - - current_pointer = ftell ( filein ) - 2; - temp_pointer = tds_read_u_long_int ( filein ); - teller = 6; - - light_coors[0] = float_read ( filein ); - light_coors[1] = float_read ( filein ); - light_coors[2] = float_read ( filein ); - - teller = teller + 3 * 4; - - if ( debug ) { - printf ( " Found light at coordinates XYZ = %f %f %f.\n", - light_coors[0], light_coors[1], light_coors[2] ); - } - - while ( end_found == FALSE ) { - - temp_int = tds_read_u_short_int ( filein ); - teller = teller + 2; - - switch ( temp_int ) { - case 0x0010: - if ( debug ) { - printf ( " COLOR_F RGB color definition section tag of %0X\n", - temp_int ); - } - for ( i = 0; i < 3; i++ ) { - rgb_val[i] = float_read ( filein ); - } - if ( debug ) { - printf ( " RGB_VAL value set to %f %f %f\n", rgb_val[0], - rgb_val[1], rgb_val[2] ); - } - teller = teller + 3 * sizeof ( float ); - break; - case 0x0011: - if ( debug ) { - printf ( " COLOR_24 24 bit color definition section tag of %0X\n", - temp_int ); - } - - for ( i = 0; i < 3; i++ ) { - true_c_val[i] = fgetc ( filein ); - } - if ( debug ) { - printf ( " TRUE_C_VAL value set to %d %d %d\n", true_c_val[0], - true_c_val[1], true_c_val[2] ); - } - teller = teller + 3; - break; - case 0x4620: - if ( debug ) { - printf ( " DL_OFF section: %0X\n", temp_int ); - } - teller = teller + tds_read_boolean ( &boolean, filein ); - if ( debug ) { - if ( boolean == TRUE ) { - printf ( " Light is on\n" ); - } - else { - printf ( " Light is off\n" ); - } - } - break; - case 0x4610: - if ( debug ) { - printf ( " DL_SPOTLIGHT section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_spot_section ( filein ); - break; - case 0x465a: - if ( debug ) { - printf ( " DL_OUTER_RANGE section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - default: - break; - } - - if ( teller >= temp_pointer ) { - end_found = TRUE; - } - - } - - pointer = ( long ) ( current_pointer + temp_pointer ); - fseek ( filein, pointer, SEEK_SET ); - - return ( temp_pointer ); -} -/******************************************************************************/ - -unsigned long int tds_read_u_long_int ( FILE *filein ) - -/******************************************************************************/ - -/* - Modified: - - 01 October 1998 - - Author: - - John Burkardt -*/ -{ - union { - unsigned long int yint; - char ychar[4]; - } y; - - if ( byte_swap == TRUE ) { - y.ychar[3] = fgetc ( filein ); - y.ychar[2] = fgetc ( filein ); - y.ychar[1] = fgetc ( filein ); - y.ychar[0] = fgetc ( filein ); - } - else { - y.ychar[0] = fgetc ( filein ); - y.ychar[1] = fgetc ( filein ); - y.ychar[2] = fgetc ( filein ); - y.ychar[3] = fgetc ( filein ); - } - - return y.yint; -} -/******************************************************************************/ - -int tds_read_long_name ( FILE *filein ) - -/******************************************************************************/ -{ - unsigned char letter; - unsigned int teller; - - teller = 0; - letter = fgetc ( filein ); -/* - Could be a dummy object. -*/ - if ( letter == 0 ) { - strcpy ( temp_name, "Default_name" ); - return -1; - } - - temp_name[teller] = letter; - teller = teller + 1; - - do { - letter = fgetc ( filein ); - temp_name[teller] = letter; - teller = teller + 1; - } while ( letter != 0 ); - - temp_name[teller-1] = 0; - - if ( debug ) { - printf ( " tds_read_long_name found name: %s.\n", temp_name ); - } - - return teller; -} -/******************************************************************************/ - -unsigned long tds_read_matdef_section ( FILE *filein ) - -/******************************************************************************/ -{ - unsigned long int current_pointer; - long int pointer; - int teller; - unsigned long int temp_pointer; - - current_pointer = ftell ( filein ) - 2; - temp_pointer = tds_read_u_long_int ( filein ); - - teller = tds_read_long_name ( filein ); - - if ( teller == -1 ) { - if ( debug ) { - printf ( " No material name found.\n" ); - } - } - else { - strcpy ( mat_name, temp_name ); - if ( debug ) { - printf ( " Material name %s.\n", mat_name ); - } - } - - pointer = ( long ) ( current_pointer + temp_pointer ); - fseek ( filein, pointer, SEEK_SET ); - - return ( temp_pointer ); -} -/******************************************************************************/ - -unsigned long tds_read_material_section ( FILE *filein ) - -/******************************************************************************/ -{ - unsigned long int current_pointer; - unsigned char end_found = FALSE; - long int pointer; - unsigned short int temp_int; - unsigned long int temp_pointer; - unsigned long int teller; - - current_pointer = ftell ( filein ) - 2; - - temp_pointer = tds_read_u_long_int ( filein ); - teller = 6; - - while ( end_found == FALSE ) { - - temp_int = tds_read_u_short_int ( filein ); - teller = teller + 2; - - switch ( temp_int ) { - - case 0xa000: - if ( debug ) { - printf ( " MAT_NAME definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_matdef_section ( filein ); - break; - case 0xa010: - if ( debug ) { - printf ( " MAT_AMBIENT definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa020: - if ( debug ) { - printf ( " MAT_DIFFUSE definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa030: - if ( debug ) { - printf ( " MAT_SPECULAR definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa040: - if ( debug ) { - printf ( " MAT_SHININESS definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa041: - if ( debug ) { - printf ( " MAT_SHIN2PCT definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa042: - if ( debug ) { - printf ( " MAT_SHIN3PCT definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa050: - if ( debug ) { - printf ( " MAT_TRANSPARENCY definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa052: - if ( debug ) { - printf ( " MAT_XPFALL definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa053: - if ( debug ) { - printf ( " MAT_REFBLUR definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa080: - if ( debug ) { - printf ( " MAT_SELF_ILLUM definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa081: - if ( debug ) { - printf ( " MAT_TWO_SIDE definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa082: - if ( debug ) { - printf ( " MAT_DECAL definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa083: - if ( debug ) { - printf ( " MAT_ADDITIVE definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa084: - if ( debug ) { - printf ( " MAT_SELF_ILPCT definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa085: - if ( debug ) { - printf ( " MAT_WIRE definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa086: - if ( debug ) { - printf ( " MAT_SUPERSMP definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa087: - if ( debug ) { - printf ( " MAT_WIRESIZE definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa088: - if ( debug ) { - printf ( " MAT_FACEMAP definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa08a: - if ( debug ) { - printf ( " MAT_XPFALLIN definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa08c: - if ( debug ) { - printf ( " MAT_PHONGSOFT definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa08e: - if ( debug ) { - printf ( " MAT_WIREABS definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa100: - if ( debug ) { - printf ( " MAT_SHADING definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa200: - if ( debug ) { - printf ( " MAT_TEXMAP definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_texmap_section ( filein ); -/* - teller = teller + tds_read_unknown_section ( filein ); -*/ - break; - case 0xa204: - if ( debug ) { - printf ( " MAT_SPECMAP definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa210: - if ( debug ) { - printf ( " MAT_OPACMAP definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa220: - if ( debug ) { - printf ( " MAT_REFLMAP definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa230: - if ( debug ) { - printf ( " MAT_BUMPMAP definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0xa353: - if ( debug ) { - printf ( " MAT_MAP_TEXBLUR definition section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - default: - if ( debug ) { - printf ( " Junk section tag of %0X\n", temp_int ); - } - break; - } - - if ( teller >= temp_pointer ) { - end_found = TRUE; - } - - } - pointer = ( long ) ( current_pointer + temp_pointer ); - - fseek ( filein, pointer, SEEK_SET ); - - return ( temp_pointer ); -} -/******************************************************************************/ - -int tds_read_name ( FILE *filein ) - -/******************************************************************************/ -{ - unsigned char letter; - unsigned int teller; - - teller = 0; - letter = fgetc ( filein ); -/* - Could be a dummy object. -*/ - - if ( letter == 0 ) { - strcpy ( temp_name, "Default name" ); - return (-1); - } - - temp_name[teller] = letter; - teller = teller + 1; - - do { - letter = fgetc ( filein ); - temp_name[teller] = letter; - teller = teller + 1; - } while ( ( letter != 0 ) && ( teller < 12 ) ); - - temp_name[teller-1] = 0; - - if ( debug ) { - printf ( " tds_read_name found name: %s.\n", temp_name ); - } - - return 0; -} -/******************************************************************************/ - -unsigned long tds_read_obj_section ( FILE *filein ) - -/******************************************************************************/ - -/* - Comments: - - Thanks to John F Flanagan for some suggested corrections. - - Modified: - - 30 June 2001 -*/ -{ - unsigned short int b; - unsigned long int chunk_size; - unsigned short int color_index; - unsigned long int current_pointer; - unsigned char end_found = FALSE; - unsigned short int g; - int i; - int j; - int cor3_num_base; - int cor3_num_inc; - int face_num_inc; - long int pointer; - unsigned short int r; - unsigned short int temp_int; - unsigned long int temp_pointer; - unsigned long int temp_pointer2; - unsigned long int teller; - - current_pointer = ftell ( filein ) - 2; - temp_pointer = tds_read_u_long_int ( filein ); - teller = 6; - cor3_num_base = cor3_num; - - while ( end_found == FALSE ) { - - temp_int = tds_read_u_short_int ( filein ); - teller = teller + 2; - - switch ( temp_int ) { - - case 0x4000: - if ( debug ) { - printf ( " NAMED_OBJECT section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - - case 0x4100: - if ( debug ) { - printf ( " N_TRI_OBJECT section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - - case 0x4110: - - if ( debug ) { - printf ( " POINT_ARRAY section tag of %0X\n", temp_int ); - } - - current_pointer = ftell ( filein ) - 2; - temp_pointer2 = tds_read_u_long_int ( filein ); - cor3_num_inc = ( int ) tds_read_u_short_int ( filein ); - - for ( i = cor3_num; i < cor3_num + cor3_num_inc; i++ ) { - cor3[0][i] = float_read ( filein ); - cor3[1][i] = float_read ( filein ); - cor3[2][i] = float_read ( filein ); - } - - cor3_num = cor3_num + cor3_num_inc; - teller = teller + temp_pointer2; - break; - - case 0x4111: - if ( debug ) { - printf ( " POINT_FLAG_ARRAY faces (2) section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - - case 0x4120: - - if ( debug ) { - printf ( " FACE_ARRAY section tag of %0X\n", - temp_int ); - } - - temp_pointer2 = tds_read_u_long_int ( filein ); - face_num_inc = ( int ) tds_read_u_short_int ( filein ); - - for ( i = face_num; i < face_num + face_num_inc; i++ ) { - face[0][i] = tds_read_u_short_int ( filein ) + cor3_num_base; - face[1][i] = tds_read_u_short_int ( filein ) + cor3_num_base; - face[2][i] = tds_read_u_short_int ( filein ) + cor3_num_base; - face_order[i] = 3; - face_flags[i] = tds_read_u_short_int ( filein ); -/* - Color is given per face, and as 24 bit RGB data packed in one word. - Extract RGB from the word, and assign R / 255 to each vertex. - - Just a guess, JVB, 30 June 2001. -*/ - temp_int = face_flags[i] & 0x000F; - r = ( temp_int & 0x0004 ) >> 2; - g = ( temp_int & 0x0002 ) >> 1; - b = ( temp_int & 0x0001 ); - - for ( j = 0; j < 3; j++ ) { - vertex_rgb[0][j][i] = ( float ) r / 255.0; - vertex_rgb[1][j][i] = ( float ) g / 255.0; - vertex_rgb[2][j][i] = ( float ) b / 255.0; - } - - } - - temp_int = tds_read_u_short_int ( filein ); - if ( temp_int == 0x4150 ) { - for ( i = face_num; i < face_num + face_num_inc; i++ ) { - face_smooth[i] = ( int ) tds_read_u_long_int ( filein ) - + cor3_num_base; - } - } - face_num = face_num + face_num_inc; - teller = ftell ( filein ); - break; - - case 0x4130: - if ( debug ) { - printf ( " MSH_MAT_GROUP section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - - case 0x4140: - if ( debug ) { - printf ( " TEX_VERTS section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_tex_verts_section ( filein ); - break; - - case 0x4150: - if ( debug ) { - printf ( " SMOOTH_GROUP section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - - case 0x4160: - - if ( debug ) { - printf ( " MESH_MATRIX section tag of %0X\n", - temp_int ); - } - - tds_read_u_long_int ( filein ); - - for ( j = 0; j < 4; j++ ) { - for ( i = 0; i < 3; i++ ) { - transform_matrix[j][i] = float_read ( filein ); - } - } - transform_matrix[0][3] = 0.0; - transform_matrix[1][3] = 0.0; - transform_matrix[2][3] = 0.0; - transform_matrix[3][3] = 0.0; - - teller = teller + 12 * sizeof ( float ); - break; - - case 0x4165: - - if ( debug ) { - printf ( " MESH_COLOR section tag of %0X\n", temp_int ); - } - - chunk_size = tds_read_u_long_int ( filein ); - - if ( chunk_size == 7 ) { - color_index = fgetc ( filein ); - teller = teller + 5; - } - else { - color_index = tds_read_u_short_int ( filein ); - teller = teller + 6; - } - if ( debug ) { - printf ( " Color index set to %d\n", color_index ); - } - break; - - case 0x4170: - if ( debug ) { - printf ( " MESH_TEXTURE_INFO section tag of %0X\n", - temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - - default: - if ( debug ) { - printf ( " JUNK section tag of %0X\n", temp_int ); - } - break; - } - - if ( teller >= temp_pointer ) { - end_found = TRUE; - } - - } - - pointer = ( long int ) ( current_pointer + temp_pointer ); - fseek ( filein, pointer, SEEK_SET ); - - return ( temp_pointer ); -} -/******************************************************************************/ - -unsigned long tds_read_object_section ( FILE *filein ) - -/******************************************************************************/ -{ - unsigned char end_found = FALSE; - unsigned long int current_pointer; - int int_val; - long int pointer; - unsigned short int temp_int; - unsigned long int temp_pointer; - unsigned long int teller; - - current_pointer = ftell ( filein ) - 2; - temp_pointer = tds_read_u_long_int ( filein ); - teller = 6; -/* - Why don't you read and save the name here? -*/ - int_val = tds_read_name ( filein ); - - if ( int_val == -1 ) { - if ( debug ) { - printf ( " Dummy Object found\n" ); - } - } - else { - strcpy ( object_name, temp_name ); - } - - while ( end_found == FALSE ) { - - temp_int = tds_read_u_short_int ( filein ); - teller = teller + 2; - - switch ( temp_int ) { - case 0x4700: - if ( debug ) { - printf ( " N_CAMERA section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_camera_section ( filein ); - break; - case 0x4600: - if ( debug ) { - printf ( " N_DIRECT_LIGHT section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_light_section ( filein ); - break; - case 0x4100: - if ( debug ) { - printf ( " OBJ_TRIMESH section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_obj_section ( filein ); - break; - case 0x4010: - if ( debug ) { - printf ( " OBJ_HIDDEN section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0x4012: - if ( debug ) { - printf ( " OBJ_DOESNT_CAST section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - default: - break; - } - - if ( teller >= temp_pointer ) { - end_found = TRUE; - } - - } - - pointer = ( long ) ( current_pointer + temp_pointer ); - - fseek ( filein, pointer, SEEK_SET ); - - return ( temp_pointer ); -} -/******************************************************************************/ - -unsigned long int tds_read_tex_verts_section ( FILE *filein ) - -/******************************************************************************/ - -/* - Purpose: - - TDS_READ_TEX_VERTS_SECTION reads the texture vertex data. - - Discussion: - - The texture vertex data seems to be associated with nodes. This routine - distributes that data to vertices (nodes as they make up a particular - face). - - Modified: - - 02 July 1999 - - Author: - - John Burkardt -*/ -{ - unsigned long int current_pointer; - int icor3; - long int pointer; - unsigned long int temp_pointer; - unsigned short int n2; - - current_pointer = ftell ( filein ) - 2; - temp_pointer = tds_read_u_long_int ( filein ); - - pointer = ( long int ) ( current_pointer + temp_pointer ); - - n2 = tds_read_u_short_int ( filein ); - - for ( icor3 = 0; icor3 < n2; icor3++ ) { - cor3_tex_uv[0][icor3] = float_read ( filein ); - cor3_tex_uv[1][icor3] = float_read ( filein ); - } - - fseek ( filein, pointer, SEEK_SET ); - - return ( temp_pointer ); -} -/******************************************************************************/ - -unsigned long tds_read_texmap_section ( FILE *filein ) - -/******************************************************************************/ - -/* - Purpose: - - TDS_READ_TEXMAP_SECTION tries to get the TEXMAP name from the TEXMAP section. - - Warning: - - The code has room for lots of textures. In this routine, we behave as - though there were only one, and we stick its name in the first name slot. - - Modified: - - 30 June 1999 - - Author: - - John Burkardt -*/ -{ - unsigned long int current_pointer; - long int pointer; - int teller; - unsigned long int temp_pointer; - - texture_num = texture_num + 1; - - current_pointer = ftell ( filein ) - 2; - temp_pointer = tds_read_u_long_int ( filein ); - - tds_read_u_short_int ( filein ); - tds_read_u_short_int ( filein ); - tds_read_u_short_int ( filein ); - tds_read_u_short_int ( filein ); - -/* - This next short int should equal A300. -*/ - tds_read_u_short_int ( filein ); - tds_read_u_long_int ( filein ); -/* - Now read the TEXMAP file name. -*/ - teller = tds_read_long_name ( filein ); - - if ( teller == -1 ) { - if ( debug ) { - printf ( " No TEXMAP name found.\n" ); - } - } - else { - strcpy ( texture_name[0], temp_name ); - if ( debug ) { - printf ( " TEXMAP name %s.\n", texture_name[0] ); - } - } - - pointer = ( long ) ( current_pointer + temp_pointer ); - fseek ( filein, pointer, SEEK_SET ); - - return ( temp_pointer ); -} -/******************************************************************************/ - -unsigned short int tds_read_u_short_int ( FILE *filein ) - -/******************************************************************************/ -{ - unsigned char c1; - unsigned char c2; - short int ival; - - c1 = fgetc ( filein ); - c2 = fgetc ( filein ); - - ival = c1 | ( c2 << 8 ); - - return ival; -} -/******************************************************************************/ - -unsigned long tds_read_spot_section ( FILE *filein ) - -/******************************************************************************/ -{ - unsigned long int current_pointer; - float falloff; - float hotspot; - long int pointer; - float target[4]; - unsigned long int temp_pointer; - - current_pointer = ftell ( filein ) - 2; - temp_pointer = tds_read_u_long_int ( filein ); - - target[0] = float_read ( filein ); - target[1] = float_read ( filein ); - target[2] = float_read ( filein ); - hotspot = float_read ( filein ); - falloff = float_read ( filein ); - - if ( debug ) { - printf ( " The target of the spot is XYZ = %f %f %f.\n", - target[0], target[1], target[2] ); - printf ( " The hotspot of this light is %f.\n", hotspot ); - printf ( " The falloff of this light is %f.\n", falloff ); - } - - pointer = ( long ) ( current_pointer + temp_pointer ); - - fseek ( filein, pointer, SEEK_SET ); - - return ( temp_pointer ); -} -/******************************************************************************/ - -unsigned long int tds_read_unknown_section ( FILE *filein ) - -/******************************************************************************/ -{ - unsigned long int current_pointer; - long int pointer; - unsigned long int temp_pointer; - - current_pointer = ftell ( filein ) - 2; - temp_pointer = tds_read_u_long_int ( filein ); - - pointer = ( long int ) ( current_pointer + temp_pointer ); - - fseek ( filein, pointer, SEEK_SET ); - - return ( temp_pointer ); -} -/******************************************************************************/ - -unsigned long tds_read_view_section ( FILE *filein, int *views_read ) - -/******************************************************************************/ -{ - unsigned long int current_pointer; - unsigned char end_found = FALSE; - long int pointer; - unsigned short int temp_int; - unsigned long int temp_pointer; - unsigned long int teller; - - current_pointer = ftell ( filein ) - 2; - temp_pointer = tds_read_u_long_int ( filein ); - teller = 6; - - while ( end_found == FALSE ) { - - temp_int = tds_read_u_short_int ( filein ); - teller = teller + 2; - - switch ( temp_int ) { - case 0x7012: - if ( debug ) { - printf ( " VIEWPORT_DATA_3 section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_vp_section ( filein, views_read ); - break; - case 0x7011: - if ( debug ) { - printf ( " VIEWPORT_DATA section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_unknown_section ( filein ); - break; - case 0x7020: - if ( debug ) { - printf ( " VIEWPORT_SIZE section tag of %0X\n", temp_int ); - } - teller = teller + tds_read_vp_section ( filein, views_read ); - break; - default: - break; - } - - if ( teller >= temp_pointer ) { - end_found = TRUE; - } - - if ( *views_read > 3 ) { - end_found = TRUE; - } - } - - pointer = ( long int ) ( current_pointer + temp_pointer ); - - fseek ( filein, pointer, SEEK_SET ); - - return ( temp_pointer ); -} -/******************************************************************************/ - -unsigned long tds_read_vp_section ( FILE *filein, int *views_read ) - -/******************************************************************************/ -{ - unsigned int attribs; - unsigned long int current_pointer; - int i; - int int_val; - long int pointer; - unsigned int port; - unsigned long int temp_pointer; - char *viewports[11] = { - "Bogus", - "Top", - "Bottom", - "Left", - "Right", - "Front", - "Back", - "User", - "Camera", - "Light", - "Disabled" - }; - - *views_read = *views_read + 1; - - current_pointer = ftell ( filein ) - 2; - temp_pointer = tds_read_u_long_int ( filein ); - - attribs = tds_read_u_short_int ( filein ); - - if ( attribs == 3 ) { - if ( debug ) { - printf ( " active in viewport.\n" ); - } - } - - if ( attribs == 5 ) { - if ( debug ) { - printf ( " active in viewport.\n" ); - } - } -/* - Read 5 INTS to get to the viewport information. -*/ - for ( i = 1; i < 6; i++ ) { - tds_read_u_short_int ( filein ); - } - - port = tds_read_u_short_int ( filein ); -/* - Find camera section. -*/ - if ( ( port == 0xffff ) || ( port == 0 ) ) { - - for ( i = 0; i < 12; i++ ) { - tds_read_u_short_int ( filein ); - } - - int_val = tds_read_name (filein ); - - if ( int_val == -1 ) { - if ( debug ) { - printf ( " No Camera name found\n" ); - } - } - - port = 0x0008; - } - - if ( debug ) { - printf ( "Reading [%s] information with tag:%d\n", viewports[port], port ); - } - - pointer = ( long int ) ( current_pointer + temp_pointer ); - - fseek ( filein, pointer, SEEK_SET ); - - return ( temp_pointer ); -} -/******************************************************************************/ - -int tds_write ( FILE *fileout ) - -/******************************************************************************/ - -/* - Purpose: - - TDS_WRITE writes graphics information to a 3D Studio Max 3DS file. - - Modified: - - 14 October 1998 - - Author: - - John Burkardt - -*/ -{ - float float_val; - int i; - int icor3; - int iface; - int j; - long int l0002; - long int l0100; - long int l3d3d; - long int l3d3e; - long int l4000; - long int l4100; - long int l4110; - long int l4120; - long int l4150; - long int l4160; - long int l4d4d; - long int lb000; - long int lb002; - long int lb00a; - long int lb008; - long int lb009; - long int lb010; - long int lb013; - long int lb020; - long int lb021; - long int lb022; - long int lb030; - long int long_int_val; - int name_length; - short int short_int_val; - unsigned short int u_short_int_val; - - bytes_num = 0; - name_length = strlen ( object_name ); - - l0002 = 10; - - l4150 = 2 + 4 + face_num * 4; - l4120 = 2 + 4 + 2 + 4 * face_num * 2 + l4150; - l4160 = 2 + 4 + 4 * 12; - l4110 = 2 + 4 + 2 + cor3_num * 3 * 4; - l4100 = 2 + 4 + l4110 + l4160 + l4120; - l4000 = 2 + 4 + ( name_length + 1 ) + l4100; - l0100 = 2 + 4 + 4; - l3d3e = 2 + 4 + 4; - l3d3d = 2 + 4 + l3d3e + l0100 + l4000; - - lb022 = 2 + 4 + 32; - lb021 = 2 + 4 + 9 * 4; - lb020 = 2 + 4 + 8 * 4; - lb013 = 2 + 4 + 6 * 2; - lb010 = 2 + 4 + ( name_length + 1 ) + 3 * 2; - lb030 = 2 + 4 + 2; - lb002 = 2 + 4 + lb030 + lb010 + lb013 + lb020 + lb021 + lb022; - lb009 = 2 + 4 + 4; - lb008 = 2 + 4 + 2 * 4; - lb00a = 2 + 4 + 2 + 9 + 2 * 2; - lb000 = 2 + 4 + lb00a + lb008 + lb009 + lb002; - - l4d4d = 2 + 4 + l0002 + l3d3d + lb000; -/* - M3DMAGIC begin. - tag, size. -*/ - short_int_val = ( short ) 0x4d4d; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + long_int_write ( fileout, l4d4d ); -/* - M3D_VERSION begin. - tag, size, version. -*/ - short_int_val = ( short ) 0x0002; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + long_int_write ( fileout, l0002 ); - long_int_val = 3; - bytes_num = bytes_num + long_int_write ( fileout, long_int_val ); -/* - M3D_VERSION end. - MDATA begin. - tag, size. -*/ - short_int_val = ( short ) 0x3d3d; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + long_int_write ( fileout, l3d3d ); -/* - MESH_VERSION begin. - tag, size, version. -*/ - short_int_val = ( short ) 0x3d3e; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + long_int_write ( fileout, l3d3e ); - long_int_val = 3; - bytes_num = bytes_num + long_int_write ( fileout, long_int_val ); -/* - MESH_VERSION end. - MASTER_SCALE begin. - tag, size, scale. -*/ - short_int_val = ( short ) 0x0100; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + long_int_write ( fileout, l0100 ); - float_val = 1.0; - bytes_num = bytes_num + float_write ( fileout, float_val ); -/* - MASTER_SCALE end. - NAMED_OBJECT begin. - tag, size, name. -*/ - short_int_val = ( short ) 0x4000; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + long_int_write ( fileout, l4000 ); - bytes_num = bytes_num + tds_write_string ( fileout, object_name ); -/* - N_TRI_OBJECT begin. - tag, size. -*/ - short_int_val = ( short ) 0x4100; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + long_int_write ( fileout, l4100 ); -/* - POINT_ARRAY begin. - tag, size, number of points, coordinates of points. - Warning! number of points could exceed a short! -*/ - short_int_val = ( short ) 0x4110; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + long_int_write ( fileout, l4110 ); - - u_short_int_val = ( unsigned short ) cor3_num; - bytes_num = bytes_num + tds_write_u_short_int ( fileout, u_short_int_val ); - - for ( icor3 = 0; icor3 < cor3_num; icor3++ ) { - for ( j = 0; j < 3; j++ ) { - bytes_num = bytes_num + float_write ( fileout, cor3[j][icor3] ); - } - } -/* - POINT_ARRAY end. - MESH_MATRIX begin. - tag, size, 4 by 3 matrix. -*/ - short_int_val = ( short ) 0x4160; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + long_int_write ( fileout, l4160 ); - - for ( i = 0; i < 4; i++ ) { - for ( j = 0; j < 3; j++ ) { - float_val = transform_matrix[i][j]; - bytes_num = bytes_num + float_write ( fileout, float_val ); - } - } -/* - MESH_MATRIX end. - FACE_ARRAY begin. - tag, size, number of faces, nodes per face. - Warning: number of faces could exceed a short! -*/ - short_int_val = ( short ) 0x4120; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + long_int_write ( fileout, l4120 ); - - u_short_int_val = ( unsigned short ) face_num; - bytes_num = bytes_num + tds_write_u_short_int ( fileout, u_short_int_val ); - - for ( iface = 0; iface < face_num; iface++ ) { - for ( j = 0; j < 3; j++ ) { - short_int_val = face[j][iface]; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - } - short_int_val = face_flags[iface]; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - } -/* - SMOOTH_GROUP begin. - tag, size, group for each face. -*/ - short_int_val = ( short ) 0x4150; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + long_int_write ( fileout, l4150 ); - - for ( iface = 0; iface < face_num; iface++ ) { - long_int_val = face_smooth[iface]; - bytes_num = bytes_num + long_int_write ( fileout, long_int_val ); - } -/* - SMOOTH_GROUP end. - FACE_ARRAY end. - N_TRI_OBJECT end. - NAMED_OBJECT end. - MDATA end. - KFDATA begin. -*/ - short_int_val = ( short ) 0xb000; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + long_int_write ( fileout, lb000 ); -/* - KFHDR begin. - tag, size, revision, filename, animlen. -*/ - short_int_val = ( short ) 0xb00a; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + long_int_write ( fileout, lb00a ); - short_int_val = 5; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + tds_write_string ( fileout, "MAXSCENE" ); - short_int_val = 100; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); -/* - KFHDR end. - KFSEG begin. - tag, size, start, end. -*/ - short_int_val = ( short ) 0xb008; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + long_int_write ( fileout, lb008 ); - long_int_val = 0; - bytes_num = bytes_num + long_int_write ( fileout, long_int_val ); - long_int_val = 100; - bytes_num = bytes_num + long_int_write ( fileout, long_int_val ); -/* - KFSEG end. - KFCURTIME begin. - tag, size, current_frame. -*/ - short_int_val = ( short ) 0xb009; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + long_int_write ( fileout, lb009 ); - long_int_val = 0; - bytes_num = bytes_num + long_int_write ( fileout, long_int_val ); -/* - KFCURTIME end. - OBJECT_NODE_TAG begin. - tag, size. -*/ - short_int_val = ( short ) 0xb002; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + long_int_write ( fileout, lb002 ); -/* - NODE_ID begin. - tag, size, id. -*/ - short_int_val = ( short ) 0xb030; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + long_int_write ( fileout, lb030 ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); -/* - NODE_ID end. - NODE_HDR begin. - tag, size, object_name, flag1, flag2, hierarchy. -*/ - short_int_val = ( short ) 0xb010; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + long_int_write ( fileout, lb010 ); - bytes_num = bytes_num + tds_write_string ( fileout, object_name ); - short_int_val = 16384; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = -1; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); -/* - NODE_HDR end. - PIVOT begin. - tag, size, pivot_x, pivot_y, pivot_z. -*/ - short_int_val = ( short ) 0xb013; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + long_int_write ( fileout, lb013 ); - for ( i = 0; i < 3; i++ ) { - float_val = pivot[i]; - bytes_num = bytes_num + float_write ( fileout, float_val ); - } -/* - PIVOT end. - POS_TRACK_TAG begin. - tag, size, flag, i1, i2, i3, i4, i5, i6, frame, l1, pos_x, pos_y, pos_z. -*/ - short_int_val = ( short ) 0xb020; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + long_int_write ( fileout, lb020 ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 1; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - long_int_val = 0; - bytes_num = bytes_num + long_int_write ( fileout, long_int_val ); - for ( i = 0; i < 3; i++ ) { - float_val = origin[i]; - bytes_num = bytes_num + float_write ( fileout, float_val ); - } -/* - POS_TRACK_TAG end. - ROT_TRACK_TAG begin. - tag, size, i1, i2, i3, i4, i5, i6, i7, i8, l1, rad, axis_x, axis_y, axis_z. -*/ - short_int_val = ( short ) 0xb021; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + long_int_write ( fileout, lb021 ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 1; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - long_int_val = 0; - bytes_num = bytes_num + long_int_write ( fileout, long_int_val ); - float_val = 0.0; - bytes_num = bytes_num + float_write ( fileout, float_val ); - bytes_num = bytes_num + float_write ( fileout, float_val ); - bytes_num = bytes_num + float_write ( fileout, float_val ); - bytes_num = bytes_num + float_write ( fileout, float_val ); -/* - ROT_TRACK_TAG end. - SCL_TRACK_TAG begin. - tag, size, i1, i2, i3, i4, i5, i6, i7, i8, l1, scale_x, scale_y, scale_z. -*/ - short_int_val = ( short ) 0xb022; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - bytes_num = bytes_num + long_int_write ( fileout, lb022 ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 1; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - short_int_val = 0; - bytes_num = bytes_num + short_int_write ( fileout, short_int_val ); - long_int_val = 0; - bytes_num = bytes_num + long_int_write ( fileout, long_int_val ); - float_val = 1.0; - bytes_num = bytes_num + float_write ( fileout, float_val ); - bytes_num = bytes_num + float_write ( fileout, float_val ); - bytes_num = bytes_num + float_write ( fileout, float_val ); -/* - SCL_TRACK_TAG end. - OBJECT_NODE_TAG end. - KFDATA end. - M3DMAGIC end. -*/ - -/* - Report. -*/ - printf ( "TDS_WRITE wrote %d bytes.\n", bytes_num ); - - return SUCCESS; -} -/******************************************************************************/ - -int tds_write_string ( FILE *fileout, char *string ) - -/******************************************************************************/ - -/* - Modified: - - 23 September 1998 - - Author: - - John Burkardt -*/ -{ - char *c; - int nchar; - - nchar = 0; - - for ( c = string; nchar < 12; c++ ) { - - fputc ( *c, fileout ); - nchar = nchar + 1; - - if ( *c == 0 ) { - return nchar; - } - - } - - return nchar; -} -/******************************************************************************/ - -int tds_write_u_short_int ( FILE *fileout, unsigned short int short_int_val ) - -/******************************************************************************/ - -/* - Modified: - - 14 October 1998 - - Author: - - John Burkardt -*/ -{ - union { - unsigned short int yint; - char ychar[2]; - } y; - - y.yint = short_int_val; - - if ( byte_swap == TRUE ) { - fputc ( y.ychar[1], fileout ); - fputc ( y.ychar[0], fileout ); - } - else { - fputc ( y.ychar[0], fileout ); - fputc ( y.ychar[1], fileout ); - } - - return 2; -} -/**********************************************************************/ - -int tec_write ( FILE *fileout ) - -/**********************************************************************/ - -/* - Purpose: - - TEC_WRITE writes graphics information to a TECPLOT file. - - Discussion: - - The file format used is appropriate for 3D finite element surface - zone data. Polygons are decomposed into triangles where necessary. - - Example: - - TITLE = "cube.tec created by IVCON." - VARIABLES = "X", "Y", "Z", "R", "G", "B" - ZONE T="TRIANGLES", N=8, E=12, F=FEPOINT, ET=TRIANGLE - 0.0 0.0 0.0 0.0 0.0 0.0 - 1.0 0.0 0.0 1.0 0.0 0.0 - 1.0 1.0 0.0 1.0 1.0 0.0 - 0.0 1.0 0.0 0.0 1.0 0.0 - 0.0 0.0 1.0 0.0 0.0 1.0 - 1.0 0.0 1.0 1.0 0.0 1.0 - 1.0 1.0 1.0 1.0 1.0 1.0 - 0.0 1.0 1.0 0.0 1.0 1.0 - 1 4 2 - 2 4 3 - 1 5 8 - 1 2 5 - 2 6 5 - 2 3 6 - 3 7 6 - 3 4 7 - 4 8 7 - 4 1 8 - 5 6 8 - 6 7 8 - - Modified: - - 09 June 1999 - - Author: - - John Burkardt -*/ -{ - float b; - int face2[3]; - float g; - int icor3; - int iface; - int imat; - int j; - int face_num2; - int text_num; - float r; -/* - Determine the number of triangular faces. -*/ - face_num2 = 0; - for ( iface = 0; iface < face_num; iface++ ) { - for ( j = 0; j < face_order[iface] - 2; j++ ) { - face_num2 = face_num2 + 1; - } - } - - text_num = 0; - - fprintf ( fileout, "\"%s created by IVCON.\"\n", fileout_name ); - fprintf ( fileout, "VARIABLES = \"X\", \"Y\", \"Z\", \"R\", \"G\", \"B\"\n" ); - fprintf ( fileout, - "ZONE T=\"TRIANGLES\", N=%d, E=%d, F=FEPOINT, ET=TRIANGLE\n", - cor3_num, face_num2 ); - - text_num = text_num + 3; -/* - Write out X, Y, Z, R, G, B per node. -*/ - for ( icor3 = 0; icor3 < cor3_num; icor3++ ) { - imat = cor3_material[icor3]; - r = material_rgba[0][imat]; - g = material_rgba[1][imat]; - b = material_rgba[2][imat]; - fprintf ( fileout, "%f %f %f %f %f %f\n", cor3[0][icor3], cor3[1][icor3], - cor3[2][icor3], r, g, b ); - text_num = text_num + 1; - } -/* - Do the next face. -*/ - for ( iface = 0; iface < face_num; iface++ ) { -/* - Break the face up into triangles, anchored at node 1. -*/ - for ( j = 0; j < face_order[iface] - 2; j++ ) { - - face2[0] = face[ 0][iface] + 1; - face2[1] = face[j+1][iface] + 1; - face2[2] = face[j+2][iface] + 1; - - fprintf ( fileout, "%d %d %d\n", face2[0], face2[1], face2[2] ); - text_num = text_num + 1; - - } - - } -/* - Report. -*/ - printf ( "\n" ); - printf ( "TEC_WRITE - Wrote %d text lines.\n", text_num ); - - return SUCCESS; -} - -/*********************************************************************/ - -void tmat_init ( float a[4][4] ) - -/*********************************************************************/ - -/* - Purpose: - - TMAT_INIT initializes the geometric transformation matrix. - - Definition: - - The geometric transformation matrix can be thought of as a 4 by 4 - matrix "A" having components: - - r11 r12 r13 t1 - r21 r22 r23 t2 - r31 r32 r33 t3 - 0 0 0 1 - - This matrix encodes the rotations, scalings and translations that - are applied to graphical objects. - - A point P = (x,y,z) is rewritten in "homogeneous coordinates" as - PH = (x,y,z,1). Then to apply the transformations encoded in A to - the point P, we simply compute A * PH. - - Individual transformations, such as a scaling, can be represented - by simple versions of the transformation matrix. If the matrix - A represents the current set of transformations, and we wish to - apply a new transformation B, { the original points are - transformed twice: B * ( A * PH ). The new transformation B can - be combined with the original one A, to give a single matrix C that - encodes both transformations: C = B * A. - - Modified: - - 19 October 1998 - - Author: - - John Burkardt - - Reference: - - Foley, van Dam, Feiner, Hughes, - Computer Graphics, Principles and Practice, - Addison Wesley, Second Edition, 1990. - - Parameters: - - Input, float A[4][4], the geometric transformation matrix. -*/ -{ - int i; - int j; - - for ( i = 0; i < 4; i++ ) { - for ( j = 0; j < 4; j++ ) { - if ( i == j ) { - a[i][j] = 1.0; - } - else { - a[i][j] = 0.0; - } - } - } - return; -} -/*********************************************************************/ - -void tmat_mxm ( float a[4][4], float b[4][4], float c[4][4] ) - -/*********************************************************************/ - -/* - Purpose: - - TMAT_MXM multiplies two geometric transformation matrices. - - Note: - - The product is accumulated in a temporary array, and { assigned - to the result. Therefore, it is legal for any two, or all three, - of the arguments to share memory. - - Modified: - - 19 October 1998 - - Author: - - John Burkardt - - Reference: - - Foley, van Dam, Feiner, Hughes, - Computer Graphics, Principles and Practice, - Addison Wesley, Second Edition, 1990. - - Parameters: - - Input, float A[4][4], the first geometric transformation matrix. - - Input, float B[4][4], the second geometric transformation matrix. - - Output, float C[4][4], the product A * B. -*/ -{ - float d[4][4]; - int i; - int j; - int k; - - for ( i = 0; i < 4; i++ ) { - for ( k = 0; k < 4; k++ ) { - d[i][k] = 0.0; - for ( j = 0; j < 4; j++ ) { - d[i][k] = d[i][k] + a[i][j] * b[j][k]; - } - } - } - - for ( i = 0; i < 4; i++ ) { - for ( j = 0; j < 4; j++ ) { - c[i][j] = d[i][j]; - } - } - return; -} -/*********************************************************************/ - -void tmat_mxp ( float a[4][4], float x[4], float y[4] ) - -/*********************************************************************/ - -/* - Purpose: - - TMAT_MXP multiplies a geometric transformation matrix times a point. - - Modified: - - 19 October 1998 - - Author: - - John Burkardt - - Reference: - - Foley, van Dam, Feiner, Hughes, - Computer Graphics, Principles and Practice, - Addison Wesley, Second Edition, 1990. - - Parameters: - - Input, float A[4][4], the geometric transformation matrix. - - Input, float X[4], the point to be multiplied. The fourth component - of X is implicitly assigned the value of 1. - - Output, float Y[4], the result of A*X. The product is accumulated in - a temporary vector, and { assigned to the result. Therefore, it - is legal for X and Y to share memory. -*/ -{ - int i; - int j; - float z[4]; - - for ( i = 0; i < 3; i++ ) { - z[i] = a[i][3]; - for ( j = 0; j < 3; j++ ) { - z[i] = z[i] + a[i][j] * x[j]; - } - } - - for ( i = 0; i < 3; i++ ) { - y[i] = z[i]; - } - return; -} -/*********************************************************************/ - -void tmat_mxp2 ( float a[4][4], float x[][3], float y[][3], int n ) - -/*********************************************************************/ - -/* - Purpose: - - TMAT_MXP2 multiplies a geometric transformation matrix times N points. - - Modified: - - 20 October 1998 - - Author: - - John Burkardt - - Reference: - - Foley, van Dam, Feiner, Hughes, - Computer Graphics, Principles and Practice, - Addison Wesley, Second Edition, 1990. - - Parameters: - - Input, float A[4][4], the geometric transformation matrix. - - Input, float X[N][3], the points to be multiplied. - - Output, float Y[N][3], the transformed points. Each product is - accumulated in a temporary vector, and { assigned to the - result. Therefore, it is legal for X and Y to share memory. - -*/ -{ - int i; - int j; - int k; - float z[4]; - - for ( k = 0; k < n; k++ ) { - - for ( i = 0; i < 3; i++ ) { - z[i] = a[i][3]; - for ( j = 0; j < 3; j++ ) { - z[i] = z[i] + a[i][j] * x[k][j]; - } - } - - for ( i = 0; i < 3; i++ ) { - y[k][i] = z[i]; - } - - } - return; -} -/*********************************************************************/ - -void tmat_mxv ( float a[4][4], float x[4], float y[4] ) - -/*********************************************************************/ - -/* - Purpose: - - TMAT_MXV multiplies a geometric transformation matrix times a vector. - - Modified: - - 12 August 1999 - - Author: - - John Burkardt - - Reference: - - Foley, van Dam, Feiner, Hughes, - Computer Graphics, Principles and Practice, - Addison Wesley, Second Edition, 1990. - - Parameters: - - Input, float A[4][4], the geometric transformation matrix. - - Input, float X[3], the vector to be multiplied. The fourth component - of X is implicitly assigned the value of 1. - - Output, float Y[3], the result of A*X. The product is accumulated in - a temporary vector, and assigned to the result. Therefore, it - is legal for X and Y to share memory. -*/ -{ - int i; - int j; - float z[4]; - - for ( i = 0; i < 3; i++ ) { - z[i] = 0.0; - for ( j = 0; j < 3; j++ ) { - z[i] = z[i] + a[i][j] * x[j]; - } - z[i] = z[i] + a[i][3]; - } - - for ( i = 0; i < 3; i++ ) { - y[i] = z[i]; - } - return; -} -/*********************************************************************/ - -void tmat_rot_axis ( float a[4][4], float b[4][4], float angle, - char axis ) - -/*********************************************************************/ - -/* - Purpose: - - TMAT_ROT_AXIS applies an axis rotation to the geometric transformation matrix. - - Modified: - - 19 April 1999 - - Author: - - John Burkardt - - Reference: - - Foley, van Dam, Feiner, Hughes, - Computer Graphics, Principles and Practice, - Addison Wesley, Second Edition, 1990. - - Parameters: - - Input, float A[4][4], the current geometric transformation matrix. - - Output, float B[4][4], the modified geometric transformation matrix. - A and B may share the same memory. - - Input, float ANGLE, the angle, in degrees, of the rotation. - - Input, character AXIS, is 'X', 'Y' or 'Z', specifying the coordinate - axis about which the rotation occurs. -*/ -{ - float c[4][4]; - float d[4][4]; - int i; - int j; - float theta; - - theta = angle * DEG_TO_RAD; - - tmat_init ( c ); - - if ( axis == 'X' || axis == 'x' ) { - c[1][1] = cos ( theta ); - c[1][2] = - sin ( theta ); - c[2][1] = sin ( theta ); - c[2][2] = cos ( theta ); - } - else if ( axis == 'Y' || axis == 'y' ) { - c[0][0] = cos ( theta ); - c[0][2] = sin ( theta ); - c[2][0] = - sin ( theta ); - c[2][2] = cos ( theta ); - } - else if ( axis == 'Z' || axis == 'z' ) { - c[0][0] = cos ( theta ); - c[0][1] = - sin ( theta ); - c[1][0] = sin ( theta ); - c[1][1] = cos ( theta ); - } - else { - printf ( "\n" ); - printf ( "TMAT_ROT_AXIS - Fatal error!\n" ); - printf ( " Illegal rotation axis: %c.\n", axis ); - printf ( " Legal choices are 'X', 'Y', or 'Z'.\n" ); - return; - } - - tmat_mxm ( c, a, d ); - - for ( i = 0; i < 4; i++ ) { - for ( j = 0; j < 4; j++ ) { - b[i][j] = d[i][j]; - } - } - return; -} -/*********************************************************************/ - -void tmat_rot_vector ( float a[4][4], float b[4][4], float angle, - float v1, float v2, float v3 ) - -/*********************************************************************/ - -/* - Purpose: - - TMAT_ROT_VECTOR applies a rotation about a vector to the geometric transformation matrix. - - Modified: - - 27 July 1999 - - Author: - - John Burkardt - - Reference: - - Foley, van Dam, Feiner, Hughes, - Computer Graphics, Principles and Practice, - Addison Wesley, Second Edition, 1990. - - Parameters: - - Input, float A[4][4], the current geometric transformation matrix. - - Output, float B[4][4], the modified geometric transformation matrix. - A and B may share the same memory. - - Input, float ANGLE, the angle, in degrees, of the rotation. - - Input, float V1, V2, V3, the X, Y and Z coordinates of a (nonzero) - point defining a vector from the origin. The rotation will occur - about this axis. -*/ -{ - float c[4][4]; - float ca; - float d[4][4]; - int i; - int j; - float sa; - float theta; - - if ( v1 * v1 + v2 * v2 + v3 * v3 == 0.0 ) { - return; - } - - theta = angle * DEG_TO_RAD; - - tmat_init ( c ); - - ca = cos ( theta ); - sa = sin ( theta ); - - c[0][0] = v1 * v1 + ca * ( 1.0 - v1 * v1 ); - c[0][1] = ( 1.0 - ca ) * v1 * v2 - sa * v3; - c[0][2] = ( 1.0 - ca ) * v1 * v3 + sa * v2; - - c[1][0] = ( 1.0 - ca ) * v2 * v1 + sa * v3; - c[1][1] = v2 * v2 + ca * ( 1.0 - v2 * v2 ); - c[1][2] = ( 1.0 - ca ) * v2 * v3 - sa * v1; - - c[2][0] = ( 1.0 - ca ) * v3 * v1 - sa * v2; - c[2][1] = ( 1.0 - ca ) * v3 * v2 + sa * v1; - c[2][2] = v3 * v3 + ca * ( 1.0 - v3 * v3 ); - - tmat_mxm ( c, a, d ); - - for ( i = 0; i < 4; i++ ) { - for ( j = 0; j < 4; j++ ) { - b[i][j] = d[i][j]; - } - } - return; -} -/*********************************************************************/ - -void tmat_scale ( float a[4][4], float b[4][4], float sx, float sy, - float sz ) - -/*********************************************************************/ - -/* - Purpose: - - TMAT_SCALE applies a scaling to the geometric transformation matrix. - - Modified: - - 19 October 1998 - - Author: - - John Burkardt - - Reference: - - Foley, van Dam, Feiner, Hughes, - Computer Graphics, Principles and Practice, - Addison Wesley, Second Edition, 1990. - - Parameters: - - Input, float A[4][4], the current geometric transformation matrix. - - Output, float B[4][4], the modified geometric transformation matrix. - A and B may share the same memory. - - Input, float SX, SY, SZ, the scalings to be applied to the X, Y and - Z coordinates. -*/ -{ - float c[4][4]; - float d[4][4]; - int i; - int j; - - tmat_init ( c ); - - c[0][0] = sx; - c[1][1] = sy; - c[2][2] = sz; - - tmat_mxm ( c, a, d ); - - for ( i = 0; i < 4; i++ ) { - for ( j = 0; j < 4; j++ ) { - b[i][j] = d[i][j]; - } - } - return; -} -/*********************************************************************/ - -void tmat_shear ( float a[4][4], float b[4][4], char *axis, float s ) - -/*********************************************************************/ - -/* - Purpose: - - TMAT_SHEAR applies a shear to the geometric transformation matrix. - - Modified: - - 19 October 1998 - - Author: - - John Burkardt - - Reference: - - Foley, van Dam, Feiner, Hughes, - Computer Graphics, Principles and Practice, - Addison Wesley, Second Edition, 1990. - - Parameters: - - Input, float A[4][4], the current geometric transformation matrix. - - Output, float B[4][4], the modified geometric transformation matrix. - A and B may share the same memory. - - Input, character*3 AXIS, is 'XY', 'XZ', 'YX', 'YZ', 'ZX' or 'ZY', - specifying the shear equation: - - XY: x' = x + s * y; - XZ: x' = x + s * z; - YX: y' = y + s * x; - YZ: y' = y + s * z; - ZX: z' = z + s * x; - ZY: z' = z + s * y. - - Input, float S, the shear coefficient. -*/ -{ - float c[4][4]; - float d[4][4]; - int i; - int j; - - tmat_init ( c ); - - if ( strcmp ( axis, "XY" ) == 0 || strcmp ( axis, "xy" ) == 0 ) { - c[0][1] = s; - } - else if ( strcmp ( axis, "XZ" ) == 0 || strcmp ( axis, "xz" ) == 0 ) { - c[0][2] = s; - } - else if ( strcmp ( axis, "YX" ) == 0 || strcmp ( axis, "yx" ) == 0 ) { - c[1][0] = s; - } - else if ( strcmp ( axis, "YZ" ) == 0 || strcmp ( axis, "yz" ) == 0 ) { - c[1][2] = s; - } - else if ( strcmp ( axis, "ZX" ) == 0 || strcmp ( axis, "zx" ) == 0 ) { - c[2][0] = s; - } - else if ( strcmp ( axis, "ZY" ) == 0 || strcmp ( axis, "zy" ) == 0 ) { - c[2][1] = s; - } - else { - printf ( "\n" ); - printf ( "TMAT_SHEAR - Fatal error!\n" ); - printf ( " Illegal shear axis: %s.\n", axis ); - printf ( " Legal choices are XY, XZ, YX, YZ, ZX, or ZY.\n" ); - return; - } - - tmat_mxm ( c, a, d ); - - for ( i = 0; i < 4; i++ ) { - for ( j = 0; j < 4; j++ ) { - b[i][j] = d[i][j]; - } - } - return; -} -/*********************************************************************/ - -void tmat_trans ( float a[4][4], float b[4][4], float x, float y, - float z ) - -/*********************************************************************/ - -/* - Purpose: - - TMAT_TRANS applies a translation to the geometric transformation matrix. - - Modified: - - 19 October 1998 - - Author: - - John Burkardt - - Reference: - - Foley, van Dam, Feiner, Hughes, - Computer Graphics, Principles and Practice, - Addison Wesley, Second Edition, 1990. - - Parameters: - - Input, float A[4][4], the current geometric transformation matrix. - - Output, float B[4][4], the modified transformation matrix. - A and B may share the same memory. - - Input, float X, Y, Z, the translation. This may be thought of as the - point that the origin moves to under the translation. -*/ -{ - int i; - int j; - - for ( i = 0; i < 4; i++ ) { - for ( j = 0; j < 4; j++ ) { - b[i][j] = a[i][j]; - } - } - b[0][3] = b[0][3] + x; - b[1][3] = b[1][3] + y; - b[2][3] = b[2][3] + z; - - return; -} -/******************************************************************************/ - -int tria_read ( FILE *filein ) - -/******************************************************************************/ - -/* - Purpose: - - TRIA_READ reads an ASCII triangle file. - - Example: - - 12 <-- Number of triangles - - (x,y,z) and (nx,ny,nz) of normal vector at: - - 0.0 0.0 0.0 0.3 0.3 0.3 node 1 of triangle 1. - 1.0 0.0 0.0 0.3 0.1 0.3 node 2 of triangle 1, - 0.0 1.0 0.0 0.3 0.1 0.3 node 3 of triangle 1, - 1.0 0.5 0.0 0.3 0.1 0.3 node 1 of triangle 2, - ... - 0.0 0.5 0.5 0.3 0.1 0.3 node 3 of triangle 12. - - Modified: - - 22 June 1999 - - Author: - - John Burkardt -*/ -{ - float cvec[3]; - int icor3; - int iface; - int iface_hi; - int iface_lo; - int ivert; - int face_num2; - float r1; - float r2; - float r3; - float r4; - float r5; - float r6; -/* - Get the number of triangles. -*/ - fgets ( input, LINE_MAX_LEN, filein ); - text_num = text_num + 1; - sscanf ( input, "%d", &face_num2 ); -/* - For each triangle: -*/ - iface_lo = face_num; - iface_hi = face_num + face_num2; - - for ( iface = iface_lo; iface < iface_hi; iface++ ) { - - if ( iface < FACE_MAX ) { - face_order[iface] = 3; - face_material[iface] = 0; - } -/* - For each face: -*/ - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - - fgets ( input, LINE_MAX_LEN, filein ); - text_num = text_num + 1; - sscanf ( input, "%e %e %e %e %e %e", &r1, &r2, &r3, &r4, &r5, &r6 ); - - cvec[0] = r1; - cvec[1] = r2; - cvec[2] = r3; - - if ( cor3_num < 1000 ) { - icor3 = rcol_find ( cor3, 3, cor3_num, cvec ); - } - else { - icor3 = -1; - } - - if ( icor3 == -1 ) { - icor3 = cor3_num; - if ( cor3_num < COR3_MAX ) { - cor3[0][cor3_num] = cvec[0]; - cor3[1][cor3_num] = cvec[1]; - cor3[2][cor3_num] = cvec[2]; - } - cor3_num = cor3_num + 1; - } - else { - dup_num = dup_num + 1; - } - - if ( iface < FACE_MAX ) { - - face[ivert][iface] = icor3; - vertex_material[ivert][iface] = 0; - vertex_normal[0][ivert][iface] = r4; - vertex_normal[1][ivert][iface] = r5; - vertex_normal[2][ivert][iface] = r6; - } - - } - } - face_num = face_num + face_num2; - - return SUCCESS; -} -/**********************************************************************/ - -int tria_write ( FILE *fileout ) - -/**********************************************************************/ - -/* - Purpose: - - TRIA_WRITE writes the graphics data to an ASCII "triangle" file. - - Discussion: - - This is just a private format that Greg Hood requested from me. - - Example: - - 12 <-- Number of triangles - - (x,y,z) and (nx,ny,nz) of normal vector at: - - 0.0 0.0 0.0 0.3 0.3 0.3 node 1 of triangle 1. - 1.0 0.0 0.0 0.3 0.1 0.3 node 2 of triangle 1, - 0.0 1.0 0.0 0.3 0.1 0.3 node 3 of triangle 1, - 1.0 0.5 0.0 0.3 0.1 0.3 node 1 of triangle 2, - ... - 0.0 0.5 0.5 0.3 0.1 0.3 node 3 of triangle 12. - - Modified: - - 10 June 1999 - - Author: - - John Burkardt -*/ -{ - int face2[3]; - int icor3; - int iface; - int jlo; - int k; - int face_num2; - int text_num; - float nx; - float ny; - float nz; - float x; - float y; - float z; - - text_num = 0; -/* - Determine the number of triangular faces. -*/ - face_num2 = 0; - for ( iface = 0; iface < face_num; iface++ ) { - for ( jlo = 0; jlo < face_order[iface] - 2; jlo ++ ) { - face_num2 = face_num2 + 1; - } - } - - fprintf ( fileout, "%d\n", face_num2 ); - text_num = text_num + 1; -/* - Do the next face. -*/ - for ( iface = 0; iface < face_num; iface++ ) { -/* - Break the face up into triangles, anchored at node 1. -*/ - for ( jlo = 0; jlo < face_order[iface] - 2; jlo ++ ) { - - face2[0] = face[ 0][iface]; - face2[1] = face[jlo+1][iface]; - face2[2] = face[jlo+2][iface]; - - for ( k = 0; k < 3; k++ ) { - - icor3 = face2[k]; - - x = cor3[0][icor3]; - y = cor3[1][icor3]; - z = cor3[2][icor3]; - - nx = cor3_normal[0][icor3]; - ny = cor3_normal[1][icor3]; - nz = cor3_normal[2][icor3]; - - fprintf ( fileout, "%f %f %f %f %f %f\n", x, y, z, nx, ny, nz ); - - text_num = text_num + 1; - - } - - } - - } -/* - Report. -*/ - printf ( "\n" ); - printf ( "TRIA_WRITE - Wrote %d text lines.\n", text_num ); - - return SUCCESS; -} -/******************************************************************************/ - -int trib_read ( FILE *filein ) - -/******************************************************************************/ - -/* - Purpose: - - TRIB_READ reads a binary triangle file. - - Example: - - 4 byte int = number of triangles - - For each triangular face: - - 3 4-byte floats = coordinates of first node; - 3 4-byte floats = components of normal vector at first node; - 3 4-byte floats = coordinates of second node; - 3 4-byte floats = components of normal vector at second node; - 3 4-byte floats = coordinates of third node; - 3 4-byte floats = components of normal vector at third node. - - Modified: - - 22 June 1999 - - Author: - - John Burkardt -*/ -{ - float cvec[3]; - int icor3; - int i; - int iface; - int iface_hi; - int iface_lo; - int ivert; - int face_num2; -/* - Read the number of triangles in the file. -*/ - face_num2 = long_int_read ( filein ); - bytes_num = bytes_num + 4; -/* - For each (triangular) face, - read the coordinates and normal vectors of three vertices, -*/ - iface_lo = face_num; - iface_hi = face_num + face_num2; - - for ( iface = iface_lo; iface < iface_hi; iface++ ) { - - if ( iface < FACE_MAX ) { - face_order[iface] = 3; - face_material[iface] = 0; - } - - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - - for ( i = 0; i < 3; i++ ) { - cvec[i] = float_read ( filein ); - bytes_num = bytes_num + 4; - } - - if ( cor3_num < 1000 ) { - icor3 = rcol_find ( cor3, 3, cor3_num, cvec ); - } - else { - icor3 = -1; - } - - if ( icor3 == -1 ) { - icor3 = cor3_num; - if ( cor3_num < COR3_MAX ) { - cor3[0][cor3_num] = cvec[0]; - cor3[1][cor3_num] = cvec[1]; - cor3[2][cor3_num] = cvec[2]; - } - cor3_num = cor3_num + 1; - } - else { - dup_num = dup_num + 1; - } - - if ( iface < FACE_MAX ) { - - face[ivert][iface] = icor3; - vertex_material[ivert][iface] = 0; - - for ( i = 0; i < 3; i++ ) { - vertex_normal[i][ivert][iface] = float_read ( filein ); - bytes_num = bytes_num + 4; - } - - } - - } - } - - face_num = face_num + face_num2; - - return SUCCESS; -} -/**********************************************************************/ - -int trib_write ( FILE *fileout ) - -/**********************************************************************/ - -/* - Purpose: - - TRIB_WRITE writes the graphics data to a binary "triangle" file. - - Discussion: - - This is just a private format that Greg Hood requested from me. - - Example: - - 12 Number of triangles - 0.0 x at node 1, triangle 1, - 0.0 y at node 1, triangle 1, - 0.0 z at node 1, triangle 1, - 0.3 nx at node 1, triangle 1, - 0.3 ny at node 1, triangle 1, - 0.3 nz at node 1, triangle 1. - 1.0 x at node 2, triangle 1, - ... - 0.7 nz at node 3, triangle 1. - 1.2 x at node 1, triangle 2, - ... - 0.3 nz at node 3, triangle 2. - 9.3 x at node 1, triangle 3, - ... - 0.3 nz at node 3, triangle 12. - - Modified: - - 16 June 1999 - - Author: - - John Burkardt -*/ -{ - int face2[3]; - int icor3; - int iface; - int jlo; - int k; - int face_num2; - float nx; - float ny; - float nz; - float x; - float y; - float z; - - bytes_num = 0; -/* - Determine the number of triangular faces. -*/ - face_num2 = 0; - for ( iface = 0; iface < face_num; iface++ ) { - for ( jlo = 0; jlo < face_order[iface] - 2; jlo ++ ) { - face_num2 = face_num2 + 1; - } - } - - bytes_num = bytes_num + long_int_write ( fileout, face_num2 ); -/* - Do the next face. -*/ - for ( iface = 0; iface < face_num; iface++ ) { -/* - Break the face up into triangles, anchored at node 1. -*/ - for ( jlo = 0; jlo < face_order[iface] - 2; jlo ++ ) { - - face2[0] = face[ 0][iface]; - face2[1] = face[jlo+1][iface]; - face2[2] = face[jlo+2][iface]; - - for ( k = 0; k < 3; k++ ) { - - icor3 = face2[k]; - - x = cor3[0][icor3]; - y = cor3[1][icor3]; - z = cor3[2][icor3]; - - nx = cor3_normal[0][icor3]; - ny = cor3_normal[1][icor3]; - nz = cor3_normal[2][icor3]; - - bytes_num = bytes_num + float_write ( fileout, x ); - bytes_num = bytes_num + float_write ( fileout, y ); - bytes_num = bytes_num + float_write ( fileout, z ); - bytes_num = bytes_num + float_write ( fileout, nx ); - bytes_num = bytes_num + float_write ( fileout, ny ); - bytes_num = bytes_num + float_write ( fileout, nz ); - - } - - } - - } -/* - Report. -*/ - printf ( "\n" ); - printf ( "TRIB_WRITE - Wrote %d bytes.\n", bytes_num ); - - return SUCCESS; -} -/******************************************************************************/ - -int txt_write ( FILE *fileout ) - -/******************************************************************************/ - -/* - Purpose: - - TXT_WRITE writes the graphics data to a text file. - - Modified: - - 25 June 1998 - - Author: - - John Burkardt -*/ -{ - int i; - int iface; - int iline; - int imat; - int ivert; - int nitem; - int text_num; - - text_num = 0; - - fprintf ( fileout, "%s created by IVCON.\n", fileout_name ); - fprintf ( fileout, "Original data in %s.\n", filein_name ); - fprintf ( fileout, "Object name is %s.\n", object_name ); - fprintf ( fileout, "Object origin at %f %f %f.\n", origin[0], origin[1], - origin[2] ); - fprintf ( fileout, "Object pivot at %f %f %f.\n", pivot[0], pivot[1], - pivot[2] ); - text_num = text_num + 5; -/* - TRANSFORMATION MATRIX. -*/ - fprintf ( fileout, "\n" ); - fprintf ( fileout, "Transformation matrix:\n" ); - fprintf ( fileout, "\n" ); - text_num = text_num + 3; - - for ( i = 0; i < 4; i++ ) { - fprintf ( fileout, " %f %f %f %f\n", transform_matrix[i][0], - transform_matrix[i][1], transform_matrix[i][2], transform_matrix[i][3] ); - text_num = text_num + 1; - } -/* - NODES. -*/ - fprintf ( fileout, "\n" ); - fprintf ( fileout, " %d nodes.\n", cor3_num ); - text_num = text_num + 2; - - if ( cor3_num > 0 ) { - - fprintf ( fileout, "\n" ); - fprintf ( fileout, " Node coordinate data:\n" ); - fprintf ( fileout, "\n" ); - text_num = text_num + 3; - - for ( i = 0; i < cor3_num; i++ ) { - fprintf ( fileout, " %d %f %f %f\n ", i, cor3[0][i], cor3[1][i], - cor3[2][i] ); - text_num = text_num + 1; - } - - fprintf ( fileout, "\n" ); - fprintf ( fileout, " Node normal vectors:\n" ); - fprintf ( fileout, "\n" ); - text_num = text_num + 3; - - for ( i = 0; i < cor3_num; i++ ) { - fprintf ( fileout, " %d %f %f %f\n ", i, cor3_normal[0][i], - cor3_normal[1][i], cor3_normal[2][i] ); - text_num = text_num + 1; - } - - fprintf ( fileout, "\n" ); - fprintf ( fileout, " Node materials:\n" ); - fprintf ( fileout, "\n" ); - text_num = text_num + 3; - - for ( i = 0; i < cor3_num; i++ ) { - fprintf ( fileout, " %d %d\n ", i, cor3_material[i] ); - text_num = text_num + 1; - } - - if ( texture_num > 0 ) { - fprintf ( fileout, "\n" ); - fprintf ( fileout, " Node texture coordinates:\n" ); - fprintf ( fileout, "\n" ); - text_num = text_num + 3; - - for ( i = 0; i < cor3_num; i++ ) { - fprintf ( fileout, " %d %f %f\n ", i, cor3_tex_uv[0][i], - cor3_tex_uv[1][i] ); - text_num = text_num + 1; - } - } - } -/* - LINES. -*/ - fprintf ( fileout, "\n" ); - fprintf ( fileout, " %d line data items.\n", line_num ); - text_num = text_num + 2; - - if ( line_num > 0 ) { - - fprintf ( fileout, "\n" ); - fprintf ( fileout, " Line index data:\n" ); - fprintf ( fileout, "\n" ); - text_num = text_num + 3; - - nitem = 0; - - for ( iline = 0; iline < line_num; iline++ ) { - - fprintf ( fileout, " %d", line_dex[iline] ); - nitem = nitem + 1; - - if ( iline == line_num - 1 || line_dex[iline] == -1 || nitem >= 10 ) { - nitem = 0; - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - } - - } - - fprintf ( fileout, "\n" ); - fprintf ( fileout, " Line materials:\n" ); - fprintf ( fileout, "\n" ); - text_num = text_num + 3; - - nitem = 0; - - for ( iline = 0; iline < line_num; iline++ ) { - - fprintf ( fileout, " %d", line_material[iline] ); - nitem = nitem + 1; - - if ( iline == line_num - 1 || line_material[iline] == -1 || nitem >= 10 ) { - nitem = 0; - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - } - } - - } -/* - COLOR DATA -*/ - fprintf ( fileout, "\n" ); - fprintf ( fileout, " %d colors.\n", color_num ); - text_num = text_num + 2; -/* - FACES. -*/ - fprintf ( fileout, "\n" ); - fprintf ( fileout, " %d faces.\n", face_num ); - text_num = text_num + 2; - - if ( face_num > 0 ) { - - fprintf ( fileout, "\n" ); - fprintf ( fileout, " Face, Material, Number of vertices, Smoothing, Flags:\n" ); - fprintf ( fileout, "\n" ); - text_num = text_num + 3; - - for ( iface = 0; iface < face_num; iface++ ) { - fprintf ( fileout, " %d %d %d %d %d\n", iface, face_material[iface], - face_order[iface], face_smooth[iface], face_flags[iface] ); - text_num = text_num + 1; - } - - fprintf ( fileout, "\n" ); - fprintf ( fileout, " Face, Vertices\n" ); - fprintf ( fileout, "\n" ); - text_num = text_num + 3; - - for ( iface = 0; iface < face_num; iface++ ) { - - fprintf ( fileout, "%d ", iface ); - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - fprintf ( fileout, " %d", face[ivert][iface] ); - } - - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - } - - fprintf ( fileout, "\n" ); - fprintf ( fileout, " Face normal vectors:\n" ); - fprintf ( fileout, "\n" ); - text_num = text_num + 3; - - for ( iface = 0; iface < face_num; iface++ ) { - fprintf ( fileout, " %d %f %f %f\n", iface, face_normal[0][iface], - face_normal[1][iface], face_normal[2][iface] ); - text_num = text_num + 1; - } - - if ( texture_num > 0 ) { - - fprintf ( fileout, "\n" ); - fprintf ( fileout, " Face texture coordinates:\n" ); - fprintf ( fileout, "\n" ); - text_num = text_num + 3; - - for ( iface = 0; iface < face_num; iface++ ) { - fprintf ( fileout, " %d %f %f\n", iface, face_tex_uv[0][iface], - face_tex_uv[1][iface] ); - text_num = text_num + 1; - } - } - } -/* - VERTICES. -*/ - if ( face_num > 0 ) { - - fprintf ( fileout, "\n" ); - fprintf ( fileout, "Vertex normal vectors:\n" ); - text_num = text_num + 2; - - for ( iface = 0; iface < face_num; iface++ ) { - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - fprintf ( fileout, " %d %d %f %f %f\n", iface, ivert, - vertex_normal[0][ivert][iface], vertex_normal[1][ivert][iface], - vertex_normal[2][ivert][iface] ); - text_num = text_num + 1; - } - } - - fprintf ( fileout, "\n" ); - fprintf ( fileout, "Vertex materials:\n" ); - fprintf ( fileout, "\n" ); - text_num = text_num + 3; - - for ( iface = 0; iface < face_num; iface++ ) { - fprintf ( fileout, "%d", iface ); - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - fprintf ( fileout, " %d", vertex_material[ivert][iface] ); - } - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - } - - if ( texture_num > 0 ) { - - fprintf ( fileout, "\n" ); - fprintf ( fileout, "Vertex UV texture coordinates:\n" ); - fprintf ( fileout, "\n" ); - text_num = text_num + 3; - - for ( iface = 0; iface < face_num; iface++ ) { - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - fprintf ( fileout, "%d %d %f %f\n", iface, ivert, - vertex_tex_uv[0][ivert][iface], vertex_tex_uv[1][ivert][iface] ); - text_num = text_num + 1; - } - } - } - } -/* - MATERIALS. -*/ - fprintf ( fileout, "\n" ); - fprintf ( fileout, "%d materials.\n", material_num ); - fprintf ( fileout, "\n" ); - fprintf ( fileout, "Index Name R G B A\n" ); - fprintf ( fileout, "\n" ); - - text_num = text_num + 5; - - for ( imat = 0; imat < material_num; imat++ ) { - fprintf ( fileout, "%d %s %f %f %f %f\n", imat, material_name[imat], - material_rgba[0][imat], material_rgba[1][imat], material_rgba[2][imat], - material_rgba[3][imat] ); - text_num = text_num + 1; - } -/* - TEXTURES. -*/ - fprintf ( fileout, "\n" ); - fprintf ( fileout, "%d textures.\n", texture_num ); - text_num = text_num + 2; - - if ( texture_num > 0 ) { - fprintf ( fileout, "\n" ); - fprintf ( fileout, "Index Name\n" ); - fprintf ( fileout, "\n" ); - for ( i = 0; i < texture_num; i++ ) { - fprintf ( fileout, "%d %s\n", i, texture_name[i] ); - } - text_num = text_num + 3; - } -/* - Report. -*/ - printf ( "\n" ); - printf ( "TXT_WRITE - Wrote %d text lines.\n", text_num ); - - return SUCCESS; -} -/**********************************************************************/ - -int ucd_write ( FILE *fileout ) - -/**********************************************************************/ - -/* - Purpose: - - UCD_WRITE writes graphics data to an AVS UCD file. - - Examples: - - # cube.ucd created by IVREAD. - # - # Material RGB to hue map: - # - # material R G B Alpha Hue - # - # 0 0.94 0.70 0.15 1.000 0.116 - # 1 0.24 0.70 0.85 1.000 0.541 - # 2 0.24 0.00 0.85 1.000 0.666 - # - # The node data is - # node # / material # / RGBA / Hue - # - 8 6 6 0 0 - 0 0.0 0.0 0.0 - 1 1.0 0.0 0.0 - 2 1.0 1.0 0.0 - 3 0.0 1.0 0.0 - 4 0.0 0.0 1.0 - 5 1.0 0.0 1.0 - 6 1.0 1.0 1.0 - 7 0.0 1.0 1.0 - 0 0 quad 0 1 2 3 - 1 0 quad 0 4 5 1 - 2 0 quad 1 5 6 2 - 3 0 quad 2 6 7 3 - 4 0 quad 3 7 4 0 - 5 0 quad 4 7 6 5 - 3 1 4 1 - material, 0...2 - RGBA, 0-1/0-1/0-1/0-1 - Hue, 0-1 - 0 0 0.94 0.70 0.15 1.0 0.116 - 1 0 0.94 0.70 0.15 1.0 0.116 - 2 0 0.94 0.70 0.15 1.0 0.116 - 3 0 0.94 0.70 0.15 1.0 0.116 - 4 1 0.24 0.70 0.85 1.0 0.541 - 5 1 0.24 0.70 0.85 1.0 0.541 - 6 2 0.24 0.24 0.85 0.0 0.666 - 7 2 0.24 0.24 0.85 0.0 0.666 - - Modified: - - 22 May 1999 - - Author: - - John Burkardt - -*/ -{ - float a; - float b; - float g; - float h; - int i; - int imat; - int j; - int text_num; - float r; - - text_num = 0; - - fprintf ( fileout, "# %s created by IVREAD.\n", fileout_name ); - fprintf ( fileout, "#\n" ); - fprintf ( fileout, "# Material RGB to Hue map:\n" ); - fprintf ( fileout, "#\n" ); - fprintf ( fileout, "# material R G B Alpha Hue\n" ); - fprintf ( fileout, "#\n" ); - - text_num = text_num + 6; - - for ( j = 0; j < material_num; j++ ) { - r = material_rgba[0][j]; - g = material_rgba[1][j]; - b = material_rgba[2][j]; - a = material_rgba[3][j]; - h = rgb_to_hue ( r, g, b ); - fprintf ( fileout, "# %d %f %f %f %f %f\n", j, r, g, b, a, h ); - text_num = text_num + 1; - } - - fprintf ( fileout, "#\n" ); - fprintf ( fileout, "# The node data is\n" ); - fprintf ( fileout, "# node # / material # / RGBA / Hue\n" ); - fprintf ( fileout, "#\n" ); - text_num = text_num + 4; - - fprintf ( fileout, "%d %d 6 0 0\n", cor3_num, face_num ); - text_num = text_num + 1; - - for ( j = 0; j < cor3_num; j++ ) { - fprintf ( fileout, "%d %f %f %f\n", j, cor3[0][j], cor3[1][j], - cor3[2][j] ); - text_num = text_num + 1; - } -/* - NOTE: - UCD only accepts triangles and quadrilaterals, not higher order - polygons. We would need to break polygons up to proceed. -*/ - for ( j = 0; j < face_num; j++ ) { - - fprintf ( fileout, "%d %d", j, face_material[j] ); - - if ( face_order[j] == 3 ) { - fprintf ( fileout, " tri" ); - } - else if ( face_order[j] == 4 ) { - fprintf ( fileout, " quad" ); - } - else { - fprintf ( fileout, " ???" ); - } - - for ( i = 0; i < face_order[j]; i++ ) { - fprintf ( fileout, "%d", face[i][j] ); - } - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - - } - - fprintf ( fileout, "3 1 4 1\n" ); - fprintf ( fileout, "material, 0...%d\n", material_num - 1 ); - fprintf ( fileout, "RGBA, 0-1/0-1/0-1/0-1\n" ); - fprintf ( fileout, "Hue, 0-1\n" ); - text_num = text_num + 4; - - for ( j = 0; j < cor3_num; j++ ) { - imat = cor3_material[j]; - r = material_rgba[0][imat]; - g = material_rgba[1][imat]; - b = material_rgba[2][imat]; - a = material_rgba[3][imat]; - h = rgb_to_hue ( r, g, b ); - - fprintf ( fileout, "%d %d %f %f %f %f %f\n", j, imat, r, g, b, a, h ); - text_num = text_num + 1; - } -/* - Report. -*/ - printf ( "\n" ); - printf ( "UCD_WRITE - Wrote %d text lines.\n", text_num ); - - return SUCCESS; -} -/******************************************************************************/ - -void vertex_normal_set ( void ) - -/******************************************************************************/ - -/* - Purpose: - - VERTEX_NORMAL_SET recomputes the face vertex normal vectors. - - Modified: - - 12 October 1998 - - Author: - - John Burkardt -*/ -{ - int i; - int i0; - int i1; - int i2; - int iface; - int ivert; - int jp1; - int jp2; - int nfix; - float norm; - float temp; - float x0; - float x1; - float x2; - float xc; - float y0; - float y1; - float y2; - float yc; - float z0; - float z1; - float z2; - float zc; - - if ( face_num <= 0 ) { - return; - } - - nfix = 0; -/* - Consider each face. -*/ - for ( iface = 0; iface < face_num; iface++ ) { - - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - - norm = 0.0; - for ( i = 0; i < 3; i++ ) { - temp = vertex_normal[i][ivert][iface]; - norm = norm + temp * temp; - } - norm = ( float ) sqrt ( norm ); - - if ( norm == 0.0 ) { - - nfix = nfix + 1; - - i0 = face[ivert][iface]; - x0 = cor3[0][i0]; - y0 = cor3[1][i0]; - z0 = cor3[2][i0]; - - jp1 = ivert + 1; - if ( jp1 >= face_order[iface] ) { - jp1 = jp1 - face_order[iface]; - } - i1 = face[jp1][iface]; - x1 = cor3[0][i1]; - y1 = cor3[1][i1]; - z1 = cor3[2][i1]; - - jp2 = ivert + 2; - if ( jp2 >= face_order[iface] ) { - jp2 = jp2 - face_order[iface]; - } - i2 = face[jp2][iface]; - x2 = cor3[0][i2]; - y2 = cor3[1][i2]; - z2 = cor3[2][i2]; - - xc = ( y1 - y0 ) * ( z2 - z0 ) - ( z1 - z0 ) * ( y2 - y0 ); - yc = ( z1 - z0 ) * ( x2 - x0 ) - ( x1 - x0 ) * ( z2 - z0 ); - zc = ( x1 - x0 ) * ( y2 - y0 ) - ( y1 - y0 ) * ( x2 - x0 ); - - norm = ( float ) sqrt ( xc * xc + yc * yc + zc * zc ); - - if ( norm == 0.0 ) { - xc = ( float ) 1.0 / sqrt ( 3.0 ); - yc = ( float ) 1.0 / sqrt ( 3.0 ); - zc = ( float ) 1.0 / sqrt ( 3.0 ); - } - else { - xc = xc / norm; - yc = yc / norm; - zc = zc / norm; - } - - vertex_normal[0][ivert][iface] = xc; - vertex_normal[1][ivert][iface] = yc; - vertex_normal[2][ivert][iface] = zc; - - } - } - } - - if ( nfix > 0 ) { - printf ( "\n" ); - printf ( "VERTEX_NORMAL_SET: Recomputed %d face vertex normals.\n", nfix ); - } - - return; -} -/**********************************************************************/ - -void vertex_to_face_material ( void ) - -/**********************************************************************/ - -/* - Purpose: - - VERTEX_TO_FACE_MATERIAL extends vertex material definitions to faces. - - Discussion: - - Assuming material indices are defined for all the vertices, this - routine assigns to each face the material associated with its - first vertex. - - Modified: - - 22 May 1999 - - Author: - - John Burkardt -*/ -{ - int iface; - int ivert; - - ivert = 0; - for ( iface = 0; iface < face_num; iface++ ) { - face_material[iface] = vertex_material[ivert][iface]; - } - - return; -} -/**********************************************************************/ - -void vertex_to_node_material ( void ) - -/**********************************************************************/ - -/* - Purpose: - - VERTEX_TO_NODE_MATERIAL extends vertex material definitions to nodes. - - Discussion: - - A NODE is a point in space. - A VERTEX is a node as used in a particular face. - One node may be used as a vertex in several faces, or none. - This routine simply runs through all the vertices, and assigns - the material of the vertex to the corresponding node. If a - node appears as a vertex several times, then the node will - end up having the material of the vertex that occurs "last". - - Modified: - - 22 May 1999 - - Author: - - John Burkardt -*/ -{ - int iface; - int ivert; - int node; - - for ( iface = 0; iface < face_num; iface++ ) { - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - node = face[ivert][iface]; - cor3_material[node] = vertex_material[ivert][iface]; - } - } - - return; -} - -/******************************************************************************/ - -int vla_read ( FILE *filein ) - -/******************************************************************************/ - -/* - Purpose: - - VLA_READ reads a VLA file. - - Examples: - - set comment cube.vla created by IVREAD - set comment Original data in cube.iv. - set comment - set intensity EXPLICIT - set parametric NON_PARAMETRIC - set filecontent LINES - set filetype NEW - set depthcue 0 - set defaultdraw stellar - set coordsys RIGHT - set author IVREAD - set site Buhl Planetarium - set library_id UNKNOWN - P 8.59816 5.55317 -3.05561 1.00000 - L 8.59816 2.49756 0.000000E+00 1.00000 - L 8.59816 2.49756 -3.05561 1.00000 - L 8.59816 5.55317 -3.05561 1.00000 - P 8.59816 5.55317 0.000000E+00 1.00000 - ...etc... - L 2.48695 2.49756 -3.05561 1.00000 - - Modified: - - 23 May 1999 - - Author: - - John Burkardt -*/ -{ - int i; - int icor3; - int dup_num; - char *next; - int text_num; - float r1; - float r2; - float r3; - float temp[3]; - char token[LINE_MAX_LEN]; - int width; -/* - Initialize. -*/ - dup_num = 0; - text_num = 0; -/* - Read the next line of the file into INPUT. -*/ - while ( fgets ( input, LINE_MAX_LEN, filein ) != NULL ) { - - text_num = text_num + 1; -/* - Advance to the first nonspace character in INPUT. -*/ - for ( next = input; *next != '\0' && isspace(*next); next++ ) { - } -/* - Skip blank lines and comments. -*/ - if ( *next == '\0' || *next == ';' ) { - continue; - } -/* - Extract the first word in this line. -*/ - sscanf ( next, "%s%n", token, &width ); -/* - Set NEXT to point to just after this token. -*/ - next = next + width; -/* - SET (ignore) -*/ - if ( leqi ( token, "set" ) == TRUE ) { - } -/* - P (begin a line) - L (continue a line) -*/ - else if ( leqi ( token, "P" ) == TRUE || leqi ( token, "L") == TRUE ) { - - if ( leqi ( token, "P" ) == TRUE ) { - if ( line_num > 0 ) { - if ( line_num < LINES_MAX ) { - line_dex[line_num] = -1; - line_material[line_num] = -1; - line_num = line_num + 1; - } - } - } - - sscanf ( next, "%e %e %e", &r1, &r2, &r3 ); - - temp[0] = r1; - temp[1] = r2; - temp[2] = r3; - - if ( cor3_num < 1000 ) { - icor3 = rcol_find ( cor3, 3, cor3_num, temp ); - } - else { - icor3 = -1; - } - - if ( icor3 == -1 ) { - - icor3 = cor3_num; - - if ( cor3_num < COR3_MAX ) { - for ( i = 0; i < 3; i++ ) { - cor3[i][cor3_num] = temp[i]; - } - } - cor3_num = cor3_num + 1; - } - else { - dup_num = dup_num + 1; - } - - if ( line_num < LINES_MAX ) { - line_dex[line_num] = icor3; - line_material[line_num] = 0; - line_num = line_num + 1; - } - } -/* - Unexpected or unrecognized. -*/ - else { - printf ( "\n" ); - printf ( "VLA_READ - Fatal error!\n" ); - printf ( " Unrecognized first word on line.\n" ); - return ERROR; - } - - } - - if ( line_num > 0 ) { - if ( line_num < LINES_MAX ) { - line_dex[line_num] = -1; - line_material[line_num] = -1; - line_num = line_num + 1; - } - } - - return SUCCESS; -} -/******************************************************************************/ - -int vla_write ( FILE *fileout ) - -/******************************************************************************/ - -/* - Purpose: - - VLA_WRITE writes internal graphics information to a VLA file. - - Discussion: - - Comments begin with a semicolon in column 1. - The X, Y, Z coordinates of points begin with a "P" to - denote the beginning of a line, and "L" to denote the - continuation of a line. The fourth entry is intensity, which - should be between 0.0 and 1.0. - - Examples: - - set comment cube.vla created by IVREAD - set comment Original data in cube.iv. - set comment - set intensity EXPLICIT - set parametric NON_PARAMETRIC - set filecontent LINES - set filetype NEW - set depthcue 0 - set defaultdraw stellar - set coordsys RIGHT - set author IVREAD - set site Buhl Planetarium - set library_id UNKNOWN - P 8.59816 5.55317 -3.05561 1.00000 - L 8.59816 2.49756 0.000000E+00 1.00000 - L 8.59816 2.49756 -3.05561 1.00000 - L 8.59816 5.55317 -3.05561 1.00000 - P 8.59816 5.55317 0.000000E+00 1.00000 - ...etc... - L 2.48695 2.49756 -3.05561 1.00000 - - Modified: - - 22 May 1999 - - Author: - - John Burkardt -*/ -{ - char c; - int iline; - float intense = 1.0; - int k; - int text_num; -/* - Initialize. -*/ - text_num = 0; - - fprintf ( fileout, "set comment %s created by IVCON.\n", fileout_name ); - fprintf ( fileout, "set comment Original data in %s.\n", filein_name ); - fprintf ( fileout, "set comment\n" ); - fprintf ( fileout, "set intensity EXPLICIT\n" ); - fprintf ( fileout, "set parametric NON_PARAMETRIC\n" ); - fprintf ( fileout, "set filecontent LINES\n" ); - fprintf ( fileout, "set filetype NEW\n" ); - fprintf ( fileout, "set depthcue 0\n" ); - fprintf ( fileout, "set defaultdraw stellar\n" ); - fprintf ( fileout, "set coordsys RIGHT\n" ); - fprintf ( fileout, "set author IVCON\n" ); - fprintf ( fileout, "set site Buhl Planetarium\n" ); - fprintf ( fileout, "set library_id UNKNOWN\n" ); - - text_num = text_num + 13; - - c = 'P'; - - for ( iline = 0; iline < line_num; iline++ ) { - - k = line_dex[iline]; - - if ( k == -1 ) { - - c = 'P'; - } - else { - - fprintf ( fileout, "%c %f %f %f %f\n", - c, cor3[0][k], cor3[1][k], cor3[2][k], intense ); - - text_num = text_num + 1; - - c = 'L'; - } - } -/* - Report. -*/ - printf ( "\n" ); - printf ( "VLA_WRITE - Wrote %d text lines.\n", text_num ); - - - return SUCCESS; -} - -/**********************************************************************/ - -int wrl_write ( FILE *fileout ) - -/**********************************************************************/ - -/* - Purpose: - - WRL_WRITE writes graphics data to a WRL file. - - Example: - - #VRML V2.0 utf8 - - WorldInfo { - title "cube.iv." - string "WRL file generated by IVREAD. - } - - Group { - children [ - - Shape { - - appearance Appearance { - material Material { - diffuseColor 0.0 0.0 0.0 - emissiveColor 0.0 0.0 0.0 - shininess 1.0 - } - } #end of appearance - - geometry IndexedLineSet { - - coord Coordinate { - point [ - 8.59816 5.55317 -3.05561 - 8.59816 2.49756 0.000000E+00 - ...etc... - 2.48695 2.49756 -3.05561 - ] - } - - coordIndex [ - 0 1 2 -1 3 4 5 6 7 8 - - 9 10 -1 11 12 -1 13 14 15 -1 1 - ...etc... - 191 -1 - ] - - colorPerVertex TRUE - - colorIndex [ - 0 0 0 -1 2 3 1 1 4 7 - - 10 9 -1 7 7 -1 3 2 2 -1 1 - ...etc... - 180 -1 - ] - - } #end of geometry - - } #end of Shape - - ] #end of children - - } #end of Group - - Modified: - - 23 May 1999 - - Author: - - John Burkardt -*/ -{ - int icor3; - int iface; - int itemp; - int ivert; - int j; - int length; - int ndx; - - text_num = 0; - - fprintf ( fileout, "#VRML V2.0 utf8\n" ); - fprintf ( fileout, "\n" ); - fprintf ( fileout, " WorldInfo {\n" ); - fprintf ( fileout, " title \"%s\"\n", fileout_name ); - fprintf ( fileout, " info \"WRL file generated by IVREAD.\"\n" ); - fprintf ( fileout, " info \"Original data in %s\"\n", filein_name ); - fprintf ( fileout, " }\n" ); - fprintf ( fileout, "\n" ); - fprintf ( fileout, " Group {\n" ); - fprintf ( fileout, " children [\n" ); - fprintf ( fileout, " Shape {\n" ); - fprintf ( fileout, " appearance Appearance {\n" ); - fprintf ( fileout, " material Material {\n" ); - fprintf ( fileout, " diffuseColor 0.0 0.0 0.0\n" ); - fprintf ( fileout, " emissiveColor 0.0 0.0 0.0\n" ); - fprintf ( fileout, " shininess 1.0\n" ); - fprintf ( fileout, " }\n" ); - fprintf ( fileout, " }\n" ); - - text_num = text_num + 18; -/* - IndexedLineSet -*/ - if ( line_num > 0 ) { - - fprintf ( fileout, " geometry IndexedLineSet {\n" ); -/* - IndexedLineSet coord -*/ - fprintf ( fileout, " coord Coordinate {\n" ); - fprintf ( fileout, " point [\n" ); - - text_num = text_num + 3; - - for ( icor3 = 0; icor3 < cor3_num; icor3++ ) { - fprintf ( fileout, " %f %f %f\n", cor3[0][icor3], - cor3[1][icor3], cor3[2][icor3] ); - text_num = text_num + 1; - } - - fprintf ( fileout, " ]\n" ); - fprintf ( fileout, " }\n" ); - text_num = text_num + 2; -/* - IndexedLineSet coordIndex. -*/ - fprintf ( fileout, " coordIndex [\n" ); - - text_num = text_num + 1; - - length = 0; - for ( j = 0; j < line_num; j++ ) { - fprintf ( fileout, "%d ", line_dex[j] ); - length = length + 1; - if ( line_dex[j] == -1 || length >= 10 || j == line_num - 1 ) { - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - length = 0; - } - } - - fprintf ( fileout, " ]\n" ); - text_num = text_num + 1; -/* - Colors. (materials) -*/ - fprintf ( fileout, " color Color {\n" ); - fprintf ( fileout, " color [\n" ); - text_num = text_num + 2; - - for ( j = 0; j < material_num; j++ ) { - fprintf ( fileout, " %f %f %f\n", material_rgba[0][j], - material_rgba[1][j], material_rgba[2][j] ); - text_num = text_num + 1; - } - - fprintf ( fileout, " ]\n" ); - fprintf ( fileout, " }\n" ); - fprintf ( fileout, " colorPerVertex TRUE\n" ); -/* - IndexedLineset colorIndex -*/ - fprintf ( fileout, " colorIndex [\n" ); - - text_num = text_num + 4; - - length = 0; - for ( j = 0; j < line_num; j++ ) { - fprintf ( fileout, "%d ", line_material[j] ); - length = length + 1; - if ( line_dex[j] == -1 || length >= 10 || j == line_num - 1 ) { - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - length = 0; - } - } - - fprintf ( fileout, " ]\n" ); - fprintf ( fileout, " }\n" ); - text_num = text_num + 2; - - } -/* - End of IndexedLineSet - - IndexedFaceSet -*/ - if ( face_num > 0 ) { - - fprintf ( fileout, " geometry IndexedFaceSet {\n" ); -/* - IndexedFaceSet coord -*/ - fprintf ( fileout, " coord Coordinate {\n" ); - fprintf ( fileout, " point [\n" ); - - text_num = text_num + 3; - - for ( icor3 = 0; icor3 < cor3_num; icor3++ ) { - fprintf ( fileout, " %f %f %f\n", cor3[0][icor3], - cor3[1][icor3], cor3[2][icor3] ); - - text_num = text_num + 1; - } - - fprintf ( fileout, " ]\n" ); - fprintf ( fileout, " }\n" ); -/* - IndexedFaceSet coordIndex. -*/ - fprintf ( fileout, " coordIndex [\n" ); - - text_num = text_num + 3; - - length = 0; - - for ( iface = 0; iface < face_num; iface++ ) { - - for ( ivert = 0; ivert <= face_order[iface]; ivert++ ) { - - if ( ivert <= face_order[iface] ) { - itemp = face[ivert][iface]; - } - else { - itemp = 0; - } - - fprintf ( fileout, "%d ", itemp ); - length = length + 1; - - if ( itemp == -1 || length >= 10 || - ( iface == face_num - 1 && ivert == face_order[iface] ) ) { - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - length = 0; - } - - } - - } - - fprintf ( fileout, " ]\n" ); - text_num = text_num + 1; -/* - IndexedFaceset colorIndex -*/ - fprintf ( fileout, " colorIndex [\n" ); - text_num = text_num + 1; - - length = 0; - ndx = 0; - - for ( iface = 0; iface < face_num; iface++ ) { - - for ( ivert = 0; ivert <= face_order[iface]; ivert++ ) { - - if ( ivert <= face_order[iface] ) { - itemp = vertex_material[ivert][iface]; - ndx = ndx + 1; - } - else { - itemp = 0; - } - - fprintf ( fileout, "%d ", itemp ); - length = length + 1; - - if ( itemp == -1 || length >= 10 || - ( iface == face_num - 1 && ivert == face_order[iface] ) ) { - - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - length = 0; - - } - - } - - } - - fprintf ( fileout, " ]\n" ); - fprintf ( fileout, " }\n" ); - text_num = text_num + 2; - - } -/* - End of IndexedFaceSet - - End of: - Shape - children - Group -*/ - fprintf ( fileout, " }\n" ); - fprintf ( fileout, " ]\n" ); - fprintf ( fileout, " }\n" ); - - text_num = text_num + 3; -/* - Report. -*/ - printf ( "\n" ); - printf ( "WRL_WRITE - Wrote %d text lines.\n", text_num ); - - return SUCCESS; -} -/******************************************************************************/ - -int xgl_write ( FILE *fileout ) - -/******************************************************************************/ - -/* - Purpose: - - XGL_WRITE writes an XGL file. - - Discussion: - - Two corrections to the routine were pointed out by - Mike Phillips, msphil@widowmaker.com, on 17 September 2001, - and are gratefully acknowledged. - - Example: - - - - - 0.1, 0.1, 0.1 - - - - 0.2, 0.1, 0.1 - - 0.1, 0.2, 0.1 - 0, 0, 100 - 0.1, 0.1, 0.2 - - - - - -

-0.5, -0.5, 1

-

0.5, -0.5, 1

-

0.5, 0.5, 1

-

-0.5, 0.5, 1

-

0.5, -0.5, 0

-

-0.5, -0.5, 0

-

-0.5, 0.5, 0

-

0.5, 0.5, 0

- - -0.408248, -0.408248, 0.816497 - 0.666667, -0.666667, 0.333333 - 0.408248, 0.408248, 0.816497 - -0.666667, 0.666667, 0.333333 - 0.408248, -0.408248, -0.816497 - -0.666667, -0.666667, -0.333333 - -0.408248, 0.408248, -0.816497 - 0.666667, 0.666667, -0.333333 - - - 0.9 - 0.1, 0.1, 0.1 - 0.2, 0.1, 0.1 - 0.1, 0.2, 0.1 - 0.8 - 0.1, 0.1, 0.2 - - - - 0 - 0 0 - 1 1 - 2 2 - - - 0 - 0 0 - 2 2 - 3 3 - - - 0 - 4 4 - 5 5 - 6 6 - - - 0 - 4 4 - 6 6 - 7 7 - - - 0 - 5 5 - 0 0 - 3 3 - - - 0 - 5 5 - 3 3 - 6 6 - - - 0 - 1 1 - 4 4 - 7 7 - - - 0 - 1 1 - 7 7 - 2 2 - - - 0 - 5 5 - 4 4 - 1 1 - - - 0 - 5 5 - 1 1 - 0 0 - - - 0 - 3 3 - 2 2 - 7 7 - - - 0 - 3 3 - 7 7 - 6 6 - -
- - - - 0, 0, 0 - 0, 0, 0 - 1, 1, 1 - 1, 1, 1 - - 0 - - -
- - Reference: - - XGL specification at http://www.xglspec.org/ - - Modified: - - 17 September 2001 - - Author: - - John Burkardt -*/ -{ - int iface; - int ivert; - int j; - float light_ambient_rgb[3]; - float light_diffuse_rgb[3]; - float light_direction[3]; - float light_specular_rgb[3]; - int material; - float material_alpha; - float material_amb_rgb[3]; - float material_diff_rgb[3]; - float material_emiss_rgb[3]; - float material_shine; - float material_spec_rgb[3]; - int mesh; - int mesh_num = 1; - int object; - float transform_forward[3]; - float transform_position[3]; - float transform_scale[3]; - float transform_up[3]; -/* - Make up some placeholder values for now. -*/ - light_ambient_rgb[0] = 0.2; - light_ambient_rgb[1] = 0.1; - light_ambient_rgb[2] = 0.1; - - light_diffuse_rgb[0] = 0.1; - light_diffuse_rgb[1] = 0.2; - light_diffuse_rgb[2] = 0.1; - - light_direction[0] = 0.0; - light_direction[1] = 0.0; - light_direction[2] = 100.0; - - light_specular_rgb[0] = 0.1; - light_specular_rgb[1] = 0.1; - light_specular_rgb[2] = 0.2; - - material_alpha = 0.9; - - material_amb_rgb[0] = 0.1; - material_amb_rgb[1] = 0.1; - material_amb_rgb[2] = 0.1; - - material_diff_rgb[0] = 0.2; - material_diff_rgb[1] = 0.1; - material_diff_rgb[2] = 0.1; - - material_emiss_rgb[0] = 0.1; - material_emiss_rgb[1] = 0.2; - material_emiss_rgb[2] = 0.1; - - material_shine = 0.8; - - material_spec_rgb[0] = 0.1; - material_spec_rgb[1] = 0.1; - material_spec_rgb[2] = 0.2; - - transform_forward[0] = 0.0; - transform_forward[1] = 0.0; - transform_forward[2] = 0.0; - - transform_position[0] = 0.0; - transform_position[1] = 0.0; - transform_position[2] = 0.0; - - transform_scale[0] = 1.0; - transform_scale[1] = 1.0; - transform_scale[2] = 1.0; - - transform_up[0] = 1.0; - transform_up[1] = 1.0; - transform_up[2] = 1.0; - - object_num = 1; - - text_num = 0; - - fprintf ( fileout, "\n" ); - fprintf ( fileout, "\n" ); - - text_num = text_num + 2; - - fprintf ( fileout, " \n" ); - fprintf ( fileout, " %f, %f, %f \n", - background_rgb[0], background_rgb[1], background_rgb[2] ); - fprintf ( fileout, " \n" ); - fprintf ( fileout, "\n" ); - fprintf ( fileout, " \n" ); - fprintf ( fileout, " %f, %f, %f \n", - light_ambient_rgb[0], light_ambient_rgb[1], light_ambient_rgb[2] ); - fprintf ( fileout, " \n" ); - fprintf ( fileout, " %f, %f, %f \n", - light_diffuse_rgb[0], light_diffuse_rgb[1], light_diffuse_rgb[2] ); - fprintf ( fileout, " %f, %f, %f \n", - light_direction[0], light_direction[1], light_direction[2] ); - fprintf ( fileout, " %f, %f, %f \n", - light_specular_rgb[0], light_specular_rgb[1], light_specular_rgb[2] ); - fprintf ( fileout, " \n" ); - fprintf ( fileout, " \n" ); - - text_num = text_num + 12; - - for ( mesh = 0; mesh < mesh_num; mesh++ ) { - - fprintf ( fileout, "\n" ); - fprintf ( fileout, " \n", mesh ); - fprintf ( fileout, "\n" ); - text_num = text_num + 3; - - for ( j = 0; j < cor3_num; j++ ) { - fprintf ( fileout, "

%f, %f, %f

\n", j, - cor3[0][j], cor3[1][j], cor3[2][j] ); - text_num = text_num + 1; - } - - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - for ( j = 0; j < cor3_num; j++ ) { - fprintf ( fileout, " %f, %f, %f \n", j, - cor3_normal[0][j], cor3_normal[1][j], cor3_normal[2][j] ); - text_num = text_num + 1; - } - - for ( material = 0; material < material_num; material++ ) { - fprintf ( fileout, "\n" ); - fprintf ( fileout, " \n", material ); - fprintf ( fileout, " %f \n", material_alpha ); - fprintf ( fileout, " %f, %f, %f \n", - material_amb_rgb[0], material_amb_rgb[1], material_amb_rgb[2] ); - fprintf ( fileout, " %f, %f, %f \n", - material_diff_rgb[0], material_diff_rgb[1], material_diff_rgb[2] ); - fprintf ( fileout, " %f, %f, %f \n", - material_emiss_rgb[0], material_emiss_rgb[1], material_emiss_rgb[2] ); - fprintf ( fileout, " %f \n", material_shine ); - fprintf ( fileout, " %f, %f, %f \n", - material_spec_rgb[0], material_spec_rgb[1], material_spec_rgb[2] ); - fprintf ( fileout, " \n" ); - text_num = text_num + 9; - } - - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - - for ( iface = 0; iface < face_num; iface++ ) { - fprintf ( fileout, " \n" ); - fprintf ( fileout, " %d \n", face_material[iface] ); - text_num = text_num + 2; - for ( ivert = 0; ivert < face_order[iface]; ivert++ ) { - fprintf ( fileout, - " %d %d \n", - ivert+1, face[ivert][iface], face[ivert][iface], ivert+1 ); - text_num = text_num + 1; - } - fprintf ( fileout, " \n" ); - text_num = text_num + 1; - } - - fprintf ( fileout, "
\n" ); - text_num = text_num + 1; - - } - - fprintf ( fileout, "\n" ); - text_num = text_num + 1; - - for ( object = 0; object < object_num; object++ ) { - - fprintf ( fileout, " \n" ); - fprintf ( fileout, " \n" ); - fprintf ( fileout, " %f, %f, %f \n", - transform_forward[0], transform_forward[1], transform_forward[2] ); - fprintf ( fileout, " %f, %f, %f \n", - transform_position[0], transform_position[1], transform_position[2] ); - fprintf ( fileout, "' %f, %f, %f \n", - transform_scale[0], transform_scale[1], transform_scale[2] ); - fprintf ( fileout, " %f, %f, %f \n", - transform_up[0], transform_up[1], transform_up[2] ); - fprintf ( fileout, " \n" ); - mesh = 0; - fprintf ( fileout, " %d \n", mesh ); - fprintf ( fileout, " \n" ); - text_num = text_num + 9; - - } - - fprintf ( fileout, "\n" ); - fprintf ( fileout, "
\n" ); - text_num = text_num + 2; - -/* - Report. -*/ - printf ( "\n" ); - printf ( "XGL_WRITE - Wrote %d text lines.\n", text_num ); - - return SUCCESS; -} diff --git a/simmechanics_to_urdf/CMakeLists.txt b/simmechanics_to_urdf/CMakeLists.txt deleted file mode 100644 index f8f1c9c..0000000 --- a/simmechanics_to_urdf/CMakeLists.txt +++ /dev/null @@ -1,30 +0,0 @@ -cmake_minimum_required(VERSION 2.4.6) -include($ENV{ROS_ROOT}/core/rosbuild/rosbuild.cmake) - -# Set the build type. Options are: -# Coverage : w/ debug symbols, w/o optimization, w/ code-coverage -# Debug : w/ debug symbols, w/o optimization -# Release : w/o debug symbols, w/ optimization -# RelWithDebInfo : w/ debug symbols, w/ optimization -# MinSizeRel : w/o debug symbols, w/ optimization, stripped binaries -#set(ROS_BUILD_TYPE RelWithDebInfo) - -rosbuild_init() - -#set the default path for built executables to the "bin" directory -set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin) -#set the default path for built libraries to the "lib" directory -set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) - -#uncomment if you have defined messages -#rosbuild_genmsg() -#uncomment if you have defined services -#rosbuild_gensrv() - -#common commands for building c++ executables and libraries -#rosbuild_add_library(${PROJECT_NAME} src/example.cpp) -#target_link_libraries(${PROJECT_NAME} another_library) -#rosbuild_add_boost_directories() -#rosbuild_link_boost(${PROJECT_NAME} thread) -#rosbuild_add_executable(example examples/example.cpp) -#target_link_libraries(example ${PROJECT_NAME}) diff --git a/simmechanics_to_urdf/Makefile b/simmechanics_to_urdf/Makefile deleted file mode 100644 index b75b928..0000000 --- a/simmechanics_to_urdf/Makefile +++ /dev/null @@ -1 +0,0 @@ -include $(shell rospack find mk)/cmake.mk \ No newline at end of file diff --git a/simmechanics_to_urdf/convert.py b/simmechanics_to_urdf/convert.py deleted file mode 100755 index 7d67c0d..0000000 --- a/simmechanics_to_urdf/convert.py +++ /dev/null @@ -1,667 +0,0 @@ -#!/usr/bin/python - -import roslib; roslib.load_manifest('simmechanics_to_urdf') -import rospy -import sys -import tf -from tf.transformations import euler_from_quaternion, quaternion_from_matrix -from geometry_msgs.msg import TransformStamped -import xml.dom.minidom -from xml.dom.minidom import Document -import math -import numpy #for creating matrix to convert to quaternion -import yaml -from urdf_python.urdf import * - -# Conversion Factors -INCH2METER = 0.0254 -SLUG2KG = 14.5939029 -SLUGININ2KGMM = .009415402 -MM2M = .001 - -# Special Reference Frame(s) -WORLD = "WORLD" - -# Arbitrary List of colors to give pieces different looks -COLORS =[("green", (0, 1, 0, 1)), ("black", (0, 0, 0, 1)), ("red", (1, 0, 0, 1)), - ("blue", (0, 0, 1, 1)), ("yellow", (1, 1, 0, 1)), ("pink", (1, 0, 1, 1)), - ("cyan", (0, 1, 1, 1)), ("green", (0, 1, 0, 1)), ("white", (1, 1, 1, 1)), - ("dblue", (0, 0, .8, 1)), ("dgreen", (.1, .8, .1, 1)), ("gray", (.5, .5, .5, 1))] - -class Converter: - def __init__(self): - # initialize member variables - self.links = {} - self.frames = {} - self.joints = {} - self.names = {} - self.colormap = {} - self.colorindex = 0 - self.usedcolors = {} - - # Start the Transform Manager - self.tfman = TransformManager() - - # Extra Transforms for Debugging - self.tfman.add([0,0,0], [0.70682518,0,0,0.70682518], "ROOT", WORLD) # rotate so Z axis is up - - def convert(self, filename, configfile, mode): - self.mode = mode - - # Parse the configuration file - self.parseConfig(configfile) - - # Parse the input file - self.parse(xml.dom.minidom.parse(filename)) - self.buildTree(self.root) - - # Create the output - self.output(self.root) - - # output the output - if mode == "xml": - print self.result.to_xml() - if mode == "graph": - print self.graph() - if mode == "groups": - print self.groups(root) - - def parseConfig(self, configFile): - """Parse the Configuration File, if it exists. - Set the fields the default if the config does - not set them """ - if configFile == None: - configuration = {} - else: - configuration = yaml.load(file(configFile, 'r')) - if configuration == None: - configuration = {} - - self.freezeList = [] - self.redefinedjoints = {} - - self.root = configuration.get('root', None) - self.extrajoints = configuration.get('extrajoints', {}) - self.filenameformat = configuration.get('filenameformat', "%s") - self.forcelowercase = configuration.get('forcelowercase', False) - self.scale = configuration.get('scale', None) - self.freezeAll = configuration.get('freezeAll', False) - self.baseframe = configuration.get('baseframe', WORLD) - - # Get lists converted to strings - self.removeList = [ str(e) for e in configuration.get('remove', []) ] - self.freezeList = [ str(e) for e in configuration.get('freeze', []) ] - - # Get map with key converted to strings - jointmap = configuration.get('redefinedjoints', {}) - for x in jointmap.keys(): - self.redefinedjoints[str(x)] = jointmap[x] - - # Add Extra Frames - for frame in configuration.get('moreframes', []): - self.tfman.add(frame['offset'], frame['orientation'], frame['parent'], frame['child']) - - - def parse(self, element): - """Recursively goes through all XML elements - and branches off for important elements""" - name = element.localName - # Grab name from root element AND recursively parse - if name == "PhysicalModelingXMLFile": - dict = getDictionary(element) - self.name = dict['name'] - - if name == "Body": - self.parseLink(element) - elif name == "SimpleJoint": - self.parseJoint(element) - elif name == "Ground": - dict = getDictionary(element) - self.parseFrames(dict['frame'], "GROUND") - else: - for child in element.childNodes: - self.parse(child) - - def parseLink(self, link): - """Parse the important bits of a link element""" - linkdict = getDictionary(link) - uid = self.getName(linkdict['name']) - linkdict['neighbors'] = [] - linkdict['children'] = [] - linkdict['jointmap'] = {} - - # Save the frames for separate parsing - frames = linkdict['frames'] - linkdict['frames'] = None - - # Save the color if it exists - if 'MaterialProp' in linkdict: - colorelement = linkdict['MaterialProp'][1] - color = colorelement.childNodes[0].data - linkdict['MaterialProp'] = None - linkdict['color'] = map(float, color.split(",")) + [1.0] - - self.links[uid] = linkdict - self.parseFrames(frames, uid) - - # Save First Actual Element as Root, if not defined already - if self.root == None and "geometryFileName" in linkdict: - self.root = uid - - def parseFrames(self, frames, parent): - """Parse the frames from xml""" - for frame in frames: - if frame.nodeType is frame.TEXT_NODE: - continue - fdict = getDictionary(frame) - fid = str(frame.getAttribute("ref")) - fdict['parent'] = parent - - offset = getlist(fdict['position']) - units = fdict['positionUnits'] - for i in range(0, len(offset)): - offset[i] = convert(offset[i], units) - - orientation = getlist(fdict['orientation']) - quat = matrixToQuaternion(orientation) - - # If the frame does not have a reference number, - # use the name plus a suffix (for CG or CS1... - # otherwise ignore the frame - if fid == "": - name = fdict['name'] - if name == "CG": - fid = parent + "CG" - elif name == "CS1": - fid = parent + "CS1" - else: - continue - - self.tfman.add(offset, quat, WORLD, fid) - self.frames[fid] = fdict - - def parseJoint(self, element): - """Parse the joint from xml""" - dict = getDictionary(element) - joint = {} - joint['name'] = dict['name'] - uid = self.getName(joint['name']) - - frames = element.getElementsByTagName("Frame") - joint['parent'] = str(frames[0].getAttribute("ref")) - joint['child'] = str(frames[1].getAttribute("ref")) - type = element.getElementsByTagName("Primitive") - - # If there multiple elements, assume a fixed joint - if len(type)==1: - pdict = getDictionary(type[0]) - joint['type'] = pdict['name'] - joint['axis'] = pdict['axis'] - if joint['type'] == 'weld': - joint['type'] = 'fixed' - else: - joint['type'] = 'fixed' - - # Ignore joints on the remove list - if joint['parent'] in self.removeList: - return - - # Force joints to be fixed on the freezeList - if joint['parent'] in self.freezeList or self.freezeAll: - joint['type'] = 'fixed' - - # Redefine specified joints on redefined list - if joint['parent'] in self.redefinedjoints.keys(): - jdict = self.redefinedjoints[joint['parent']] - if 'name' in jdict: - uid = jdict['name'] - - # Default to continuous joints - joint['type'] = jdict.get('type', 'continuous') - - if 'axis' in jdict: - joint['axis'] = jdict['axis'] - if 'limits' in jdict: - joint['limits'] = jdict['limits'] - - self.joints[uid] = joint - - def buildTree(self, root): - """Reduce the graph structure of links and joints to a tree - by breadth first search. Then construct new coordinate frames - from new tree structure""" - - # Create a list of all neighboring links at each link - for jid in self.joints: - jointdict = self.joints[jid] - if "Root" in jointdict['name']: - continue - pid = self.getLinkNameByFrame(jointdict['parent']) - cid = self.getLinkNameByFrame(jointdict['child']) - parent = self.links[pid] - child = self.links[cid] - - parent['neighbors'].append(cid) - parent['jointmap'][cid] = jid - child['neighbors'].append(pid) - child['jointmap'][pid] = jid - - # Add necessary information for any user-defined joints - for (name, extrajoint) in self.extrajoints.items(): - pid = extrajoint['pid'] - cid = extrajoint['cid'] - jorigin = extrajoint['jorigin'] - newframe = name + "_frame" - - self.links[pid]['neighbors'].append(cid) - self.links[pid]['jointmap'][cid] = name - self.links[cid]['neighbors'].append(pid) - self.links[cid]['jointmap'][pid] = name - self.joints[name] = {'name': name, 'parent': jorigin, 'child': newframe} - for (k,v) in extrajoint['attributes'].items(): - self.joints[name][k] = v - self.frames[jorigin] = {'parent': pid} - self.frames[newframe] = {'parent': cid} - - # Starting with designated root node, perform BFS to - # create the tree - queue = [ root ] - self.links[root]['parent'] = "GROUND" - while len(queue) > 0: - id = queue.pop(0) - link = self.links[id] - for n in link['neighbors']: - nbor = self.links[n] - # if a neighbor has not been visited yet, - # add it as a child node - if not 'parent' in nbor: - nbor['parent'] = id - queue.append(n) - link['children'].append(n) - - # build new coordinate frames - for id in self.links: - link = self.links[id] - if not 'parent' in link: - continue - parentid = link['parent'] - if parentid == "GROUND": - ref = self.baseframe - else: - joint = self.joints[link['jointmap'][parentid]] - ref = joint['parent'] - # The root of each link is the offset to the joint - # and the rotation of the CS1 frame - (off1, rot1) = self.tfman.get(WORLD, ref) - (off2, rot2) = self.tfman.get(WORLD, id + "CS1") - self.tfman.add(off1, rot2, WORLD, "X" + id) - - - def output(self, rootid): - """Creates the URDF from the parsed document. - Makes the document and starts the recursive build process""" - self.result = URDF(self.name) - self.outputLink(rootid) - self.processLink(rootid) - - def processLink(self, id): - """ Creates the output for the specified node's - child links, the connecting joints, then - recursively processes each child """ - link = self.links[id] - for cid in link['children']: - jid = link['jointmap'][cid] - - self.outputLink(cid) - self.outputJoint(jid, id) - self.processLink(cid) - - def outputLink(self, id): - """ Creates the URDF output for a single link """ - - linkdict = self.links[id] - if linkdict['name'] == "RootPart": - return - - visual = Visual() - inertial = Inertial() - collision = Collision() - - # Define Geometry - filename = linkdict['geometryFileName'] - if self.forcelowercase: - filename = filename.lower() - filename = self.filenameformat % filename - - visual.geometry = Mesh(filename, self.scale) - collision.geometry = visual.geometry - - # Define Inertial Frame - units = linkdict['massUnits'] - massval = convert(float(linkdict['mass']), units) - inertial.mass = massval - - matrix = getlist(linkdict["inertia"]) - - units = linkdict['inertiaUnits'] - - for i in range(0,len(matrix)): - matrix[i] = convert(matrix[i], units) - - inertial.matrix['ixx'] = matrix[0] - inertial.matrix['ixy'] = matrix[1] - inertial.matrix['ixz'] = matrix[2] - inertial.matrix['iyy'] = matrix[4] - inertial.matrix['iyz'] = matrix[5] - inertial.matrix['izz'] = matrix[8] - - # Inertial origin is the center of gravity - (off, rot) = self.tfman.get("X" + id, id+"CG") - rpy = list(euler_from_quaternion(rot)) - inertial.origin = Pose(zero(off), zero(rpy)) - - # Visual offset is difference between origin and CS1 - (off, rot) = self.tfman.get("X" + id, id+"CS1") - rpy = list(euler_from_quaternion(rot)) - visual.origin = Pose(zero(off), zero(rpy)) - collision.origin = visual.origin - - # Define Material - visual.material = Material() - # Use specified color, if exists. Otherwise, get random color - if 'color' in linkdict: - cname = "%s_color"%id - (r,g,b,a) = linkdict['color'] - else: - (cname, (r,g,b,a)) = self.getColor(linkdict['name']) - - visual.material.name = cname - - # If color has already been output, only output name - if not cname in self.usedcolors: - visual.material.color = Color(r,g,b,a) - self.usedcolors[cname] = True - - link = Link(id, visual, inertial, collision) - self.result.add_link(link) - - def getColor(self, s): - """ Gets a two element list containing a color name, - and it's rgba. The color selected is based on the mesh name. - If already seen, returns the saved color - Otherwise, returns the next available color""" - if s in self.colormap: - return self.colormap[s] - color = COLORS[self.colorindex] - self.colormap[s] = color - self.colorindex = (self.colorindex + 1) % len(COLORS) - return color - - def outputJoint(self, id, parentname): - """ Outputs URDF for a single joint """ - jointdict = self.joints[id] - - if "Root" in jointdict['name']: - return - - - # Define the parent and child - pid = self.getLinkNameByFrame(jointdict['parent']) - cid = self.getLinkNameByFrame(jointdict['child']) - - # If the original joint was reversed while building the tree, - # swap the two ids - if parentname != pid: - cid = pid - pid = parentname - - # Define joint type - jtype = jointdict['type'] - - limits = None - axis = None - - if 'limits' in jointdict: - limits = JointLimit(None, None) - for (k,v) in jointdict['limits'].items(): - setattr(limits, k, v) - - if 'axis' in jointdict and jtype != 'fixed': - axis = jointdict['axis'].replace(',', ' ') - - # Define the origin - (off, rot) = self.tfman.get("X" + pid, "X" + cid) - rpy = list(euler_from_quaternion(rot)) - origin = Pose(zero(off), zero(rpy)) - - joint = Joint(id, pid, cid, jtype, limits=limits, axis=axis, origin=origin) - self.result.add_joint(joint) - - def getName(self, basename): - """Return a unique name of the format - basenameD where D is the lowest number - to make the name unique""" - index = 1 - name = basename + str(index) - while name in self.names: - index = index + 1 - name = basename + str(index) - self.names[name] = 1 - return name - - def getLinkNameByFrame(self, key): - """Gets the link name from the frame object""" - return self.frames[key]['parent'] - - def graph(self): - """For debugging purposes, output a graphviz - representation of the tree structure, noting - which joints have been reversed and which have - been removed""" - graph = "digraph proe {\n" - for jkey in self.joints: - joint = self.joints[jkey] - pref = joint['parent'] - cref = joint['child'] - label = pref + ":" + cref - pkey = self.getLinkNameByFrame(pref) - ckey = self.getLinkNameByFrame(cref) - case = 'std' - if pkey != "GROUND": - parent = self.links[pkey] - if not ckey in parent['children']: - child = self.links[ckey] - if pkey in child['children']: - case = 'rev' - else: - case = 'not' - pkey = pkey.replace("-", "_") - ckey = ckey.replace("-", "_") - - if (case == 'std' or case == 'rev') and (joint['type'] != "fixed"): - style = " penwidth=\"5\"" - else: - style = ""; - - if case == 'std': - s = pkey + " -> " + ckey + " [ label = \""+label+"\""; - elif case == 'not': - s = pkey + " -> " + ckey + " [ label = \""+label+"\" color=\"yellow\"" - elif case == 'rev': - s = ckey + " -> " + pkey + " [ label = \""+label+"\" color=\"blue\"" - s = s + style + "];" - - if not "Root" in s and "-> SCR_" not in s: - graph = graph + s + "\n" - return graph + "}\n" - - def groups(self, root): - """ For planning purposes, print out lists of - all the links between the different joints""" - self.groups = {} - self.makeGroup(root, "BASE") - s = "" - for key in self.groups.keys(): - s = s + key + ":\n\t" - ids = self.groups[key] - for id in ids: - s = s+id + " " - s = s + "\n\n" - return s - - def makeGroup(self, id, gid): - """ Helper function for recursively gathering - groups of joints. """ - if gid in self.groups: - idlist = self.groups[gid] - idlist.append(id) - else: - idlist = [id] - self.groups[gid] = idlist - link = self.links[id] - for child in link['children']: - jid = link['jointmap'][child] - joint = self.joints[jid] - if joint['type'] == 'weld': - ngid = gid - else: - ngid = jid - - self.makeGroup(child, ngid) - -def getDictionary(tag): - """Builds a dictionary from the specified xml tag - where each child of the tag is entered into the dictionary - with the name of the child tag as the key, and the contents - as the value. Also removes quotes from quoted values""" - x = {} - for child in tag.childNodes: - if child.nodeType is child.TEXT_NODE: - continue - key = str(child.localName) - if len(child.childNodes) == 1: - data = str(child.childNodes[0].data) - if data[0] == '"' and data[-1] == '"': - if len(data) != 2: - x[key] = data[1:-1] - else: - x[key] = data - else: - data = child.childNodes - x[key] = data - return x - -def getlist(string): - """Splits a string of comma delimited floats to - a list of floats""" - slist = string.split(",") - flist = [] - for s in slist: - flist.append(float(s)) - return flist - - -def convert(value, units): - """Convert value from the specified units to mks units""" - if units == 'kg' or units == 'm' or units == 'kg*m^2': - return value - elif units == 'slug*in^2': - return value * SLUGININ2KGMM - elif units == 'slug': - return value * SLUG2KG - elif units == 'in': - return value * INCH2METER - elif units == 'mm': - return value * MM2M - else: - raise Exception("unsupported mass unit: %s" % units) - -def matrixToQuaternion(matrix): - """Concert 3x3 rotation matrix into a quaternion""" - (R11, R12, R13, R21, R22, R23, R31, R32, R33) = matrix - # Build 4x4 matrix - M = [[R11, R21, R31, 0], - [R12, R22, R32, 0], - [R13, R23, R33, 0], - [0, 0, 0, 1]] - A = numpy.array(M) - [w,x,y,z] = quaternion_from_matrix(A) - return [w,x,y,z] - -def quaternion_to_rpy(quat): - """Convert quaternion into roll pitch yaw list (in degrees)""" - rpy = list(euler_from_quaternion(quat)) - for i in range(0, len(rpy)): - rpy[i] = rpy[i]*180/math.pi - return rpy - -def zero(arr): - """Converts any numbers less than 1e-7 to 0 in the array""" - for i in range(0,len(arr)): - if math.fabs(arr[i]) < 1e-7: - arr[i] = 0 - return arr - - -class TransformManager: - def __init__(self): - self.tf = tf.Transformer(True, rospy.Duration(10.0)) - - def add(self, offset, angle, parent, child): - """Adds a new transform to the set""" - m = TransformStamped() - m.header.frame_id = parent - m.child_frame_id = child - m.transform.translation.x = offset[0] - m.transform.translation.y = offset[1] - m.transform.translation.z = offset[2] - m.transform.rotation.x = angle[0] - m.transform.rotation.y = angle[1] - m.transform.rotation.z = angle[2] - m.transform.rotation.w = angle[3] - self.tf.setTransform(m) - - def get(self, parent, child): - """Retrieves a transform""" - (off,rpy) = self.tf.lookupTransform(parent, child, rospy.Time(0)) - return [list(off), list(rpy)] - - def printTransform(self, parent, child): - """Attempts to print the specified transform""" - (off, rot) = self.get(parent, child) - rpy = quaternion_to_rpy(rot) - - s = parent + "-->" + child - l = (30 - len(s))*" " - print "%s%s[%+.5f %+.5f %+.5f] \t [%+3.3f %+.3f %+.3f] \t [%+.6f %+.6f %+.6f %+.6f] " \ - % (s, l, off[0], off[1], off[2], rpy[0], rpy[1], rpy[2], rot[0], rot[1], rot[2], rot[3]) - - def kill(self): - """Stops thread from running""" - self.running = False - -if __name__ == '__main__': - argc = len(sys.argv) - if argc == 3: - filename = sys.argv[1] - config = None - mode = sys.argv[2] - elif argc == 4: - filename = sys.argv[1] - config = sys.argv[2] - mode = sys.argv[3] - else: - print "Usage: " + sys.argv[0] + " {XML filename} [configfile] {tf|xml|graph|groups|none}" - sys.exit(-1) - try: - rospy.init_node('convert') - con = Converter() - try: - con.convert(filename, config, mode) - while mode == "tf" and not rospy.is_shutdown(): - None - except Exception: - raise - - except rospy.ROSInterruptException: pass - diff --git a/simmechanics_to_urdf/convertToBinaries.py b/simmechanics_to_urdf/convertToBinaries.py deleted file mode 100755 index 8dd6877..0000000 --- a/simmechanics_to_urdf/convertToBinaries.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/python -import os -import sys -import subprocess - -if __name__ == '__main__': - if len(sys.argv) != 2: - print "Usage: " + sys.argv[0] + " [directory]" - sys.exit(-1) - path= sys.argv[1] - dirList=os.listdir(path) - for fname in dirList: - path1 = path + fname - path2 = path + fname + "b" - cmd = "rosrun ivcon ivcon " + path1 + " " + path2 - proc = subprocess.Popen([cmd], stdout=subprocess.PIPE, shell=True) - (out, err) = proc.communicate() - print err diff --git a/simmechanics_to_urdf/mainpage.dox b/simmechanics_to_urdf/mainpage.dox deleted file mode 100644 index f438819..0000000 --- a/simmechanics_to_urdf/mainpage.dox +++ /dev/null @@ -1,26 +0,0 @@ -/** -\mainpage -\htmlinclude manifest.html - -\b simmechanics_to_urdf is ... - - - - -\section codeapi Code API - - - - -*/ diff --git a/simmechanics_to_urdf/manifest.xml b/simmechanics_to_urdf/manifest.xml deleted file mode 100644 index a1e4c61..0000000 --- a/simmechanics_to_urdf/manifest.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - Converts SimMechanics XML to URDF - - David Lu!! - BSD - - http://ros.org/wiki/simmechanics_to_urdf - - - - - - - -