From aeea62cfd0ee594a687effc4ff8e7021235cd0a9 Mon Sep 17 00:00:00 2001 From: cignoni Date: Mon, 8 Nov 2010 15:06:21 +0000 Subject: [PATCH] New version of PTX importer. Added support of direct point cloud loading --- wrap/io_trimesh/import_ptx.h | 193 +++++++++++++++++++---------------- 1 file changed, 104 insertions(+), 89 deletions(-) diff --git a/wrap/io_trimesh/import_ptx.h b/wrap/io_trimesh/import_ptx.h index 3a5ab0ad..773b9aad 100644 --- a/wrap/io_trimesh/import_ptx.h +++ b/wrap/io_trimesh/import_ptx.h @@ -42,6 +42,7 @@ Added comments for documentation #include #include #include +#include #include namespace vcg { @@ -190,12 +191,10 @@ namespace io { bool hascolor; bool savecolor = importparams.savecolor && VertexType::HasColor(); - bool onlypoints = importparams.pointsonly; - bool switchside = importparams.switchside; - bool flipfaces = importparams.flipfaces; + bool switchside = importparams.switchside; int total = 50; - if (onlypoints) total = 100; + if (importparams.pointsonly) total = 100; char linebuf[256]; fscanf(fp,"%i\n",&colnum); @@ -254,34 +253,33 @@ namespace io { (*vi).P()[0]=xx; (*vi).P()[1]=yy; (*vi).P()[2]=zz; - // updating bbox - m.bbox.Add( (*vi).P() ); if(VertexType::HasQuality()) { (*vi).Q()=rf; } - if(hascolor && savecolor) - { - (*vi).C()[0]=rr; - (*vi).C()[1]=gg; - (*vi).C()[2]=bb; - } - else if(!hascolor && savecolor) - { - (*vi).C()[0]=rf*255; - (*vi).C()[1]=rf*255; - (*vi).C()[2]=rf*255; - } + if(savecolor) + { + if(hascolor) + { + (*vi).C()[0]=rr; + (*vi).C()[1]=gg; + (*vi).C()[2]=bb; + } else { + (*vi).C()[0]=rf*255; + (*vi).C()[1]=rf*255; + (*vi).C()[2]=rf*255; + } + } vi++; + if(switchside) std::swap(rownum,colnum); + // now for each line until end of mesh (row*col)-1 for(ii=0; ii<((rownum*colnum)-1); ii++) { - char tmp[255]; - sprintf(tmp, "PTX Mesh Loading..."); - if(cb) cb((ii*total)/vn, tmp); + if(cb && (ii%100)==0) cb((ii*total)/vn, "Vertex Loading"); // read the stream if(hascolor) @@ -294,12 +292,8 @@ namespace io { (*vi).P()[1]=yy; (*vi).P()[2]=zz; - m.bbox.Add( (*vi).P() ); - if(VertexType::HasQuality()) - { - (*vi).Q()=rf; - } + if(tri::HasPerVertexQuality(m)) (*vi).Q()=rf; if(hascolor && savecolor) { @@ -317,13 +311,12 @@ namespace io { vi++; } - if(! onlypoints) + if(! importparams.pointsonly) { // now i can triangulate int trinum = (rownum-1) * (colnum-1) * 2; typename OpenMeshType::FaceIterator fi= Allocator::AddFaces(m,trinum); - m.fn = trinum; - int v0i,v1i,v2i, t; + int v0i,v1i,v2i, t; t=0; for(int rit=0; rit::PerFaceNormalized(m); - for(typename OpenMeshType::FaceIterator fi = m.face.begin(); fi != m.face.end(); fi++) - if(!(*fi).IsD()) - { - raggio = -((*fi).V(0)->P() + (*fi).V(1)->P() + (*fi).V(2)->P()) / 3.0; - raggio.Normalize(); - if((raggio.dot((*fi).N())) < limit) - Allocator::DeleteFace(m,*fi); - - } - } - } + if(m.vert[v0].IsD()) continue; - for(typename OpenMeshType::VertexIterator vi = m.vert.begin(); vi != m.vert.end(); vi++) - { - if(!(*vi).IsD()) - (*vi).P() = currtrasf * (*vi).P(); - } + int vL = (ritL) + ((cit ) * rownum); + int vR = (ritR) + ((cit) * rownum); + int vT = (rit ) + ((citT ) * rownum); + int vB = (rit ) + ((citB) * rownum); - // deleting unreferenced vertices - vcg::tri::Clean::RemoveUnreferencedVertex(m); - vcg::tri::UpdateNormals::PerFaceNormalized(m); - vcg::tri::UpdateBounding::Box(m); + Point3f v0p=m.vert[v0].P(); + Point3f vLp(0,0,0),vRp(0,0,0),vTp(0,0,0),vBp(0,0,0); // Compute the 4 edges around the vertex. + if(!m.vert[vL].IsD()) vLp=(m.vert[vL].P()-v0p).Normalize(); + if(!m.vert[vR].IsD()) vRp=(m.vert[vR].P()-v0p).Normalize(); + if(!m.vert[vT].IsD()) vTp=(m.vert[vT].P()-v0p).Normalize(); + if(!m.vert[vB].IsD()) vBp=(m.vert[vB].P()-v0p).Normalize(); + float r=0; + int rc=0; Point3f v0pn = Normalize(v0p); + // Skip edges that are too steep + // Compute the four normalized vector orthogonal to each pair of consecutive edges. + Point3f vLTn = (vLp ^ vTp).Normalize(); + Point3f vTRn = (vTp ^ vRp).Normalize(); + Point3f vRBn = (vRp ^ vBp).Normalize(); + Point3f vBLn = (vBp ^ vLp).Normalize(); + + // Compute an average Normal skipping null normals and normals that are too steep. + // Compute also the sum of non null edge lenght to compute the radius + Point3f N(0,0,0); + if((vLTn*v0pn)>limitCos) { N+=vLTn; r += Distance(m.vert[vL].P(),v0p)+Distance(m.vert[vT].P(),v0p); rc++; } + if((vTRn*v0pn)>limitCos) { N+=vTRn; r += Distance(m.vert[vT].P(),v0p)+Distance(m.vert[vR].P(),v0p); rc++; } + if((vRBn*v0pn)>limitCos) { N+=vRBn; r += Distance(m.vert[vR].P(),v0p)+Distance(m.vert[vB].P(),v0p); rc++; } + if((vBLn*v0pn)>limitCos) { N+=vBLn; r += Distance(m.vert[vB].P(),v0p)+Distance(m.vert[vL].P(),v0p); rc++; } + + m.vert[v0].N()=-N; + + if(tri::HasPerVertexRadius(m)) m.vert[v0].R() = r/(rc*2.0f); + // Isolated points has null normal. Delete them please. + if(m.vert[v0].N() == Point3f(0,0,0)) Allocator::DeleteVertex(m,m.vert[v0]); + } + } + } + else + // eliminate high angle triangles + { + if(importparams.flipfaces) + tri::Clean::FlipMesh(m); + if(importparams.anglecull) + { + if(cb) cb(85,"PTX Mesh Loading - remove steep faces"); + tri::UpdateNormals::PerFaceNormalized(m); + for(FaceIterator fi = m.face.begin(); fi != m.face.end(); fi++) + if(!(*fi).IsD()) + { + Point3f raggio = -((*fi).P(0) + (*fi).P(1) + (*fi).P(2)) / 3.0; + raggio.Normalize(); + if((raggio.dot((*fi).N())) < limitCos) + Allocator::DeleteFace(m,*fi); + } + // deleting unreferenced vertices only if we are interested in faces... + tri::Clean::RemoveUnreferencedVertex(m); + } + } + + tri::UpdatePosition::Matrix(m,currtrasf,true); + tri::Allocator::CompactVertexVector(m); + tri::UpdateBounding::Box(m); if(cb) cb(100,"PTX Mesh Loading finish!"); return true; } @@ -443,4 +458,4 @@ namespace io { } // end Namespace tri } // end Namespace io } // end Namespace vcg -#endif \ No newline at end of file +#endif