955 lines
27 KiB
C++
955 lines
27 KiB
C++
|
/*
|
||
|
FLUIDS v.1 - SPH Fluid Simulator for CPU and GPU
|
||
|
Copyright (C) 2009. Rama Hoetzlein, http://www.rchoetzlein.com
|
||
|
|
||
|
ZLib license
|
||
|
This software is provided 'as-is', without any express or implied
|
||
|
warranty. In no event will the authors be held liable for any damages
|
||
|
arising from the use of this software.
|
||
|
|
||
|
Permission is granted to anyone to use this software for any purpose,
|
||
|
including commercial applications, and to alter it and redistribute it
|
||
|
freely, subject to the following restrictions:
|
||
|
|
||
|
1. The origin of this software must not be misrepresented; you must not
|
||
|
claim that you wrote the original software. If you use this software
|
||
|
in a product, an acknowledgment in the product documentation would be
|
||
|
appreciated but is not required.
|
||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||
|
misrepresented as being the original software.
|
||
|
3. This notice may not be removed or altered from any source distribution.
|
||
|
*/
|
||
|
|
||
|
#include <conio.h>
|
||
|
#include <vector.h>
|
||
|
#include "mesh.h"
|
||
|
#include "mdebug.h"
|
||
|
//#include "mfile.h"
|
||
|
|
||
|
//#include "event.h"
|
||
|
|
||
|
#include <gl/glut.h>
|
||
|
|
||
|
#define DEGtoRAD (3.141592/180.0)
|
||
|
|
||
|
bool Mesh::mbInitStatic = false;
|
||
|
int Mesh::miBufSize[MAX_MFORMAT][MAX_BFORMAT];
|
||
|
|
||
|
Mesh::Mesh ()
|
||
|
{
|
||
|
debug.SendToConsole ( true );
|
||
|
|
||
|
m_Mform = MFormat::UDef;
|
||
|
m_CurrF = 0;
|
||
|
m_Vbuf = BUF_UNDEF;
|
||
|
m_Ebuf = BUF_UNDEF;
|
||
|
m_Fbuf = BUF_UNDEF;
|
||
|
}
|
||
|
|
||
|
Mesh& Mesh::operator= ( Mesh& src )
|
||
|
{
|
||
|
CopyBuffers ( src );
|
||
|
CopyAttributes ( src );
|
||
|
m_Mform = src.GetMeshBufs ( m_Vbuf, m_Ebuf, m_Fbuf );
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
void Mesh::InitStatic ()
|
||
|
{
|
||
|
mbInitStatic = true;
|
||
|
miBufSize[ (int) FVF ][ (int) BVert ] = sizeof ( VertFVF );
|
||
|
miBufSize[ (int) FVF ][ (int) BFace ] = sizeof ( FaceFVF );
|
||
|
miBufSize[ (int) FVF ][ (int) BEdge ] = 0;
|
||
|
miBufSize[ (int) CM ][ (int) BVert ] = sizeof ( VertCM );
|
||
|
miBufSize[ (int) CM ][ (int) BEdge ] = sizeof ( EdgeCM );
|
||
|
miBufSize[ (int) CM ][ (int) BFace ] = sizeof ( FaceCM );
|
||
|
|
||
|
}
|
||
|
|
||
|
/*void Mesh::onUpdate ( objData dat, mint::Event* e )
|
||
|
{
|
||
|
uchar dtype;
|
||
|
hval num;
|
||
|
hval max;
|
||
|
long size;
|
||
|
ushort stride;
|
||
|
int num_buf;
|
||
|
|
||
|
switch ( dat ) {
|
||
|
case 'full':
|
||
|
ClearBuffers ();
|
||
|
ClearAttributes ();
|
||
|
|
||
|
m_Mform = (MFormat) e->getUChar ();
|
||
|
m_Vbuf = e->getUChar ();
|
||
|
m_Ebuf = e->getUChar ();
|
||
|
m_Fbuf = e->getUChar ();
|
||
|
num_buf = e->getInt ();
|
||
|
for (int b=0; b < num_buf; b++) {
|
||
|
dtype = e->getUChar ();
|
||
|
stride = e->getUShort ();
|
||
|
num = e->getInt ();
|
||
|
max = e->getInt ();
|
||
|
AddBuffer ( dtype, stride, max );
|
||
|
e->getMem ( mBuf[b].data, num * mBuf[b].stride );
|
||
|
mBuf[b].num = num;
|
||
|
}
|
||
|
|
||
|
mHeapNum = e->getInt ();
|
||
|
mHeapMax = e->getInt ();
|
||
|
mHeapFree = e->getInt ();
|
||
|
mHeap = new hval[mHeapMax];
|
||
|
e->getMem ( (char*) mHeap, mHeapNum * sizeof(hval) );
|
||
|
break;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
void Mesh::UpdateMesh ()
|
||
|
{
|
||
|
int s = GetSize () + (mBuf.size()+1)*4*sizeof(int);
|
||
|
mint::Event* e = updateStart ( 'full', s );
|
||
|
|
||
|
e->attachUChar ( (char) m_Mform ) ;
|
||
|
e->attachUChar ( (char) m_Vbuf );
|
||
|
e->attachUChar ( (char) m_Ebuf );
|
||
|
e->attachUChar ( (char) m_Fbuf );
|
||
|
e->attachInt ( mBuf.size() );
|
||
|
for (int b=0; b < mBuf.size(); b++) {
|
||
|
e->attachUChar ( mBuf[b].dtype );
|
||
|
e->attachUShort ( mBuf[b].stride );
|
||
|
e->attachInt ( mBuf[b].num );
|
||
|
e->attachInt ( mBuf[b].max );
|
||
|
e->attachMem ( mBuf[b].data, mBuf[b].num * mBuf[b].stride );
|
||
|
}
|
||
|
e->attachInt ( mHeapNum );
|
||
|
e->attachInt ( mHeapMax );
|
||
|
e->attachInt ( mHeapFree );
|
||
|
e->attachMem ( (char*) mHeap, mHeapNum * sizeof(hval) );
|
||
|
|
||
|
updateEnd ( e );
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
//------------------------------------------------------------------ FVF - Face-vertex-face Mesh
|
||
|
void Mesh::CreateFVF ()
|
||
|
{
|
||
|
if ( !mbInitStatic ) InitStatic ();
|
||
|
SetFuncFVF ();
|
||
|
|
||
|
m_Mform = FVF;
|
||
|
m_Vbuf = AddBuffer ( (uchar) BVert, BufSize( FVF, BVert ), 64 );
|
||
|
m_Fbuf = AddBuffer ( (uchar) BFace, BufSize( FVF, BFace ), 64 );
|
||
|
AddAttribute ( m_Vbuf, "pos", sizeof ( AttrPos ), false );
|
||
|
AddAttribute ( m_Vbuf, "norm", sizeof ( AttrNorm ) );
|
||
|
|
||
|
AddHeap ( 128 );
|
||
|
}
|
||
|
|
||
|
void Mesh::ClearFVF ()
|
||
|
{
|
||
|
ResetBuffer ( 0, mBuf[0].max );
|
||
|
ResetBuffer ( 1, mBuf[0].max );
|
||
|
|
||
|
ResetHeap ();
|
||
|
}
|
||
|
|
||
|
void Mesh::SmoothFVF ( int iter )
|
||
|
{
|
||
|
Vector3DF norm, side;
|
||
|
int cnt;
|
||
|
FaceFVF* f;
|
||
|
VertFVF *v1, *v2, *v3;
|
||
|
AttrPos* face_pos;
|
||
|
face_pos = new AttrPos[ NumFace() ];
|
||
|
|
||
|
for (int j=0; j < iter; j++) {
|
||
|
// Compute centroid of all faces
|
||
|
for (int n=0; n < NumFace(); n++) {
|
||
|
f = GetFaceFVF ( n );
|
||
|
v1 = GetVertFVF(f->v1); v2 = GetVertFVF(f->v2); v3 = GetVertFVF(f->v3);
|
||
|
face_pos[n].x = ( v1->x + v2->x + v3->x ) / 3.0;
|
||
|
face_pos[n].y = ( v1->y + v2->y + v3->y ) / 3.0;
|
||
|
face_pos[n].z = ( v1->z + v2->z + v3->z ) / 3.0;
|
||
|
}
|
||
|
// Compute new vertex positions
|
||
|
int cnt;
|
||
|
Vector3DF vec;
|
||
|
for (int n=0; n < NumVert(); n++) {
|
||
|
v1 = GetVertFVF ( n );
|
||
|
vec.Set (0,0,0);
|
||
|
hval* fptr = mHeap + v1->flist.pos;
|
||
|
for (int j=0; j < v1->flist.cnt; j++) {
|
||
|
vec.x += face_pos[ (*fptr) ].x;
|
||
|
vec.y += face_pos[ (*fptr) ].y;
|
||
|
vec.z += face_pos[ (*fptr) ].z;
|
||
|
fptr++;
|
||
|
}
|
||
|
v1->x = vec.x / (float) v1->flist.cnt;
|
||
|
v1->y = vec.y / (float) v1->flist.cnt;
|
||
|
v1->z = vec.z / (float) v1->flist.cnt;
|
||
|
}
|
||
|
}
|
||
|
delete face_pos;
|
||
|
}
|
||
|
|
||
|
void Mesh::SetNormalFVF ( int n, Vector3DF norm )
|
||
|
{
|
||
|
VertFVF* v1;
|
||
|
AttrNorm* vn;
|
||
|
int noff = GetAttrOffset ( "norm" );
|
||
|
v1 = GetVertFVF ( n );
|
||
|
vn = (AttrNorm* ) ((char*) v1 + noff );
|
||
|
vn->nx = norm.x;
|
||
|
vn->ny = norm.y;
|
||
|
vn->nz = norm.z;
|
||
|
}
|
||
|
|
||
|
|
||
|
void Mesh::SetColorFVF ( int n, DWORD clr )
|
||
|
{
|
||
|
VertFVF* v1;
|
||
|
AttrClr* vc;
|
||
|
int coff = GetAttrOffset ( "color" );
|
||
|
if ( coff == -1 ) return;
|
||
|
v1 = GetVertFVF ( n );
|
||
|
vc = (AttrClr* ) ((char*) v1 + coff );
|
||
|
vc->clr = clr;
|
||
|
}
|
||
|
void Mesh::ComputeNormalsFVF ()
|
||
|
{
|
||
|
Vector3DF norm, side;
|
||
|
FaceFVF* f;
|
||
|
VertFVF *v1, *v2, *v3, *v4;
|
||
|
AttrNorm* vn;
|
||
|
AttrNorm* face_norms;
|
||
|
face_norms = new AttrNorm[ NumFace() ];
|
||
|
|
||
|
// Clear vertex normals
|
||
|
int noff = GetAttrOffset ( "norm" );
|
||
|
for (int n=0; n < NumVert(); n++) {
|
||
|
v1 = GetVertFVF ( n );
|
||
|
vn = (AttrNorm*) ((char*) v1 + noff);
|
||
|
vn->nx = 0;
|
||
|
vn->ny = 0;
|
||
|
vn->nz = 0;
|
||
|
}
|
||
|
|
||
|
// Compute normals of all faces
|
||
|
for (int n=0; n < NumFace(); n++) {
|
||
|
f = GetFaceFVF ( n );
|
||
|
v1 = GetVertFVF(f->v1); v2 = GetVertFVF(f->v2); v3 = GetVertFVF(f->v3);
|
||
|
side = Vector3DF ( v2->x, v2->y, v2->z );
|
||
|
side -= Vector3DF ( v1->x, v1->y, v1->z );
|
||
|
side.Normalize ();
|
||
|
norm = Vector3DF ( v3->x, v3->y, v3->z );
|
||
|
norm -= Vector3DF ( v1->x, v1->y, v1->z );
|
||
|
norm.Normalize ();
|
||
|
norm.Cross ( side );
|
||
|
face_norms[n].nx = norm.x;
|
||
|
face_norms[n].ny = norm.y;
|
||
|
face_norms[n].nz = norm.z;
|
||
|
vn = (AttrNorm*) ((char*) v1 + noff); vn->nx += norm.x; vn->ny += norm.y; vn->nz += norm.z;
|
||
|
vn = (AttrNorm*) ((char*) v2 + noff); vn->nx += norm.x; vn->ny += norm.y; vn->nz += norm.z;
|
||
|
vn = (AttrNorm*) ((char*) v3 + noff); vn->nx += norm.x; vn->ny += norm.y; vn->nz += norm.z;
|
||
|
if ( f->v4 != -1 ) {
|
||
|
v4 = GetVertFVF(f->v4);
|
||
|
vn = (AttrNorm*) ((char*) v4 + noff); vn->nx += norm.x; vn->ny += norm.y; vn->nz += norm.z;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Normalize vertex normals
|
||
|
Vector3DF vec;
|
||
|
for (int n=0; n < NumVert(); n++) {
|
||
|
v1 = GetVertFVF ( n );
|
||
|
vn = (AttrNorm*) ((char*) v1 + noff);
|
||
|
vec.Set ( vn->nx, vn->ny, vn->nz );
|
||
|
vec.Normalize ();
|
||
|
vn->nx = vec.x;
|
||
|
vn->ny = vec.y;
|
||
|
vn->nz = vec.z;
|
||
|
}
|
||
|
|
||
|
// Compute normal of a vertex from surrounding faces (slow method)
|
||
|
/*int cnt;
|
||
|
for (int n=0; n < NumVert(); n++) {
|
||
|
v1 = GetVertFVF ( n );
|
||
|
vn = (VertNorm*) GetExtraFVF ( v1 );
|
||
|
cnt = 0;
|
||
|
vn->nx = 0; vn->ny = 0; vn->nz = 0;
|
||
|
hval* fptr = mHeap + v1->flist.pos;
|
||
|
for (int j=0; j < v1->flist.cnt; j++) {
|
||
|
vn->nx += face_norms[ (*fptr) ].nx;
|
||
|
vn->ny += face_norms[ (*fptr) ].ny;
|
||
|
vn->nz += face_norms[ (*fptr) ].nz;
|
||
|
cnt++;
|
||
|
fptr++;
|
||
|
}
|
||
|
vn->nx /= (float) cnt;
|
||
|
vn->ny /= (float) cnt;
|
||
|
vn->nz /= (float) cnt;
|
||
|
}*/
|
||
|
|
||
|
delete face_norms;
|
||
|
}
|
||
|
|
||
|
void Mesh::SetFuncFVF ()
|
||
|
{
|
||
|
m_AddVertFunc = &Mesh::AddVertFVF;
|
||
|
m_AddFaceFast3Func = &Mesh::AddFaceFast3FVF;
|
||
|
m_AddFaceFast4Func = &Mesh::AddFaceFast4FVF;
|
||
|
}
|
||
|
|
||
|
xref Mesh::AddFaceFast3FVF ( xref v1, xref v2, xref v3 )
|
||
|
{
|
||
|
xref fNdx;
|
||
|
FaceFVF* f = (FaceFVF*) AddElem ( m_Fbuf, fNdx );
|
||
|
f->v1 = v1; f->v2 = v2; f->v3 = v3; f->v4 = -1;
|
||
|
AddRef ( fNdx, GetVertFVF(v1)->flist, FACE_DELTA );
|
||
|
AddRef ( fNdx, GetVertFVF(v2)->flist, FACE_DELTA );
|
||
|
AddRef ( fNdx, GetVertFVF(v3)->flist, FACE_DELTA );
|
||
|
return fNdx;
|
||
|
}
|
||
|
xref Mesh::AddFaceFast4FVF ( xref v1, xref v2, xref v3, xref v4 )
|
||
|
{
|
||
|
xref fNdx;
|
||
|
FaceFVF* f = (FaceFVF*) AddElem ( m_Fbuf, fNdx );
|
||
|
f->v1 = v1; f->v2 = v2; f->v3 = v3; f->v4 = v4;
|
||
|
AddRef ( fNdx, GetVertFVF(v1)->flist, FACE_DELTA );
|
||
|
AddRef ( fNdx, GetVertFVF(v2)->flist, FACE_DELTA );
|
||
|
AddRef ( fNdx, GetVertFVF(v3)->flist, FACE_DELTA );
|
||
|
AddRef ( fNdx, GetVertFVF(v4)->flist, FACE_DELTA );
|
||
|
return fNdx;
|
||
|
}
|
||
|
xref Mesh::AddVertFVF ( float x, float y, float z )
|
||
|
{
|
||
|
xref ndx;
|
||
|
VertFVF* v = (VertFVF*) AddElem ( m_Vbuf, ndx );
|
||
|
v->x = x; v->y = y; v->z = z;
|
||
|
ClearRefs ( v->flist );
|
||
|
return ndx;
|
||
|
}
|
||
|
|
||
|
void Mesh::DebugFVF ()
|
||
|
{
|
||
|
int n;
|
||
|
int j;
|
||
|
VertFVF* v;
|
||
|
FaceFVF* f;
|
||
|
debug.Printf ( "-- MESH --\n");
|
||
|
|
||
|
debug.Printf ( "-- verts\n" );
|
||
|
for (n=0; n < NumVert(); n++) {
|
||
|
v = GetVertFVF(n);
|
||
|
debug.Printf ( "%d: (%2.1f,%2.1f,%2.1f) f:%d %d{", n, v->x, v->y, v->z, v->flist.cnt, v->flist.pos);
|
||
|
if ( v->flist.cnt > 0 ) {
|
||
|
for (j=0; j < v->flist.cnt; j++)
|
||
|
debug.Printf ( "%d ", *(mHeap+v->flist.pos+j) - FACE_DELTA );
|
||
|
}
|
||
|
debug.Printf ( "}\n" );
|
||
|
}
|
||
|
debug.Printf ( "-- faces\n" );
|
||
|
for (n=0; n < NumFace(); n++) {
|
||
|
f = GetFaceFVF(n);
|
||
|
debug.Printf ( "%d: v:%d %d %d\n", n, f->v1, f->v2, f->v3);
|
||
|
}
|
||
|
|
||
|
DebugHeap ();
|
||
|
|
||
|
debug.Printf ("\n\n");
|
||
|
//_getch();
|
||
|
}
|
||
|
|
||
|
|
||
|
//------------------------------------------------------------------ CM - Connected Mesh
|
||
|
// Create Connected Mesh (CM)
|
||
|
void Mesh::CreateCM ()
|
||
|
{
|
||
|
if ( !mbInitStatic ) InitStatic ();
|
||
|
SetFuncCM ();
|
||
|
|
||
|
m_Mform = CM;
|
||
|
m_Vbuf = AddBuffer ( (uchar) BVert, BufSize( CM, BVert ), 64 );
|
||
|
m_Ebuf = AddBuffer ( (uchar) BEdge, BufSize ( CM, BEdge), 64 );
|
||
|
m_Fbuf = AddBuffer ( (uchar) BFace, BufSize ( CM, BFace), 64 );
|
||
|
AddAttribute ( m_Vbuf, "pos", sizeof(AttrPos), false );
|
||
|
AddAttribute ( m_Vbuf, "norm", sizeof(AttrNorm) );
|
||
|
|
||
|
AddHeap ( 128 );
|
||
|
}
|
||
|
|
||
|
void Mesh::SetFuncCM ()
|
||
|
{
|
||
|
m_AddVertFunc = &Mesh::AddVertCM;
|
||
|
m_AddFaceFast3Func = &Mesh::AddFaceFast3CM;
|
||
|
m_AddFaceFast4Func = &Mesh::AddFaceFast4CM;
|
||
|
}
|
||
|
|
||
|
|
||
|
xref Mesh::AddVertCM ( float x, float y, float z )
|
||
|
{
|
||
|
xref ndx;
|
||
|
VertCM* v = (VertCM*) AddElem ( m_Vbuf, ndx );
|
||
|
v->x = x; v->y = y; v->z = z;
|
||
|
ClearRefs ( v->elist );
|
||
|
ClearRefs ( v->flist );
|
||
|
return ndx;
|
||
|
}
|
||
|
|
||
|
xref Mesh::AddFaceFast3CM ( xref v1, xref v2, xref v3 )
|
||
|
{
|
||
|
xref fNdx;
|
||
|
FaceCM* f = (FaceCM*) AddElem ( m_Fbuf, fNdx );
|
||
|
f->v1 = v1; f->v2 = v2; f->v3 = v3; f->v4 = -1;
|
||
|
xref eNdx;
|
||
|
eNdx = AddEdgeCM ( f->v1, f->v2 ); f->e1 = eNdx;
|
||
|
eNdx = AddEdgeCM ( f->v2, f->v3 ); f->e2 = eNdx;
|
||
|
eNdx = AddEdgeCM ( f->v3, f->v1 ); f->e3 = eNdx;
|
||
|
AddRef ( fNdx, GetVertCM(v1)->flist, FACE_DELTA );
|
||
|
AddRef ( fNdx, GetVertCM(v2)->flist, FACE_DELTA );
|
||
|
AddRef ( fNdx, GetVertCM(v3)->flist, FACE_DELTA );
|
||
|
return fNdx;
|
||
|
}
|
||
|
xref Mesh::AddFaceFast4CM ( xref v1, xref v2, xref v3, xref v4 )
|
||
|
{
|
||
|
xref fNdx;
|
||
|
FaceCM* f = (FaceCM*) AddElem ( m_Fbuf, fNdx );
|
||
|
f->v1 = v1; f->v2 = v2; f->v3 = v3; f->v4 = v4;
|
||
|
xref eNdx;
|
||
|
eNdx = AddEdgeCM ( f->v1, f->v2 ); f->e1 = eNdx;
|
||
|
eNdx = AddEdgeCM ( f->v2, f->v3 ); f->e2 = eNdx;
|
||
|
eNdx = AddEdgeCM ( f->v3, f->v4 ); f->e3 = eNdx;
|
||
|
eNdx = AddEdgeCM ( f->v4, f->v1 ); f->e4 = eNdx;
|
||
|
AddRef ( fNdx, GetVertCM(v1)->flist, FACE_DELTA );
|
||
|
AddRef ( fNdx, GetVertCM(v2)->flist, FACE_DELTA );
|
||
|
AddRef ( fNdx, GetVertCM(v3)->flist, FACE_DELTA );
|
||
|
AddRef ( fNdx, GetVertCM(v4)->flist, FACE_DELTA );
|
||
|
return fNdx;
|
||
|
}
|
||
|
|
||
|
xref Mesh::FindEdgeCM ( xref v1, xref v2 )
|
||
|
{
|
||
|
EdgeCM *pE;
|
||
|
VertCM *pV1;
|
||
|
pV1 = GetVertCM(v1);
|
||
|
if ( pV1->elist.cnt == 0 ) return -1;
|
||
|
hval* e = mHeap + pV1->elist.pos;
|
||
|
#ifdef MESH_DEBUG
|
||
|
for (int n=0; n < pV1->elist.cnt; n++) {
|
||
|
pE = GetEdgeCM( (*e)-EDGE_DELTA );
|
||
|
if ( pE->v1 == v2 || pE->v2 == v2 ) return (*e)-EDGE_DELTA;
|
||
|
e++;
|
||
|
}
|
||
|
#else
|
||
|
for (int n=0; n < pV1->elist.cnt; n++) {
|
||
|
pE = GetEdgeCM( *e );
|
||
|
if ( pE->v1 == v2 || pE->v2 == v2 ) return *e;
|
||
|
e++;
|
||
|
}
|
||
|
#endif
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
xref Mesh::AddEdgeCM ( xref v1, xref v2 )
|
||
|
{
|
||
|
xref eNdx = FindEdgeCM ( v1, v2 );
|
||
|
EdgeCM* e = GetEdgeCM(eNdx);
|
||
|
if ( eNdx == -1 ) {
|
||
|
e = (EdgeCM*) AddElem ( m_Ebuf, eNdx );
|
||
|
e->f1 = 0;
|
||
|
e->f2 = 0;
|
||
|
e->v1 = v1;
|
||
|
e->v2 = v2;
|
||
|
AddRef ( eNdx, GetVertCM(v1)->elist, EDGE_DELTA );
|
||
|
AddRef ( eNdx, GetVertCM(v2)->elist, EDGE_DELTA );
|
||
|
}
|
||
|
return eNdx;
|
||
|
}
|
||
|
|
||
|
void Mesh::DebugCM ()
|
||
|
{
|
||
|
int n;
|
||
|
int j;
|
||
|
VertCM* v;
|
||
|
EdgeCM* e;
|
||
|
FaceCM* f;
|
||
|
debug.Printf ( "-- MESH --\n");
|
||
|
|
||
|
debug.Printf ( "-- verts\n" );
|
||
|
for (n=0; n < NumVert(); n++) {
|
||
|
v = GetVertCM(n);
|
||
|
debug.Printf ( "%d: (%2.1f,%2.1f,%2.1f) e:%d %d{", n, v->x, v->y, v->z, v->elist.cnt, v->elist.pos);
|
||
|
if ( v->elist.cnt > 0 ) {
|
||
|
for (j=0; j < v->elist.cnt; j++)
|
||
|
debug.Printf ( "%d ", *(mHeap+v->elist.pos+j) - EDGE_DELTA );
|
||
|
}
|
||
|
debug.Printf ( "}, f:%d %d{", v->flist.cnt, v->flist.pos);
|
||
|
if ( v->flist.cnt > 0 ) {
|
||
|
for (j=0; j < v->flist.cnt; j++)
|
||
|
debug.Printf ( "%d ", *(mHeap+v->flist.pos+j) - FACE_DELTA );
|
||
|
}
|
||
|
debug.Printf ( "}\n" );
|
||
|
}
|
||
|
|
||
|
debug.Printf ( "-- edges\n" );
|
||
|
for (n=0; n < NumEdge(); n++) {
|
||
|
e = GetEdgeCM (n);
|
||
|
debug.Printf ( "%d: v:%d %d, f:%d %d\n", n, e->v1, e->v2, e->f1, e->f2 );
|
||
|
}
|
||
|
|
||
|
debug.Printf ( "-- faces\n" );
|
||
|
for (n=0; n < NumFace(); n++) {
|
||
|
f = GetFaceCM(n);
|
||
|
debug.Printf ( "%d: v:%d %d %d, e:%d %d %d\n", n, f->v1, f->v2, f->v3, f->e1, f->e2, f->e3 );
|
||
|
}
|
||
|
|
||
|
|
||
|
hval* pVal = mHeap;
|
||
|
debug.Printf ( "-- heap (size: %d, max: %d, free: %04d)\n", mHeapNum, mHeapMax, mHeapFree );
|
||
|
for (n=0; n < mHeapNum; n++) {
|
||
|
if ( (n % 8) == 0 ) debug.Printf ( "\n[%04d] ", n );
|
||
|
#ifdef MESH_DEBUG
|
||
|
if ( *pVal == 0 ) {
|
||
|
debug.Printf ( "00000 ");
|
||
|
} else if ( *pVal == (hval) 0xFFFF ) {
|
||
|
debug.Printf ( "----- ");
|
||
|
} else if ( *pVal >= VERT_DELTA && *pVal < EDGE_DELTA ) {
|
||
|
debug.Printf ( "v%04d ", *pVal - VERT_DELTA );
|
||
|
} else if ( *pVal >= EDGE_DELTA && *pVal < FACE_DELTA ) {
|
||
|
debug.Printf ( "e%04d ", *pVal - EDGE_DELTA );
|
||
|
} else if ( *pVal >= FACE_DELTA ) {
|
||
|
debug.Printf ( "f%04d ", *pVal - FACE_DELTA );
|
||
|
} else {
|
||
|
debug.Printf ( "H%04d ", (int) *pVal );
|
||
|
}
|
||
|
#else
|
||
|
debug.Printf ( "%05d ", (int) *pVal );
|
||
|
#endif
|
||
|
pVal++;
|
||
|
}
|
||
|
|
||
|
debug.Printf ("\n\n");
|
||
|
//_getch();
|
||
|
}
|
||
|
|
||
|
void Mesh::DebugHeap ()
|
||
|
{
|
||
|
hval* pVal = mHeap;
|
||
|
debug.Printf ( "-- heap (size: %d, max: %d, free: %04d)\n", mHeapNum, mHeapMax, mHeapFree );
|
||
|
for (int n=0; n < mHeapNum; n++) {
|
||
|
if ( (n % 8) == 0 ) debug.Printf ( "\n[%04d] ", n );
|
||
|
#ifdef MESH_DEBUG
|
||
|
if ( *pVal == 0 ) {
|
||
|
debug.Printf ( "00000 ");
|
||
|
} else if ( *pVal == (hval) 0xFFFF ) {
|
||
|
debug.Printf ( "----- ");
|
||
|
} else if ( *pVal >= VERT_DELTA && *pVal < EDGE_DELTA ) {
|
||
|
debug.Printf ( "v%04d ", *pVal - VERT_DELTA );
|
||
|
} else if ( *pVal >= EDGE_DELTA && *pVal < FACE_DELTA ) {
|
||
|
debug.Printf ( "e%04d ", *pVal - EDGE_DELTA );
|
||
|
} else if ( *pVal >= FACE_DELTA ) {
|
||
|
debug.Printf ( "f%04d ", *pVal - FACE_DELTA );
|
||
|
} else {
|
||
|
debug.Printf ( "H%04d ", (int) *pVal );
|
||
|
}
|
||
|
#else
|
||
|
debug.Printf ( "%05d ", (int) *pVal );
|
||
|
#endif
|
||
|
pVal++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Mesh::DrawVertsCM ( float* viewmat, int a, int b )
|
||
|
{
|
||
|
VertCM* v;
|
||
|
|
||
|
glColor3f (1,0,0);
|
||
|
glLoadMatrixf ( viewmat );
|
||
|
glTranslatef ( mT.x, mT.y, mT.z );
|
||
|
glBegin ( GL_POINTS );
|
||
|
for (int n = a; n <= b; n++) {
|
||
|
v = GetVertCM (n);
|
||
|
glVertex3f ( v->x, v->y, v->z );
|
||
|
//glCallList ( m_GLObj );
|
||
|
}
|
||
|
glEnd ();
|
||
|
}
|
||
|
|
||
|
void Mesh::DrawVertsFVF ( float* viewmat, int a, int b )
|
||
|
{
|
||
|
VertFVF* v;
|
||
|
glColor3f (1,0,0);
|
||
|
glLoadMatrixf ( viewmat );
|
||
|
glTranslatef ( mT.x, mT.y, mT.z );
|
||
|
glBegin ( GL_POINTS );
|
||
|
for (int n = a; n <= b; n++) {
|
||
|
v = GetVertFVF (n);
|
||
|
glVertex3f ( v->x, v->y, v->z );
|
||
|
//glCallList ( m_GLObj );
|
||
|
}
|
||
|
glEnd ();
|
||
|
}
|
||
|
|
||
|
void Mesh::DrawFacesCM ( float* viewmat, int a, int b )
|
||
|
{
|
||
|
FaceCM* f;
|
||
|
VertCM* v;
|
||
|
AttrNorm* vn;
|
||
|
int noff = GetAttrOffset ( "norm" );
|
||
|
glLoadMatrixf ( viewmat );
|
||
|
glTranslatef ( mT.x, mT.y, mT.z );
|
||
|
GLenum dm = GL_TRIANGLES;
|
||
|
glBegin ( dm );
|
||
|
f = GetFaceCM ( a );
|
||
|
for (int n = a; n <= b; n++) {
|
||
|
if ( f->v4 == -1 ) {
|
||
|
if ( dm != GL_TRIANGLES ) { glEnd (); glBegin ( GL_TRIANGLES ); dm = GL_TRIANGLES; }
|
||
|
v = GetVertCM(f->v1); vn = (AttrNorm*) ((char*) v + noff);
|
||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||
|
v = GetVertCM(f->v2); vn = (AttrNorm*) ((char*) v + noff);
|
||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||
|
v = GetVertCM(f->v3); vn = (AttrNorm*) ((char*) v + noff);
|
||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||
|
} else {
|
||
|
if ( dm != GL_QUADS ) { glEnd (); glBegin ( GL_QUADS ); dm = GL_QUADS; }
|
||
|
v = GetVertCM(f->v1); vn = (AttrNorm*) ((char*) v + noff);
|
||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||
|
v = GetVertCM(f->v2); vn = (AttrNorm*) ((char*) v + noff);
|
||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||
|
v = GetVertCM(f->v3); vn = (AttrNorm*) ((char*) v + noff);
|
||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||
|
v = GetVertCM(f->v4); vn = (AttrNorm*) ((char*) v + noff);
|
||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||
|
}
|
||
|
f++;
|
||
|
}
|
||
|
glEnd ();
|
||
|
}
|
||
|
|
||
|
void Mesh::DrawFacesFVF ( float* viewmat, int a, int b )
|
||
|
{
|
||
|
FaceFVF* f;
|
||
|
VertFVF* v;
|
||
|
AttrNorm* vn;
|
||
|
AttrClr* vc;
|
||
|
int noff = GetAttrOffset ( "norm" );
|
||
|
int coff = GetAttrOffset ( "color" );
|
||
|
coff = -1;
|
||
|
|
||
|
//glLoadMatrixf ( viewmat );
|
||
|
//glTranslatef ( mT.x, mT.y, mT.z );
|
||
|
GLenum dm = GL_TRIANGLES;
|
||
|
glBegin ( dm );
|
||
|
f = GetFaceFVF ( a );
|
||
|
for (int n = a; n <= b; n++) {
|
||
|
if ( f->v4 == -1 ) {
|
||
|
if ( dm != GL_TRIANGLES ) { glEnd (); glBegin ( GL_TRIANGLES ); dm = GL_TRIANGLES; }
|
||
|
v = GetVertFVF(f->v1); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
|
||
|
if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
|
||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||
|
|
||
|
v = GetVertFVF(f->v2); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
|
||
|
if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
|
||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||
|
|
||
|
v = GetVertFVF(f->v3); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
|
||
|
if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
|
||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||
|
} else {
|
||
|
if ( dm != GL_QUADS ) { glEnd (); glBegin ( GL_QUADS ); dm = GL_QUADS; }
|
||
|
v = GetVertFVF(f->v1); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
|
||
|
if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
|
||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||
|
|
||
|
v = GetVertFVF(f->v2); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
|
||
|
if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
|
||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||
|
|
||
|
v = GetVertFVF(f->v3); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
|
||
|
if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
|
||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||
|
|
||
|
v = GetVertFVF(f->v4); vn = (AttrNorm*) ((char*) v + noff); vc = (AttrClr*) ((char*) v +coff);
|
||
|
if ( coff != -1 ) glColor4f ( RED(vc->clr), GRN(vc->clr), BLUE(vc->clr), ALPH(vc->clr) );
|
||
|
glNormal3f ( vn->nx, vn->ny, vn->nz ); glVertex3f ( v->x, v->y, v->z );
|
||
|
}
|
||
|
f++;
|
||
|
}
|
||
|
glEnd ();
|
||
|
}
|
||
|
|
||
|
void Mesh::DrawEdgesCM ( float* viewmat, int a, int b )
|
||
|
{
|
||
|
EdgeCM* e;
|
||
|
|
||
|
glLoadMatrixf ( viewmat );
|
||
|
glTranslatef ( mT.x, mT.y, mT.z );
|
||
|
glBegin ( GL_LINES );
|
||
|
e = GetEdgeCM ( a );
|
||
|
for (int n = a; n <= b; n++) {
|
||
|
glVertex3f ( GetVertCM(e->v1)->x, GetVertCM(e->v1)->y, GetVertCM(e->v1)->z );
|
||
|
glVertex3f ( GetVertCM(e->v2)->x, GetVertCM(e->v2)->y, GetVertCM(e->v2)->z );
|
||
|
e++;
|
||
|
}
|
||
|
glEnd ();
|
||
|
}
|
||
|
|
||
|
void Mesh::DrawGL ( float* viewmat )
|
||
|
{
|
||
|
mT.Set(0,0,0);
|
||
|
|
||
|
switch ( m_Mform ) {
|
||
|
case CM: {
|
||
|
glDepthRange (0.001, 1.001);
|
||
|
//glColor3f ( 1, 0, 0 ); DrawVertsCM ( viewmat, 0, NumVert()-1 );
|
||
|
glColor3f ( .6, .6, .6 ); DrawFacesCM ( viewmat, 0, NumFace()-1 );
|
||
|
//glDepthRange (0.0005, 1.0005);
|
||
|
//glColor3f ( 1, 1, 1); DrawEdgesCM ( viewmat, 0, NumEdge()-1 );
|
||
|
} break;
|
||
|
case FVF: {
|
||
|
//glColor3f (1,0,0); DrawVertsFVF ( viewmat, 0, NumVert()-1 );
|
||
|
//glEnable (GL_LIGHTING);
|
||
|
|
||
|
glPolygonMode ( GL_FRONT_AND_BACK, GL_FILL );
|
||
|
glColor4f ( .9, .9, .9, 0.75 ); DrawFacesFVF ( viewmat, 0, NumFace()-1 );
|
||
|
|
||
|
/*glDisable (GL_LIGHTING );
|
||
|
glDepthRange (0.000, 1.00);
|
||
|
glPolygonMode ( GL_FRONT_AND_BACK, GL_LINE );
|
||
|
glLineWidth ( 3 );
|
||
|
glColor4f ( 0, 0, 0, 1.0 ); DrawFacesFVF ( viewmat, 0, NumFace()-1 );
|
||
|
glEnable ( GL_LIGHTING );
|
||
|
|
||
|
glLineWidth ( 1);
|
||
|
|
||
|
glDepthRange (0.0, 1.0);
|
||
|
glPolygonMode ( GL_FRONT_AND_BACK, GL_FILL );*/
|
||
|
|
||
|
} break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Mesh::DrawFaceGL ( float* viewmat )
|
||
|
{
|
||
|
mT.Set (0,0,0);
|
||
|
if ( m_CurrF < 0 ) m_CurrF = NumFace()-1;
|
||
|
if ( m_CurrF >= NumFace() ) m_CurrF = 0;
|
||
|
|
||
|
switch ( m_Mform ) {
|
||
|
case FVF:
|
||
|
glDepthRange (0.0, 1.0); glColor3f (1.0, 1.0, 1.0 );
|
||
|
DrawFacesFVF ( viewmat, m_CurrF, m_CurrF );
|
||
|
break;
|
||
|
case CM:
|
||
|
glDepthRange (0.0, 1.0); glColor3f (1.0, 1.0, 1.0 );
|
||
|
DrawFacesCM ( viewmat, m_CurrF, m_CurrF );
|
||
|
break;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
void Mesh::Measure ()
|
||
|
{
|
||
|
hval* pCurr = mHeap + mHeapFree;
|
||
|
int vs, es, fs, hs, hm, as, frees = 0;
|
||
|
vs = NumVert(); if ( vs !=0 ) vs *= GetStride(m_Vbuf);
|
||
|
es = NumEdge(); if ( es !=0 ) es *= GetStride(m_Ebuf);
|
||
|
fs = NumFace(); if ( fs !=0 ) fs *= GetStride(m_Fbuf);
|
||
|
hs = mHeapNum*sizeof(hval);
|
||
|
hm = mHeapMax*sizeof(hval);
|
||
|
|
||
|
while ( pCurr != mHeap-1 ) {
|
||
|
frees += *(pCurr);
|
||
|
pCurr = mHeap + * (hpos*) (pCurr + FPOS);
|
||
|
}
|
||
|
frees *= sizeof(hval);
|
||
|
as = 0;
|
||
|
if ( m_Vbuf!=-1 ) as += mBuf[m_Vbuf].max * GetStride(m_Vbuf);
|
||
|
if ( m_Fbuf!=-1 ) as += mBuf[m_Fbuf].max * GetStride(m_Fbuf);
|
||
|
if ( m_Ebuf!=-1 ) as += mBuf[m_Ebuf].max * GetStride(m_Ebuf);
|
||
|
as += hm;
|
||
|
|
||
|
debug.Printf ( "NumVert: %07.1fk (%d)\n", vs/1000.0, NumVert() );
|
||
|
debug.Printf ( "NumFace: %07.1fk (%d)\n", fs/1000.0, NumFace() );
|
||
|
debug.Printf ( "NumEdge: %07.1fk (%d)\n", es/1000.0, NumEdge() );
|
||
|
debug.Printf ( "Heap Size: %07.1fk (%d)\n", hs/1000.0, mHeapNum );
|
||
|
debug.Printf ( "Free Size: %07.1fk\n", frees/1000.0 );
|
||
|
debug.Printf ( "Heap Used: %07.1fk (%5.1f%%)\n", (hs-frees)/1000.0, (hs-frees)*100.0/(vs+es+fs+hs-frees) );
|
||
|
debug.Printf ( "Heap Max: %07.1fk\n", hm/1000.0 );
|
||
|
debug.Printf ( "Total Used: %07.1fk\n", (vs+es+fs+hs-frees)/1000.0 );
|
||
|
debug.Printf ( "Total Alloc: %07.1fk\n", as/1000.0 );
|
||
|
debug.Printf ( "Fragmentation: %f%%\n", (hm-(hs-frees))*100.0 / hm );
|
||
|
}
|
||
|
|
||
|
|
||
|
/*int Mesh::GetIndex ( int b, void* v )
|
||
|
{
|
||
|
if ( v == 0x0 ) return -1;
|
||
|
return ((char*) v - (char*) mBuf[b].data) / mBuf[b].stride;
|
||
|
}*/
|
||
|
|
||
|
int Mesh::FindPlyElem ( char typ )
|
||
|
{
|
||
|
for (int n=0; n < m_Ply.size(); n++) {
|
||
|
if ( m_Ply[n]->type == typ ) return n;
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
int Mesh::FindPlyProp ( int elem, std::string name )
|
||
|
{
|
||
|
for (int n=0; n < m_Ply[elem]->prop_list.size(); n++) {
|
||
|
if ( m_Ply[elem]->prop_list[n].name.compare ( name)==0 )
|
||
|
return n;
|
||
|
}
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
void Mesh::LoadPly ( char* fname, float s )
|
||
|
{
|
||
|
/* int m_PlyCnt;
|
||
|
float m_PlyData[40];
|
||
|
char buf[1000];
|
||
|
char bword[1000];
|
||
|
std::string word;
|
||
|
Buffer b(1000);
|
||
|
int vnum, fnum, elem, cnt;
|
||
|
char typ;
|
||
|
|
||
|
if ( m_Mform == MFormat::UDef )
|
||
|
CreateFVF ();
|
||
|
|
||
|
m_File.Open ( fname, FILE_READ | FILE_SEQUENTIAL );
|
||
|
if ( !m_File.Valid() ) {
|
||
|
error.PrintF ( "mesh", "Could not find file: %s\n", fname );
|
||
|
error.Exit ();
|
||
|
}
|
||
|
|
||
|
// Read header
|
||
|
m_File.ReadLine ( buf, 1000 );
|
||
|
b.ReadWord ( buf, bword ); word = bword;
|
||
|
if ( word.compare("ply" )!=0 ) {
|
||
|
error.PrintF ( "Not a ply file. %s\n", fname );
|
||
|
error.Exit ();
|
||
|
}
|
||
|
|
||
|
debug.Printf ( "Reading PLY.\n" );
|
||
|
while ( m_File.ReadLine ( buf, 1000 ) == FILE_STATUS_OK ) {
|
||
|
b.ReadWord ( buf, bword );
|
||
|
word = bword;
|
||
|
if ( word.compare("comment" )!=0 ) {
|
||
|
if ( word.compare("end_header")==0 ) break;
|
||
|
if ( word.compare("property")==0 ) {
|
||
|
b.ReadWord ( buf, bword );
|
||
|
word = bword;
|
||
|
if ( word.compare("float")==0 ) typ = PLY_FLOAT;
|
||
|
if ( word.compare("float16")==0 ) typ = PLY_FLOAT;
|
||
|
if ( word.compare("float32")==0 ) typ = PLY_FLOAT;
|
||
|
if ( word.compare("int8")==0 ) typ = PLY_INT;
|
||
|
if ( word.compare("uint8")==0 ) typ = PLY_UINT;
|
||
|
if ( word.compare("list")==0) {
|
||
|
typ = PLY_LIST;
|
||
|
b.ReadWord ( buf, bword );
|
||
|
b.ReadWord ( buf, bword );
|
||
|
}
|
||
|
b.ReadWord ( buf, bword );
|
||
|
word = bword;
|
||
|
AddPlyProperty ( typ, word );
|
||
|
}
|
||
|
if ( word.compare("element" )==0 ) {
|
||
|
b.ReadWord ( buf, bword); word = bword;
|
||
|
if ( word.compare("vertex")==0 ) {
|
||
|
b.ReadWord ( buf, bword);
|
||
|
vnum = atoi ( bword );
|
||
|
debug.Printf ( " Verts: %d\n", vnum );
|
||
|
AddPlyElement ( PLY_VERTS, vnum );
|
||
|
}
|
||
|
if ( word.compare("face")==0 ) {
|
||
|
b.ReadWord ( buf, bword);
|
||
|
fnum = atoi ( bword );
|
||
|
debug.Printf ( " Faces: %d\n", fnum );
|
||
|
AddPlyElement ( PLY_FACES, fnum );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Read data
|
||
|
int xi, yi, zi;
|
||
|
debug.Printf ( " Reading verts..\n" );
|
||
|
elem = FindPlyElem ( PLY_VERTS );
|
||
|
xi = FindPlyProp ( elem, "x" );
|
||
|
yi = FindPlyProp ( elem, "y" );
|
||
|
zi = FindPlyProp ( elem, "z" );
|
||
|
if ( elem == -1 || xi == -1 || yi == -1 || zi == -1 ) {
|
||
|
debug.Printf ( "ERROR: Vertex data not found.\n" );
|
||
|
exit(-1);
|
||
|
}
|
||
|
for (int n=0; n < m_Ply[elem]->num; n++) {
|
||
|
m_File.ReadLine ( buf, 1000 );
|
||
|
for (int j=0; j < m_Ply[elem]->prop_list.size(); j++) {
|
||
|
b.ReadWord ( buf, bword );
|
||
|
m_PlyData[ j ] = atof ( bword );
|
||
|
}
|
||
|
AddVert ( m_PlyData[xi]*s, m_PlyData[zi]*s, m_PlyData[yi]*s );
|
||
|
}
|
||
|
|
||
|
debug.Printf ( " Reading faces..\n" );
|
||
|
elem = FindPlyElem ( PLY_FACES );
|
||
|
xi = FindPlyProp ( elem, "vertex_indices" );
|
||
|
if ( elem == -1 || xi == -1 ) {
|
||
|
debug.Printf ( "ERROR: Face data not found.\n" );
|
||
|
exit(-1);
|
||
|
}
|
||
|
for (int n=0; n < m_Ply[elem]->num; n++) {
|
||
|
m_File.ReadLine ( buf, 1000 );
|
||
|
m_PlyCnt = 0;
|
||
|
for (int j=0; j < m_Ply[elem]->prop_list.size(); j++) {
|
||
|
if ( m_Ply[elem]->prop_list[j].type == PLY_LIST ) {
|
||
|
b.ReadWord ( buf, bword );
|
||
|
cnt = atoi ( bword );
|
||
|
m_PlyData[ m_PlyCnt++ ] = cnt;
|
||
|
for (int c =0; c < cnt; c++) {
|
||
|
b.ReadWord ( buf, bword );
|
||
|
m_PlyData[ m_PlyCnt++ ] = atof ( bword );
|
||
|
}
|
||
|
} else {
|
||
|
b.ReadWord ( buf, bword );
|
||
|
m_PlyData[ m_PlyCnt++ ] = atof ( bword );
|
||
|
}
|
||
|
}
|
||
|
if ( m_PlyData[xi] == 3 ) {
|
||
|
//debug.Printf ( " Face: %d, %d, %d\n", (int) m_PlyData[xi+1], (int) m_PlyData[xi+2], (int) m_PlyData[xi+3] );
|
||
|
AddFaceFast ( (int) m_PlyData[xi+1], (int) m_PlyData[xi+2], (int) m_PlyData[xi+3] );
|
||
|
}
|
||
|
|
||
|
if ( m_PlyData[xi] == 4 ) {
|
||
|
//debug.Printf ( " Face: %d, %d, %d, %d\n", (int) m_PlyData[xi+1], (int) m_PlyData[xi+2], (int) m_PlyData[xi+3], (int) m_PlyData[xi+4]);
|
||
|
AddFaceFast ( (int) m_PlyData[xi+1], (int) m_PlyData[xi+2], (int) m_PlyData[xi+3], (int) m_PlyData[xi+4] );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Measure ();
|
||
|
ComputeNormalsFVF (); // !-- should be abstracted
|
||
|
*/
|
||
|
|
||
|
// UpdateMesh ();
|
||
|
}
|
||
|
|
||
|
void Mesh::AddPlyElement ( char typ, int n )
|
||
|
{
|
||
|
debug.Printf ( " Element: %d, %d\n", typ, n );
|
||
|
PlyElement* p = new PlyElement;
|
||
|
p->num = n;
|
||
|
p->type = typ;
|
||
|
p->prop_list.clear ();
|
||
|
m_PlyCurrElem = m_Ply.size();
|
||
|
m_Ply.push_back ( p );
|
||
|
}
|
||
|
|
||
|
void Mesh::AddPlyProperty ( char typ, std::string name )
|
||
|
{
|
||
|
debug.Printf ( " Property: %d, %s\n", typ, name.c_str() );
|
||
|
PlyProperty p;
|
||
|
p.name = name;
|
||
|
p.type = typ;
|
||
|
m_Ply [ m_PlyCurrElem ]->prop_list.push_back ( p );
|
||
|
}
|