Merge branch 'devel' of https://github.com/cnr-isti-vclab/vcglib into devel
This commit is contained in:
commit
58a9b0eefe
|
@ -19,3 +19,9 @@ release/
|
|||
*.vcxproj
|
||||
*.vcxproj.filters
|
||||
*.suo
|
||||
*.ply
|
||||
wrap/nanoply/nanoply_vcg/nanoply_vcg.sln
|
||||
*.db
|
||||
wrap/nanoply/nanoply_vcg/nanoply_vcg.VC.VC.opendb
|
||||
wrap/nanoply/nanoply_vcg/.vs/nanoply_vcg/v15/ipch/AutoPCH/NANOPLY_VCG-1b6b1a83/MAIN-5f62d91f/MAIN.ipch
|
||||
*.sln
|
||||
|
|
|
@ -296,15 +296,14 @@ int main(int argc, char**argv)
|
|||
// save error files.
|
||||
if(flags & SamplingFlags::SAVE_ERROR)
|
||||
{
|
||||
vcg::tri::io::PlyInfo p;
|
||||
p.mask|=vcg::tri::io::Mask::IOM_VERTCOLOR | vcg::tri::io::Mask::IOM_VERTQUALITY /* | vcg::ply::PLYMask::PM_VERTQUALITY*/ ;
|
||||
int saveMask = vcg::tri::io::Mask::IOM_VERTCOLOR | vcg::tri::io::Mask::IOM_VERTQUALITY /* | vcg::ply::PLYMask::PM_VERTQUALITY*/ ;
|
||||
//p.mask|=vcg::ply::PLYMask::PM_VERTCOLOR|vcg::ply::PLYMask::PM_VERTQUALITY;
|
||||
if(ColorMax!=0 || ColorMin != 0){
|
||||
vcg::tri::UpdateColor<CMesh>::PerVertexQualityRamp(S1,ColorMin,ColorMax);
|
||||
vcg::tri::UpdateColor<CMesh>::PerVertexQualityRamp(S2,ColorMin,ColorMax);
|
||||
}
|
||||
tri::io::ExporterPLY<CMesh>::Save( S1,S1NewName.c_str(),true,p);
|
||||
tri::io::ExporterPLY<CMesh>::Save( S2,S2NewName.c_str(),true,p);
|
||||
tri::io::ExporterPLY<CMesh>::Save( S1,S1NewName.c_str(),saveMask);
|
||||
tri::io::ExporterPLY<CMesh>::Save( S2,S2NewName.c_str(),saveMask);
|
||||
}
|
||||
|
||||
// save error files.
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
TEMPLATE = subdirs
|
||||
SUBDIRS = trimesh_allocate \
|
||||
trimesh_attribute \
|
||||
trimesh_attribute_saving \
|
||||
trimesh_ball_pivoting \
|
||||
trimesh_base \
|
||||
trimesh_closest \
|
||||
|
@ -37,6 +38,7 @@ SUBDIRS = trimesh_allocate \
|
|||
trimesh_smooth \
|
||||
trimesh_split_vertex \
|
||||
trimesh_texture \
|
||||
trimesh_texture_clean \
|
||||
trimesh_topology \
|
||||
trimesh_topological_cut \
|
||||
trimesh_voronoi \
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
include(../common.pri)
|
||||
TARGET = trimesh_attribute
|
||||
SOURCES += trimesh_attribute.cpp ../../../wrap/ply/plylib.cpp
|
||||
SOURCES += trimesh_attribute.cpp
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/****************************************************************************
|
||||
* VCGLib o o *
|
||||
* Visual and Computer Graphics Library o o *
|
||||
* _ O _ *
|
||||
* Copyright(C) 2004-2016 \/)\/ *
|
||||
* Visual Computing Lab /\/| *
|
||||
* ISTI - Italian National Research Council | *
|
||||
* \ *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
|
||||
* for more details. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
/*! \file trimesh_attribute.cpp
|
||||
\ingroup code_sample
|
||||
|
||||
\brief the minimal example of using the attributes
|
||||
|
||||
Attributes are a simple mechanism to associate user-defined 'attributes' to the simplicies and to the mesh.
|
||||
See the page '\ref attributes' for more details.
|
||||
*/
|
||||
|
||||
#include<vcg/complex/complex.h>
|
||||
#include<vcg/complex/algorithms/create/platonic.h>
|
||||
#include<wrap/io_trimesh/export_ply.h>
|
||||
class MyEdge;
|
||||
class MyFace;
|
||||
class MyVertex;
|
||||
struct MyUsedTypes : public vcg::UsedTypes< vcg::Use<MyVertex>::AsVertexType,
|
||||
vcg::Use<MyFace> ::AsFaceType>{};
|
||||
|
||||
class MyVertex : public vcg::Vertex< MyUsedTypes, vcg::vertex::Coord3f,vcg::vertex::Normal3f, vcg::vertex::BitFlags>{};
|
||||
class MyFace : public vcg::Face< MyUsedTypes, vcg::face::VertexRef, vcg::face::Normal3f, vcg::face::BitFlags> {};
|
||||
|
||||
class MyMesh : public vcg::tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace> > {};
|
||||
int main()
|
||||
{
|
||||
MyMesh m;
|
||||
Torus<MyMesh>(m, 3.0f, 1.0f);
|
||||
//! [Adding a few attributes]
|
||||
// add a per-vertex attribute with type float named "GaussianCurvature"
|
||||
MyMesh::PerVertexAttributeHandle<float>
|
||||
hvf = vcg::tri::Allocator<MyMesh>:: GetPerVertexAttribute<float> (m,std::string("GaussianCurvature"));
|
||||
|
||||
MyMesh::PerVertexAttributeHandle<vcg::Point3f>
|
||||
hv3f = vcg::tri::Allocator<MyMesh>:: GetPerVertexAttribute<vcg::Point3f> (m,std::string("InvertedNormal"));
|
||||
|
||||
// add a per-face attribute with type float named "FaceArea"
|
||||
MyMesh::PerFaceAttributeHandle<float>
|
||||
hff = vcg::tri::Allocator<MyMesh>:: GetPerFaceAttribute<float> (m,std::string("FaceArea"));
|
||||
//! [filling the attribute]
|
||||
vcg::tri::Allocator<MyMesh>::ClearPerVertexAttribute<float>(m,hvf, float(M_PI*2));
|
||||
vcg::tri::Allocator<MyMesh>::ClearPerVertexAttribute<vcg::Point3f>(m,hv3f, vcg::Point3f(0,0,0));
|
||||
|
||||
ForEachFace(m, [&](MyFace &f){
|
||||
hff[&f]=vcg::DoubleArea(f)*0.5f;
|
||||
for(int i=0;i<3;++i){
|
||||
hvf[f.V(i)] -= vcg::Angle(f.P1(i)-f.P0(i),f.P2(i)-f.P0(i));
|
||||
hv3f[f.V(i)] -= vcg::NormalizedTriangleNormal(f);
|
||||
}
|
||||
});
|
||||
|
||||
//! [Saving 3 attributes in ply, one of the 3 disguised as quality]
|
||||
vcg::tri::io::PlyInfo pi;
|
||||
pi.AddPerVertexFloatAttribute("GaussianCurvature","quality");
|
||||
pi.AddPerFaceFloatAttribute("FaceArea");
|
||||
pi.AddPerVertexPoint3fAttribute(m,"InvertedNormal");
|
||||
vcg::tri::io::ExporterPLY<MyMesh>::Save(m,"MeshWithCurvature.ply",false,pi);
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
include(../common.pri)
|
||||
TARGET = trimesh_attribute_saving
|
||||
SOURCES += trimesh_attribute_saving.cpp ../../../wrap/ply/plylib.cpp
|
|
@ -102,8 +102,7 @@ int main(int argc, char **argv)
|
|||
printf("Output mesh vn:%i fn:%i\n",m.VN(),m.FN());
|
||||
printf("Created in :%i msec (%i+%i)\n",t2-t0,t1-t0,t2-t1);
|
||||
|
||||
vcg::tri::io::PlyInfo pi;
|
||||
vcg::tri::io::ExporterPLY<MyMesh>::Save(m,argv[2],pi.mask);
|
||||
vcg::tri::io::ExporterPLY<MyMesh>::Save(m,argv[2]);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
|
|
@ -137,8 +137,6 @@ int main(int argc, char **argv)
|
|||
|
||||
printf("Output mesh vn:%i fn:%i\n",m.VN(),m.FN());
|
||||
|
||||
vcg::tri::io::PlyInfo pi;
|
||||
pi.mask|=vcg::tri::io::Mask::IOM_BITPOLYGONAL;
|
||||
vcg::tri::io::Exporter<MyMesh>::Save(m,argv[2],pi.mask);
|
||||
vcg::tri::io::Exporter<MyMesh>::Save(m,argv[2],vcg::tri::io::Mask::IOM_BITPOLYGONAL);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
/****************************************************************************
|
||||
* VCGLib o o *
|
||||
* Visual and Computer Graphics Library o o *
|
||||
* _ O _ *
|
||||
* Copyright(C) 2004-2016 \/)\/ *
|
||||
* Visual Computing Lab /\/| *
|
||||
* ISTI - Italian National Research Council | *
|
||||
* \ *
|
||||
* All rights reserved. *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
|
||||
* for more details. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
#include<vcg/complex/complex.h>
|
||||
|
||||
#include <wrap/io_trimesh/export_obj.h>
|
||||
#include <vcg/complex/algorithms/update/texture.h>
|
||||
#include <vcg/complex/algorithms/create/platonic.h>
|
||||
|
||||
/*! \file trimesh_texture_clean.cpp
|
||||
\ingroup code_sample
|
||||
|
||||
\brief a small example about removing fake texture seams eventually generated by rounding error in a texture param
|
||||
|
||||
*/
|
||||
|
||||
using namespace vcg;
|
||||
|
||||
class MyEdge;
|
||||
class MyFace;
|
||||
class MyVertex;
|
||||
struct MyUsedTypes : public UsedTypes< Use<MyVertex>::AsVertexType, Use<MyFace>::AsFaceType>{};
|
||||
|
||||
class MyVertex : public Vertex< MyUsedTypes, vertex::Coord3f, vertex::VFAdj, vertex::Normal3f, vertex::BitFlags >{};
|
||||
class MyFace : public Face < MyUsedTypes, face::VertexRef, face::VFAdj, face::WedgeTexCoord2f, face::Mark, face::BitFlags > {};
|
||||
class MyMesh : public tri::TriMesh< std::vector<MyVertex>, std::vector<MyFace > >{};
|
||||
|
||||
|
||||
int main(int ,char ** )
|
||||
{
|
||||
MyMesh m;
|
||||
int mask = tri::io::Mask::IOM_WEDGTEXCOORD;
|
||||
|
||||
// generate a simple 2D grid
|
||||
Grid(m,20,20,1,1);
|
||||
// assign it a simple planar parametrization
|
||||
tri:UpdateTexture<MyMesh>::WedgeTexFromPlane(m,Point3f(1.0f,0,0),Point3f(0,1.0f,0),true);
|
||||
tri::io::ExporterOBJ<MyMesh>::Save(m,"grid_0.obj",mask);
|
||||
|
||||
// randomly perturb a few coord textures introducing fake seams
|
||||
for(MyFace &f : m.face)
|
||||
{
|
||||
for(int i=0;i<3;++i)
|
||||
if(rand()%20==0)
|
||||
{
|
||||
f.WT(i).U()+=0.0000001;
|
||||
f.WT(i).V()-=0.0000001;
|
||||
}
|
||||
}
|
||||
tri::io::ExporterOBJ<MyMesh>::Save(m,"grid_1.obj",mask);
|
||||
|
||||
// Merge texture coords that very close
|
||||
tri::UpdateTopology<MyMesh>::VertexFace(m);
|
||||
tri::UpdateTexture<MyMesh>::WedgeTexMergeClose(m);
|
||||
|
||||
tri::io::ExporterOBJ<MyMesh>::Save(m,"grid_2.obj",mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
include(../common.pri)
|
||||
TARGET = trimesh_texture_clean
|
||||
SOURCES += trimesh_texture_clean.cpp
|
||||
|
|
@ -24,6 +24,8 @@
|
|||
#ifndef __VCGLIB_CLEAN
|
||||
#define __VCGLIB_CLEAN
|
||||
|
||||
#include <unordered_set>
|
||||
|
||||
// VCG headers
|
||||
#include <vcg/complex/complex.h>
|
||||
#include <vcg/complex/algorithms/closest.h>
|
||||
|
@ -310,7 +312,7 @@ public:
|
|||
}
|
||||
|
||||
|
||||
/** This function removes that are not referenced by any face or by any edge.
|
||||
/** This function removes vertices that are not referenced by any face or by any edge.
|
||||
@param m The mesh
|
||||
@param DeleteVertexFlag if false prevent the vertex deletion and just count it.
|
||||
@return The number of removed vertices
|
||||
|
@ -583,7 +585,7 @@ public:
|
|||
firstVp++;
|
||||
}
|
||||
|
||||
return ToSplitVec.size();
|
||||
return int(ToSplitVec.size());
|
||||
}
|
||||
|
||||
|
||||
|
@ -1369,7 +1371,7 @@ public:
|
|||
count = 0;
|
||||
|
||||
ScalarType NormalThrRad = math::ToRad(normalThresholdDeg);
|
||||
ScalarType eps = 0.0001; // this epsilon value is in absolute value. It is a distance from edge in baricentric coords.
|
||||
ScalarType eps = ScalarType(0.0001); // this epsilon value is in absolute value. It is a distance from edge in baricentric coords.
|
||||
//detection stage
|
||||
for(FaceIterator fi=m.face.begin();fi!= m.face.end();++fi ) if(!(*fi).IsV())
|
||||
{ Point3<ScalarType> NN = vcg::TriangleNormal((*fi)).Normalize();
|
||||
|
@ -1790,6 +1792,7 @@ public:
|
|||
*/
|
||||
static void SelectFoldedFaceFromOneRingFaces(MeshType &m, ScalarType cosThreshold)
|
||||
{
|
||||
typedef std::unordered_set<VertexPointer> VertexSet;
|
||||
tri::RequireVFAdjacency(m);
|
||||
tri::RequirePerFaceNormal(m);
|
||||
tri::RequirePerVertexNormal(m);
|
||||
|
@ -1803,33 +1806,33 @@ public:
|
|||
#pragma omp parallel for schedule(dynamic, 10)
|
||||
for (int i = 0; i < m.face.size(); i++)
|
||||
{
|
||||
std::vector<typename MeshType::VertexPointer> nearVertex;
|
||||
std::vector<typename MeshType::CoordType> point;
|
||||
typename MeshType::FacePointer f = &m.face[i];
|
||||
VertexSet nearVertex;
|
||||
std::vector<CoordType> pointVec;
|
||||
FacePointer f = &m.face[i];
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
std::vector<typename MeshType::VertexPointer> temp;
|
||||
vcg::face::VVStarVF<typename MeshType::FaceType>(f->V(j), temp);
|
||||
typename std::vector<typename MeshType::VertexPointer>::iterator iter = temp.begin();
|
||||
std::vector<VertexPointer> temp;
|
||||
vcg::face::VVStarVF<FaceType>(f->V(j), temp);
|
||||
typename std::vector<VertexPointer>::iterator iter = temp.begin();
|
||||
for (; iter != temp.end(); iter++)
|
||||
{
|
||||
if ((*iter) != f->V1(j) && (*iter) != f->V2(j))
|
||||
{
|
||||
nearVertex.push_back((*iter));
|
||||
point.push_back((*iter)->P());
|
||||
if (nearVertex.insert((*iter)).second)
|
||||
pointVec.push_back((*iter)->P());
|
||||
}
|
||||
}
|
||||
nearVertex.push_back(f->V(j));
|
||||
point.push_back(f->P(j));
|
||||
nearVertex.insert(f->V(j));
|
||||
pointVec.push_back(f->P(j));
|
||||
}
|
||||
|
||||
if (point.size() > 3)
|
||||
if (pointVec.size() > 3)
|
||||
{
|
||||
vcg::Plane3<typename MeshType::ScalarType> plane;
|
||||
vcg::FitPlaneToPointSet(point, plane);
|
||||
vcg::Plane3<ScalarType> plane;
|
||||
vcg::FitPlaneToPointSet(pointVec, plane);
|
||||
float avgDot = 0;
|
||||
for (int j = 0; j < nearVertex.size(); j++)
|
||||
avgDot += plane.Direction().dot(nearVertex[j]->N());
|
||||
for (auto nvp : nearVertex)
|
||||
avgDot += plane.Direction().dot(nvp->N());
|
||||
avgDot /= nearVertex.size();
|
||||
typename MeshType::VertexType::NormalType normal;
|
||||
if (avgDot < 0)
|
||||
|
|
|
@ -398,7 +398,7 @@ public:
|
|||
{
|
||||
visible.vert[i].P() = m.vert[ind].P();
|
||||
m.vert[ind].SetS();
|
||||
m.vert[ind].C() = Color4b::LightBlue;
|
||||
//m.vert[ind].C() = Color4b::LightBlue;
|
||||
selCnt++;
|
||||
}
|
||||
}
|
||||
|
@ -416,6 +416,8 @@ public:
|
|||
|
||||
tri::Allocator<CHMesh>::CompactEveryVector(visible);
|
||||
tri::Clean<CHMesh>::FlipMesh(visible);
|
||||
tri::UpdateNormal<CHMesh>::PerFaceNormalized(visible);
|
||||
tri::UpdateNormal<CHMesh>::PerVertexNormalized(visible);
|
||||
|
||||
}
|
||||
};
|
||||
|
|
|
@ -99,7 +99,7 @@ template <class MESH> class AdvancingFront {
|
|||
void BuildMesh(CallBackPos call = NULL, int interval = 512)
|
||||
{
|
||||
float finalfacesext = mesh.vert.size() * 2.0f;
|
||||
if(call) call(0, "Advancing front");
|
||||
if (call) (*call)(0, "Advancing front");
|
||||
while(1) {
|
||||
|
||||
for(int i = 0; i < interval; i++) {
|
||||
|
|
|
@ -120,7 +120,7 @@ template <class MESH> class BallPivoting: public AdvancingFront<MESH> {
|
|||
targets.push_back(vp);
|
||||
}
|
||||
|
||||
int n = targets.size();
|
||||
int n = int(targets.size());
|
||||
if(n<3) continue;
|
||||
|
||||
bool success = true;
|
||||
|
@ -205,10 +205,10 @@ template <class MESH> class BallPivoting: public AdvancingFront<MESH> {
|
|||
Mark(vv1);
|
||||
Mark(vv2);
|
||||
|
||||
v0 = tri::Index(this->mesh,vv0);
|
||||
v1 = tri::Index(this->mesh,vv1);
|
||||
v2 = tri::Index(this->mesh,vv2);
|
||||
return true;
|
||||
v0 = int(tri::Index(this->mesh, vv0));
|
||||
v1 = int(tri::Index(this->mesh, vv1));
|
||||
v2 = int(tri::Index(this->mesh, vv2));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ template <class MESH> class BallPivoting: public AdvancingFront<MESH> {
|
|||
if(nn==0) return -1;
|
||||
|
||||
VertexType *candidate = NULL;
|
||||
ScalarType min_angle = M_PI;
|
||||
ScalarType min_angle = ScalarType(M_PI);
|
||||
//
|
||||
// Loop over all the nearest vertexes and choose the best one according the ball pivoting strategy.
|
||||
//
|
||||
|
@ -312,7 +312,7 @@ template <class MESH> class BallPivoting: public AdvancingFront<MESH> {
|
|||
assert((candidate->P() - v1).Norm() > min_edge);
|
||||
}
|
||||
|
||||
int candidateIndex = tri::Index(this->mesh,candidate);
|
||||
int candidateIndex = int(tri::Index(this->mesh,candidate));
|
||||
assert(candidateIndex != edge.v0 && candidateIndex != edge.v1);
|
||||
|
||||
Point3x newnormal = ((candidate->P() - v0)^(v1 - v0)).Normalize();
|
||||
|
|
|
@ -59,7 +59,7 @@ namespace tri {
|
|||
|
||||
// Simple prototype for later use...
|
||||
template<class MeshType>
|
||||
void MCSimplify( MeshType &m, float perc, bool preserveBB=true, vcg::CallBackPos *cb=0);
|
||||
int MCSimplify( MeshType &m, float perc, bool preserveBB=true, vcg::CallBackPos *cb=0);
|
||||
|
||||
|
||||
/** Surface Reconstruction
|
||||
|
@ -550,63 +550,66 @@ template < class MeshType, class VertexPair>
|
|||
|
||||
|
||||
template< class MeshType>
|
||||
void MCSimplify( MeshType &m, float absoluteError, bool preserveBB, vcg::CallBackPos *cb)
|
||||
int MCSimplify( MeshType &m, float absoluteError, bool preserveBB, vcg::CallBackPos *cb)
|
||||
{
|
||||
|
||||
typedef PlyMCTriEdgeCollapse<MeshType,BasicVertexPair<typename MeshType::VertexType> > MyColl;
|
||||
typedef typename MeshType::FaceIterator FaceIterator;
|
||||
typedef typename MeshType::CoordType CoordType;
|
||||
typedef PlyMCTriEdgeCollapse<MeshType,BasicVertexPair<typename MeshType::VertexType> > MyColl;
|
||||
typedef typename MeshType::FaceIterator FaceIterator;
|
||||
typedef typename MeshType::CoordType CoordType;
|
||||
|
||||
|
||||
tri::UpdateBounding<MeshType>::Box(m);
|
||||
tri::UpdateTopology<MeshType>::VertexFace(m);
|
||||
TriEdgeCollapseMCParameter pp;
|
||||
pp.bb.Import(m.bbox);
|
||||
pp.preserveBBox=preserveBB;
|
||||
vcg::LocalOptimization<MeshType> DeciSession(m,&pp);
|
||||
if(absoluteError==0)
|
||||
{
|
||||
tri::UpdateBounding<MeshType>::Box(m);
|
||||
tri::UpdateTopology<MeshType>::VertexFace(m);
|
||||
TriEdgeCollapseMCParameter pp;
|
||||
pp.bb.Import(m.bbox);
|
||||
pp.preserveBBox=preserveBB;
|
||||
vcg::LocalOptimization<MeshType> DeciSession(m,&pp);
|
||||
if(absoluteError==0)
|
||||
{
|
||||
// guess the mc side.
|
||||
// In a MC mesh the vertices are on the egdes of the cells. and the edges are (mostly) on face of the cells.
|
||||
// If you have 2 vert over the same face xy they share z
|
||||
|
||||
std::vector<float> ZSet;
|
||||
for(FaceIterator fi = m.face.begin();fi!=m.face.end();++fi)
|
||||
if(!(*fi).IsD())
|
||||
{
|
||||
CoordType v0=(*fi).V(0)->P();
|
||||
CoordType v1=(*fi).V(1)->P();
|
||||
CoordType v2=(*fi).V(2)->P();
|
||||
if(v0[2]==v1[2] && v0[1]!=v1[1] && v0[0]!=v1[0]) ZSet.push_back(v0[2]);
|
||||
if(v0[2]==v2[2] && v0[1]!=v1[1] && v2[0]!=v2[0]) ZSet.push_back(v0[2]);
|
||||
if(v1[2]==v2[2] && v1[1]!=v1[1] && v2[0]!=v2[0]) ZSet.push_back(v0[2]);
|
||||
if(ZSet.size()>100) break;
|
||||
}
|
||||
std::sort(ZSet.begin(),ZSet.end());
|
||||
std::vector<float>::iterator lastV = std::unique(ZSet.begin(),ZSet.end());
|
||||
ZSet.resize(lastV-ZSet.begin());
|
||||
float Delta=0;
|
||||
for(size_t i = 0; i< ZSet.size()-1;++i)
|
||||
{
|
||||
Delta = std::max(ZSet[i+1]-ZSet[i],Delta);
|
||||
// qDebug("%f",Delta);
|
||||
}
|
||||
absoluteError= Delta/4.0f;
|
||||
}
|
||||
// qDebug("Simplifying at absoluteError=%f",absoluteError);
|
||||
std::vector<float> ZSet;
|
||||
for(FaceIterator fi = m.face.begin();fi!=m.face.end();++fi)
|
||||
if(!(*fi).IsD())
|
||||
{
|
||||
CoordType v0=(*fi).V(0)->P();
|
||||
CoordType v1=(*fi).V(1)->P();
|
||||
CoordType v2=(*fi).V(2)->P();
|
||||
if(v0[2]==v1[2] && v0[1]!=v1[1] && v0[0]!=v1[0]) ZSet.push_back(v0[2]);
|
||||
if(v0[2]==v2[2] && v0[1]!=v2[1] && v0[0]!=v2[0]) ZSet.push_back(v0[2]);
|
||||
if(v1[2]==v2[2] && v1[1]!=v2[1] && v1[0]!=v2[0]) ZSet.push_back(v1[2]);
|
||||
if(ZSet.size()>100) break;
|
||||
}
|
||||
if (ZSet.size() == 0) return -1; //no straight edges found. exit with error
|
||||
std::sort(ZSet.begin(),ZSet.end());
|
||||
std::vector<float>::iterator lastV = std::unique(ZSet.begin(),ZSet.end());
|
||||
ZSet.resize(lastV-ZSet.begin());
|
||||
float Delta=0;
|
||||
for(size_t i = 0; i< ZSet.size()-1;++i)
|
||||
{
|
||||
Delta = std::max(ZSet[i+1]-ZSet[i],Delta);
|
||||
//qDebug("%f",Delta);
|
||||
}
|
||||
absoluteError= Delta/4.0f;
|
||||
}
|
||||
//qDebug("Simplifying at absoluteError=%f",absoluteError);
|
||||
|
||||
float TargetError = absoluteError;
|
||||
char buf[1024];
|
||||
DeciSession.template Init< MyColl > ();
|
||||
float TargetError = absoluteError;
|
||||
char buf[1024];
|
||||
DeciSession.template Init< MyColl > ();
|
||||
|
||||
pp.areaThr=TargetError*TargetError;
|
||||
DeciSession.SetTimeBudget(1.0f);
|
||||
if(TargetError < std::numeric_limits<float>::max() ) DeciSession.SetTargetMetric(TargetError);
|
||||
while(DeciSession.DoOptimization() && DeciSession.currMetric < TargetError)
|
||||
{
|
||||
sprintf(buf,"Simplyfing %7i err %9g \r",m.fn,DeciSession.currMetric);
|
||||
if (cb) cb(int(100.0f*DeciSession.currMetric/TargetError),buf);
|
||||
}
|
||||
pp.areaThr=TargetError*TargetError;
|
||||
DeciSession.SetTimeBudget(1.0f);
|
||||
if(TargetError < std::numeric_limits<float>::max() ) DeciSession.SetTargetMetric(TargetError);
|
||||
while(DeciSession.DoOptimization() && DeciSession.currMetric < TargetError)
|
||||
{
|
||||
sprintf(buf,"Simplyfing %7i err %9g \r",m.fn,DeciSession.currMetric);
|
||||
if (cb) cb(int(100.0f*DeciSession.currMetric/TargetError),buf);
|
||||
}
|
||||
|
||||
return 1; //success
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -27,8 +27,9 @@
|
|||
#include <vcg/complex/algorithms/update/bounding.h>
|
||||
#include <vcg/complex/algorithms/update/component_ep.h>
|
||||
#include <vcg/complex/algorithms/create/marching_cubes.h>
|
||||
#include <vcg/space/index/grid_static_ptr.h>
|
||||
#include <vcg/complex/algorithms/closest.h>
|
||||
//#include <vcg/space/index/grid_static_ptr.h>
|
||||
//#include <vcg/complex/algorithms/closest.h>
|
||||
#include <vcg/space/index/kdtree/kdtree_face.h>
|
||||
|
||||
namespace vcg {
|
||||
namespace tri {
|
||||
|
@ -63,13 +64,15 @@ class Resampler : public BasicGrid<typename NewMeshType::ScalarType>
|
|||
{
|
||||
private:
|
||||
typedef int VertexIndex;
|
||||
typedef typename vcg::GridStaticPtr<OldFaceType, OldScalarType> GridType;
|
||||
//typedef typename vcg::GridStaticPtr<OldFaceType, OldScalarType> GridType;
|
||||
typedef vcg::KdTreeFace<OldMeshType> GridType;
|
||||
|
||||
protected:
|
||||
|
||||
int SliceSize;
|
||||
int CurrentSlice;
|
||||
typedef tri::FaceTmark<OldMeshType> MarkerFace;
|
||||
//typedef tri::FaceTmark<OldMeshType> MarkerFace;
|
||||
typedef vcg::tri::EmptyTMark<OldMeshType> MarkerFace;
|
||||
MarkerFace markerFunctor;
|
||||
|
||||
VertexIndex *_x_cs; // indici dell'intersezioni della superficie lungo gli Xedge della fetta corrente
|
||||
|
@ -159,6 +162,7 @@ class Resampler : public BasicGrid<typename NewMeshType::ScalarType>
|
|||
OldCoordType closestPt;
|
||||
DISTFUNCTOR PDistFunct;
|
||||
OldFaceType *f = _g.GetClosest(PDistFunct,markerFunctor,testPt,max_dist,dist,closestPt);
|
||||
|
||||
if (f==NULL) return field_value(false,0);
|
||||
if(AbsDistFlag) return field_value(true,dist);
|
||||
assert(!f->IsD());
|
||||
|
@ -230,6 +234,7 @@ class Resampler : public BasicGrid<typename NewMeshType::ScalarType>
|
|||
/// the distance of the bb
|
||||
void ComputeSliceValues(int slice,field_value *slice_values)
|
||||
{
|
||||
#pragma omp parallel for schedule(dynamic, 10)
|
||||
for (int i=0; i<=this->siz.X(); i++)
|
||||
{
|
||||
for (int k=0; k<=this->siz.Z(); k++)
|
||||
|
|
|
@ -283,7 +283,7 @@ public:
|
|||
template<class MESH> class MinimumWeightEar : public TrivialEar<MESH>
|
||||
{
|
||||
public:
|
||||
static float &DiedralWeight() { static float _dw=0.1; return _dw;}
|
||||
static float &DiedralWeight() { static float _dw=0.1f; return _dw;}
|
||||
typedef TrivialEar<MESH> TE;
|
||||
typename MESH::ScalarType dihedralRad;
|
||||
typename MESH::ScalarType aspectRatio;
|
||||
|
|
|
@ -179,7 +179,7 @@ public:
|
|||
this->optimalPos = newPos;
|
||||
}
|
||||
|
||||
void Execute(TriMeshType &m, BaseParameterClass */*_pp*/)
|
||||
void Execute(TriMeshType &m, BaseParameterClass * /*_pp*/)
|
||||
{
|
||||
CoordType newPos = this->optimalPos;
|
||||
QH::Qd(this->pos.V(1))+=QH::Qd(this->pos.V(0)); // v0 is deleted and v1 take the new position
|
||||
|
|
|
@ -241,7 +241,7 @@ public:
|
|||
{
|
||||
tri::RequireCompactness(m);
|
||||
h.resize(m.vn);
|
||||
for(int i=0;i<m.vn;++i) h[i]=0;
|
||||
fill(h.begin(),h.end(),0);
|
||||
for(FaceIterator fi=m.face.begin(); fi!=m.face.end();++fi)
|
||||
{
|
||||
ScalarType a = DoubleArea(*fi)/6.0;
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
#include <vcg/space/index/kdtree/kdtree.h>
|
||||
|
||||
|
||||
namespace vcg
|
||||
{
|
||||
|
||||
|
@ -94,7 +93,7 @@ class OutlierRemoval
|
|||
dem += 0.230389 * value * value;
|
||||
dem += 0.000972 * value * value * value;
|
||||
dem += 0.078108 * value * value * value * value;
|
||||
ScalarType op = max(0.0, 1.0 - 1.0 / dem);
|
||||
ScalarType op = std::max(0.0, 1.0 - 1.0 / dem);
|
||||
outlierScore[i] = op;
|
||||
}
|
||||
|
||||
|
|
|
@ -162,7 +162,7 @@ public:
|
|||
for (vi = m.vert.begin(); vi != m.vert.end(); ++vi)
|
||||
if (!(*vi).IsD())
|
||||
{
|
||||
ScalarType weight = useQualityAsWeight ? (*vi).Q() : 1.0;
|
||||
ScalarType weight = useQualityAsWeight ? (*vi).Q() : 1.0f;
|
||||
accumulator[0] += (double)((*vi).P()[0] * weight);
|
||||
accumulator[1] += (double)((*vi).P()[1] * weight);
|
||||
accumulator[2] += (double)((*vi).P()[2] * weight);
|
||||
|
@ -212,6 +212,21 @@ public:
|
|||
return area/ScalarType(2.0);
|
||||
}
|
||||
|
||||
static ScalarType ComputeBorderLength(MeshType & m)
|
||||
{
|
||||
RequireFFAdjacency(m);
|
||||
ScalarType sum = 0;
|
||||
tri::UpdateTopology<MeshType>::FaceFace(m);
|
||||
ForEachFace(m, [&](FaceType &f) {
|
||||
for (int k=0; k<f.VN(); k++)
|
||||
if (face::IsBorder(f, k))
|
||||
{
|
||||
sum += Distance(f.cP(k), f.cP(1));
|
||||
}
|
||||
});
|
||||
return sum;
|
||||
}
|
||||
|
||||
static void ComputePerVertexQualityDistribution( MeshType & m, Distribution<ScalarType> &h, bool selectionOnly = false) // V1.0
|
||||
{
|
||||
tri::RequirePerVertexQuality(m);
|
||||
|
|
|
@ -790,6 +790,7 @@ static Color4b ColorDesaturate(Color4b c, int method)
|
|||
}
|
||||
default: assert(0);
|
||||
}
|
||||
return Color4b(255, 255, 255, 255);
|
||||
}
|
||||
|
||||
//ausiliary function to compute average lightness. value = (R+G+B)/3
|
||||
|
|
|
@ -48,6 +48,7 @@ typedef typename MeshType::VertexIterator VertexIterator;
|
|||
typedef typename MeshType::FaceType FaceType;
|
||||
typedef typename MeshType::FacePointer FacePointer;
|
||||
typedef typename MeshType::FaceIterator FaceIterator;
|
||||
typedef typename vcg::Point2<ScalarType> UVCoordType;
|
||||
|
||||
static void WedgeTexFromPlane(ComputeMeshType &m, const Point3<ScalarType> &uVec, const Point3<ScalarType> &vVec, bool aspectRatio, ScalarType sideGutter=0.0)
|
||||
{
|
||||
|
@ -70,7 +71,7 @@ static void WedgeTexFromPlane(ComputeMeshType &m, const Point3<ScalarType> &uVec
|
|||
|
||||
if (sideGutter>0.0)
|
||||
{
|
||||
ScalarType deltaGutter = std::min(wideU, wideV) * min(sideGutter, (ScalarType)0.5);
|
||||
ScalarType deltaGutter = std::min(wideU, wideV) * std::min(sideGutter, (ScalarType)0.5);
|
||||
|
||||
bb.max[0] += deltaGutter;
|
||||
bb.min[0] -= deltaGutter;
|
||||
|
@ -138,6 +139,40 @@ static void WedgeTexRemoveNull(ComputeMeshType &m, const std::string &texturenam
|
|||
}
|
||||
|
||||
}
|
||||
/** \brief Merge supposedly wrong texcoords
|
||||
* It can happens that for rounding errors texcoords on different wedges but on the same vertex have different tex coords.
|
||||
* This function merges them according a threshold. It requires initialized VF adjacency.
|
||||
* the default for merging is if two textures dist less than one 16th of texel on a 4k texture...
|
||||
*/
|
||||
|
||||
static int WedgeTexMergeClose(ComputeMeshType &m, ScalarType mergeThr = ScalarType(1.0/65536.0) )
|
||||
{
|
||||
tri::RequireVFAdjacency(m);
|
||||
int mergedCnt=0;
|
||||
ForEachVertex(m, [&](VertexType &v){
|
||||
face::VFIterator<FaceType> vfi(&v);
|
||||
std::vector<UVCoordType> clusterVec;
|
||||
clusterVec.push_back(vfi.F()->WT(vfi.I()).P());
|
||||
++vfi;
|
||||
while(!vfi.End())
|
||||
{
|
||||
UVCoordType cur= vfi.F()->WT(vfi.I()).P();
|
||||
bool merged=false;
|
||||
for(auto p:clusterVec) {
|
||||
if(p!=cur && Distance(p,cur) < mergeThr){
|
||||
vfi.F()->WT(vfi.I()).P()=p;
|
||||
++mergedCnt;
|
||||
merged=true;
|
||||
}
|
||||
}
|
||||
if(!merged)
|
||||
clusterVec.push_back(cur);
|
||||
|
||||
++vfi;
|
||||
}
|
||||
});
|
||||
return mergedCnt;
|
||||
}
|
||||
|
||||
}; // end class
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ protected:
|
|||
}
|
||||
|
||||
public:
|
||||
static const int VoroRelaxationStep = 20;
|
||||
static const int VoroRelaxationStep = 30;
|
||||
|
||||
///
|
||||
/// \brief Remesh the main function that remeshes a mesh preserving creases.
|
||||
|
@ -355,7 +355,7 @@ protected:
|
|||
|
||||
// refine to obtain a base mesh
|
||||
VoronoiProcessingParameter vpp;
|
||||
vpp.refinementRatio = 4.0f;
|
||||
vpp.refinementRatio = 5.0f;
|
||||
Voronoi::PreprocessForVoronoi(baseMesh, samplingRadius, vpp);
|
||||
|
||||
// Poisson sampling preserving border
|
||||
|
@ -372,7 +372,15 @@ protected:
|
|||
|
||||
// Montecarlo oversampling
|
||||
Mesh montecarloMesh;
|
||||
int poissonCount = SurfaceSampler::ComputePoissonSampleNum(original, samplingRadius) * 0.7;
|
||||
// const int poissonCount = SurfaceSampler::ComputePoissonSampleNum(original, samplingRadius)/* * 0.7*/;
|
||||
int poissonCount = 0;
|
||||
{
|
||||
const ScalarType meshArea = Stat<Mesh>::ComputeMeshArea(original);
|
||||
const ScalarType meshBoundary = Stat<Mesh>::ComputeBorderLength(original);
|
||||
const double factor = math::Sqrt(3)/2;
|
||||
const ScalarType areaPerSample = samplingRadius*samplingRadius * factor;
|
||||
poissonCount = meshArea / areaPerSample - meshBoundary * samplingRadius * factor * 0.5; // totalArea / (r^2 * sqrt(3)/2) - (totalBoundary * r * sqrt(3)/4)
|
||||
}
|
||||
|
||||
// std::cout << "poisson Count: " << poissonCount << std::endl;
|
||||
if (poissonCount <= 0)
|
||||
|
@ -386,7 +394,7 @@ protected:
|
|||
else
|
||||
{
|
||||
// Montecarlo poisson sampling
|
||||
SurfaceSampler::MontecarloPoisson(original, mps, poissonCount * 20);
|
||||
SurfaceSampler::MontecarloPoisson(original, mps, poissonCount * 40);
|
||||
BuildMeshFromCoordVector(montecarloMesh,sampleVec);
|
||||
|
||||
#ifdef DEBUG_VORO
|
||||
|
@ -421,6 +429,7 @@ protected:
|
|||
vpp.seedPerturbationProbability = 0.0f;
|
||||
Voronoi::RestrictedVoronoiRelaxing(baseMesh, seedPointVec, seedFixedVec, VoroRelaxationStep, vpp);
|
||||
|
||||
|
||||
#ifdef DEBUG_VORO
|
||||
BuildMeshFromCoordVector(poissonMesh,seedPointVec);
|
||||
io::ExporterPLY<MeshType>::Save(poissonMesh, QString("relaxedMesh_%1.ply").arg(idx).toStdString().c_str());
|
||||
|
|
|
@ -1157,12 +1157,12 @@ public:
|
|||
template <class ATTR_TYPE>
|
||||
static
|
||||
void
|
||||
ClearPerVertexAttribute( MeshType & m,typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE> & h){
|
||||
ClearPerVertexAttribute( MeshType & m,typename MeshType::template PerVertexAttributeHandle<ATTR_TYPE> & h, const ATTR_TYPE & initVal = ATTR_TYPE()){
|
||||
typename std::set<PointerToAttribute > ::iterator i;
|
||||
for( i = m.vert_attr.begin(); i != m.vert_attr.end(); ++i)
|
||||
if( (*i)._handle == h._handle ){
|
||||
for(typename MeshType::VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
|
||||
h[vi] = ATTR_TYPE();
|
||||
h[vi] = initVal;
|
||||
return;}
|
||||
assert(0);
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ static void UniformCone(int vn, std::vector<Point3<ScalarType > > &NN, ScalarTyp
|
|||
|
||||
printf("----------AngleRad %f Angledeg %f ratio %f vn %i vn2 %i \n",AngleRad,math::ToDeg(AngleRad),Ratio,vn,int(vn/Ratio));
|
||||
Fibonacci(vn/Ratio,NNT);
|
||||
printf("asked %i got %i (expecting %i instead of %i)\n", int(vn/Ratio), NNT.size(), int(NNT.size()*Ratio), vn);
|
||||
printf("asked %i got %i (expecting %i instead of %i)\n", int(vn/Ratio), int(NNT.size()), int(NNT.size()*Ratio), vn);
|
||||
typename std::vector<Point3<ScalarType> >::iterator vi;
|
||||
|
||||
ScalarType cosAngle = cos(AngleRad);
|
||||
|
|
|
@ -57,18 +57,23 @@ namespace vcg {
|
|||
|
||||
public:
|
||||
|
||||
KdTreeFace(MeshType& mesh, unsigned int maxObjPerCell = 64, unsigned int maxDepth = 64) : epsilon(std::numeric_limits<Scalar>::epsilon())
|
||||
KdTreeFace():epsilon(std::numeric_limits<Scalar>::epsilon())
|
||||
{
|
||||
targetCellSize = 64;
|
||||
targetMaxDepth = 64;
|
||||
};
|
||||
|
||||
KdTreeFace(unsigned int maxObjPerCell, unsigned int maxDepth) : epsilon(std::numeric_limits<Scalar>::epsilon())
|
||||
{
|
||||
targetCellSize = maxObjPerCell;
|
||||
targetMaxDepth = maxDepth;
|
||||
mNodes.resize(1);
|
||||
Node& node = mNodes.back();
|
||||
node.leaf = 0;
|
||||
node.aabb = mesh.bbox;
|
||||
node.aabb.Offset(VectorType(epsilon, epsilon, epsilon));
|
||||
for (int i = 0; i < mesh.face.size(); i++)
|
||||
node.list.push_back(&mesh.face[i]);
|
||||
numLevel = createTree(0, 1);
|
||||
};
|
||||
|
||||
KdTreeFace(MeshType& mesh, unsigned int maxObjPerCell = 64, unsigned int maxDepth = 64, bool onlySelection = false) : epsilon(std::numeric_limits<Scalar>::epsilon())
|
||||
{
|
||||
targetCellSize = maxObjPerCell;
|
||||
targetMaxDepth = maxDepth;
|
||||
Set(mesh.face.begin(), mesh.face.end(), mesh.face.size(), onlySelection);
|
||||
};
|
||||
|
||||
~KdTreeFace()
|
||||
|
@ -76,10 +81,53 @@ namespace vcg {
|
|||
|
||||
};
|
||||
|
||||
|
||||
template <class ObjectMarker> FacePointer doQueryClosest(const VectorType& queryPoint, VectorType& narestPoint, Scalar& dist, ObjectMarker& marker, Scalar maxDist = std::numeric_limits<Scalar>::max())
|
||||
template <class ObjIter>
|
||||
void Set(const ObjIter & _oBegin, const ObjIter & _oEnd, int size = 0, bool onlySelection = false)
|
||||
{
|
||||
if (maxDist < std::numeric_limits<Scalar>::max() && !mNodes[0].aabb.IsIn(queryPoint) && vcg::PointFilledBoxDistance(queryPoint, mNodes[0].aabb) >= maxDist)
|
||||
mNodes.resize(1);
|
||||
Node& node = mNodes.back();
|
||||
node.leaf = 0;
|
||||
node.aabb.Offset(VectorType(epsilon, epsilon, epsilon));
|
||||
Box3<Scalar> box;
|
||||
if (onlySelection)
|
||||
{
|
||||
for (ObjIter i = _oBegin; i != _oEnd; ++i)
|
||||
{
|
||||
if ((*i).IsS())
|
||||
{
|
||||
node.list.push_back(&(*i));
|
||||
box.Add((*i).P(0));
|
||||
box.Add((*i).P(1));
|
||||
box.Add((*i).P(2));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (ObjIter i = _oBegin; i != _oEnd; ++i)
|
||||
{
|
||||
node.list.push_back(&(*i));
|
||||
box.Add((*i).P(0));
|
||||
box.Add((*i).P(1));
|
||||
box.Add((*i).P(2));
|
||||
}
|
||||
}
|
||||
node.aabb = box;
|
||||
numLevel = CreateTree(0, 1);
|
||||
};
|
||||
|
||||
void Clear()
|
||||
{
|
||||
for (int i = 0; i < mNodes.size(); i++)
|
||||
mNodes[i].list.clear();
|
||||
mNodes.clear();
|
||||
};
|
||||
|
||||
//template <class ObjectMarker> FacePointer GetClosest(const VectorType& queryPoint, VectorType& narestPoint, Scalar& dist, ObjectMarker& marker, Scalar maxDist = std::numeric_limits<Scalar>::max())
|
||||
template <class ObjPointDistFunction, class ObjectMarker>
|
||||
FacePointer GetClosest(ObjPointDistFunction& pDistFunc, ObjectMarker& marker, const VectorType& queryPoint, Scalar maxDist, Scalar& dist, VectorType& narestPoint)
|
||||
{
|
||||
if (mNodes.size() == 0|| (maxDist < std::numeric_limits<Scalar>::max() && !mNodes[0].aabb.IsIn(queryPoint) && vcg::PointFilledBoxDistance(queryPoint, mNodes[0].aabb) >= maxDist))
|
||||
{
|
||||
dist = maxDist;
|
||||
return NULL;
|
||||
|
@ -109,7 +157,7 @@ namespace vcg {
|
|||
marker.Mark(node.list[i]);
|
||||
Scalar tempDist = minDist;
|
||||
VectorType tempP;
|
||||
if (vcg::face::PointDistanceBase(*node.list[i], queryPoint, tempDist, tempP))
|
||||
if (pDistFunc(*node.list[i], queryPoint, tempDist, tempP))
|
||||
{
|
||||
if (tempDist < minDist)
|
||||
{
|
||||
|
@ -176,7 +224,7 @@ namespace vcg {
|
|||
};
|
||||
|
||||
|
||||
int createTree(unsigned int nodeId, unsigned int level)
|
||||
int CreateTree(unsigned int nodeId, unsigned int level)
|
||||
{
|
||||
Node& node = mNodes[nodeId];
|
||||
VectorType diag = node.aabb.max - node.aabb.min;
|
||||
|
@ -264,7 +312,7 @@ namespace vcg {
|
|||
else
|
||||
{
|
||||
leftChild.leaf = 0;
|
||||
leftLevel = createTree(firstChildId, level + 1);
|
||||
leftLevel = CreateTree(firstChildId, level + 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -278,7 +326,7 @@ namespace vcg {
|
|||
else
|
||||
{
|
||||
rightChild.leaf = 0;
|
||||
rightLevel = createTree(firstChildId + 1, level + 1);
|
||||
rightLevel = CreateTree(firstChildId + 1, level + 1);
|
||||
}
|
||||
}
|
||||
if (leftLevel > rightLevel)
|
||||
|
|
|
@ -206,7 +206,7 @@ protected:
|
|||
inSphVec.push_back(hi);
|
||||
}
|
||||
}
|
||||
return inSphVec.size();
|
||||
return int(inSphVec.size());
|
||||
}
|
||||
|
||||
size_t RemoveInSphere(const Point3<ScalarType> &p, const ScalarType radius)
|
||||
|
|
|
@ -50,26 +50,26 @@ void ComputeCrossCovarianceMatrix(const std::vector<Point3<S> > &spVec, Point3<S
|
|||
const std::vector<Point3<S> > &tpVec, Point3<S> &tpBarycenter,
|
||||
Eigen::Matrix3d &m)
|
||||
{
|
||||
assert(spVec.size()==tpVec.size());
|
||||
m.setZero();
|
||||
spBarycenter.SetZero();
|
||||
tpBarycenter.SetZero();
|
||||
Eigen::Vector3d spe;
|
||||
Eigen::Vector3d tpe;
|
||||
typename std::vector <Point3<S> >::const_iterator si,ti;
|
||||
for(si=spVec.begin(),ti=tpVec.begin();si!=spVec.end();++si,++ti){
|
||||
spBarycenter+=*si;
|
||||
tpBarycenter+=*ti;
|
||||
si->ToEigenVector(spe);
|
||||
ti->ToEigenVector(tpe);
|
||||
m+=spe*tpe.transpose();
|
||||
}
|
||||
spBarycenter/=spVec.size();
|
||||
tpBarycenter/=tpVec.size();
|
||||
spBarycenter.ToEigenVector(spe);
|
||||
tpBarycenter.ToEigenVector(tpe);
|
||||
m/=spVec.size();
|
||||
m-=spe*tpe.transpose();
|
||||
assert(spVec.size() == tpVec.size());
|
||||
m.setZero();
|
||||
spBarycenter.SetZero();
|
||||
tpBarycenter.SetZero();
|
||||
Eigen::Vector3d spe;
|
||||
Eigen::Vector3d tpe;
|
||||
typename std::vector <Point3<S> >::const_iterator si, ti;
|
||||
for (si = spVec.begin(), ti = tpVec.begin(); si != spVec.end(); ++si, ++ti){
|
||||
spBarycenter += *si;
|
||||
tpBarycenter += *ti;
|
||||
si->ToEigenVector(spe);
|
||||
ti->ToEigenVector(tpe);
|
||||
m += spe*tpe.transpose();
|
||||
}
|
||||
spBarycenter /= double(spVec.size());
|
||||
tpBarycenter /= double(tpVec.size());
|
||||
spBarycenter.ToEigenVector(spe);
|
||||
tpBarycenter.ToEigenVector(tpe);
|
||||
m /= double(spVec.size());
|
||||
m -= spe*tpe.transpose();
|
||||
}
|
||||
|
||||
/*! \brief Compute the roto-translation that applied to PMov bring them onto Pfix
|
||||
|
|
|
@ -760,7 +760,7 @@ namespace Tags
|
|||
class BindVertexInputTag : public XMLTag
|
||||
{
|
||||
public:
|
||||
BindVertexInputTag(const QString& semantic,const QString& input_semantic,const QString& input_set)
|
||||
BindVertexInputTag(const QString& semantic,const QString& input_semantic,const QString& /*input_set*/)
|
||||
:XMLTag("bind_vertex_input")
|
||||
{
|
||||
_attributes.push_back(TagAttribute("semantic",semantic));
|
||||
|
|
|
@ -97,7 +97,7 @@ namespace vcg
|
|||
_perwire_noshading = true;
|
||||
_persolid_noshading = false;
|
||||
|
||||
_perpoint_pointsize = 1.0f;
|
||||
_perpoint_pointsize = 3.0f;
|
||||
_perpoint_pointsmooth_enabled = false;
|
||||
_perpoint_pointattenuation_enabled = true;
|
||||
_perwire_wirewidth = 1.0f;
|
||||
|
@ -296,7 +296,7 @@ namespace vcg
|
|||
if (_glopts != NULL)
|
||||
{
|
||||
std::string tmp;
|
||||
int size = _glopts->serialize(tmp);
|
||||
size_t size = _glopts->serialize(tmp);
|
||||
token[i] = str.substr(pos, size);
|
||||
if (token[i].length() < size)
|
||||
return false;
|
||||
|
@ -1509,7 +1509,7 @@ namespace vcg
|
|||
{
|
||||
//qDebug("Indexed drawing");
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _bo[INT_ATT_NAMES::ATT_VERTINDICES]->_bohandle);
|
||||
glDrawElements(GL_TRIANGLES, _mesh.FN() * _bo[INT_ATT_NAMES::ATT_VERTINDICES]->_components, GL_UNSIGNED_INT, NULL);
|
||||
glDrawElements(GL_TRIANGLES, GLsizei(_mesh.FN() * _bo[INT_ATT_NAMES::ATT_VERTINDICES]->_components), GL_UNSIGNED_INT, NULL);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
|
||||
}
|
||||
|
@ -1819,7 +1819,7 @@ namespace vcg
|
|||
//qDebug("Indexed drawing");
|
||||
updateClientState(req);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _bo[INT_ATT_NAMES::ATT_EDGEINDICES]->_bohandle);
|
||||
glDrawElements(GL_LINES, _edge.size() * _bo[INT_ATT_NAMES::ATT_EDGEINDICES]->_components, GL_UNSIGNED_INT, NULL);
|
||||
glDrawElements(GL_LINES, GLsizei(_edge.size() * _bo[INT_ATT_NAMES::ATT_EDGEINDICES]->_components), GL_UNSIGNED_INT, NULL);
|
||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||
InternalRendAtts tmp;
|
||||
updateClientState(tmp);
|
||||
|
@ -2235,8 +2235,8 @@ namespace vcg
|
|||
assert(nz >= 0);
|
||||
assert(nz < 2);
|
||||
|
||||
_v[0] = size_t(vcg::tri::Index(m, pe->V(nz)));;
|
||||
_v[1] = size_t(vcg::tri::Index(m, pe->V((nz + 1) % 2)));
|
||||
_v[0] = GLuint(vcg::tri::Index(m, pe->V(nz)));;
|
||||
_v[1] = GLuint(vcg::tri::Index(m, pe->V((nz + 1) % 2)));
|
||||
assert(_v[0] != _v[1]); // The face pointed by 'f' is Degenerate (two coincident vertexes)
|
||||
|
||||
if (_v[0] > _v[1])
|
||||
|
|
|
@ -226,7 +226,7 @@ public:
|
|||
//err = glGetError();
|
||||
std::vector<FacePointer> result;
|
||||
PickFace(x,y,m,result,width,height);
|
||||
ScalarType LocalEpsilon(0.001);
|
||||
ScalarType LocalEpsilon(ScalarType(0.001));
|
||||
for(size_t i =0;i<result.size();++i)
|
||||
{
|
||||
CoordType p = glProject(M,vp,CoordType::Construct(Barycenter(*(result[i])))) ;
|
||||
|
|
|
@ -139,7 +139,7 @@ void Rubberband::Render(QGLWidget* gla)
|
|||
assert(!glGetError());
|
||||
}
|
||||
|
||||
void Rubberband::RenderLine(QGLWidget* gla, Point3f AA, Point3f BB)
|
||||
void Rubberband::RenderLine(QGLWidget* /*gla*/, Point3f AA, Point3f BB)
|
||||
{
|
||||
// Drawing of the line from AA to BB
|
||||
glPushAttrib(GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT | GL_LINE_BIT | GL_POINT_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT | GL_COLOR_BUFFER_BIT);
|
||||
|
|
|
@ -234,7 +234,7 @@ namespace io {
|
|||
if(AddDuplexVertexCoord(ListOfDuplexVert,Key(i,t)))
|
||||
{
|
||||
VectorOfVertexType.push_back((*(*fi).V(k)));
|
||||
ListOfDuplexVert[Key(i,t)] = VectorOfVertexType.size()-1;
|
||||
ListOfDuplexVert[Key(i,t)] = int(VectorOfVertexType.size()-1);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,7 +96,6 @@ namespace vcg {
|
|||
static int Save(SaveMeshType &m, const char * filename, bool binary, PlyInfo &pi, CallBackPos *cb=0) // V1.0
|
||||
{
|
||||
FILE * fpout;
|
||||
int i;
|
||||
const char * hbin = "binary_little_endian";
|
||||
const char * hasc = "ascii";
|
||||
const char * h;
|
||||
|
@ -106,7 +105,7 @@ namespace vcg {
|
|||
const int DGTVQ = vcg::tri::io::Precision<typename VertexType::QualityType>::digits();
|
||||
const int DGTVR = vcg::tri::io::Precision<typename VertexType::RadiusType>::digits();
|
||||
const int DGTFQ = vcg::tri::io::Precision<typename FaceType::QualityType>::digits();
|
||||
bool multit = false;
|
||||
bool saveTexIndexFlag = false;
|
||||
|
||||
if(binary) h=hbin;
|
||||
else h=hasc;
|
||||
|
@ -127,10 +126,10 @@ namespace vcg {
|
|||
{
|
||||
const char * TFILE = "TextureFile";
|
||||
|
||||
for(i=0; i < static_cast<int>(m.textures.size()); ++i)
|
||||
for(size_t i=0; i < m.textures.size(); ++i)
|
||||
fprintf(fpout,"comment %s %s\n", TFILE, (const char *)(m.textures[i].c_str()) );
|
||||
|
||||
if(m.textures.size()>1 && (HasPerWedgeTexCoord(m) || HasPerVertexTexCoord(m))) multit = true;
|
||||
if(m.textures.size()>1 && (HasPerWedgeTexCoord(m) || HasPerVertexTexCoord(m))) saveTexIndexFlag = true;
|
||||
}
|
||||
|
||||
if((pi.mask & Mask::IOM_CAMERA))
|
||||
|
@ -211,8 +210,8 @@ namespace vcg {
|
|||
"property float texture_v\n"
|
||||
);
|
||||
}
|
||||
for(i=0;i<pi.vdn;i++)
|
||||
fprintf(fpout,"property %s %s\n",pi.VertexData[i].stotypename(),pi.VertexData[i].propname);
|
||||
for(size_t i=0;i<pi.VertDescriptorVec.size();i++)
|
||||
fprintf(fpout,"property %s %s\n",pi.VertDescriptorVec[i].stotypename(),pi.VertDescriptorVec[i].propname);
|
||||
|
||||
fprintf(fpout,
|
||||
"element face %d\n"
|
||||
|
@ -227,13 +226,21 @@ namespace vcg {
|
|||
);
|
||||
}
|
||||
|
||||
if( (HasPerWedgeTexCoord(m) || HasPerVertexTexCoord(m) ) && pi.mask & Mask::IOM_WEDGTEXCOORD ) // Note that you can save VT as WT if you really want it...
|
||||
if( (HasPerWedgeTexCoord(m) && pi.mask & Mask::IOM_WEDGTEXCOORD ) ||
|
||||
(HasPerVertexTexCoord(m) && (!HasPerWedgeTexCoord(m)) && pi.mask & Mask::IOM_WEDGTEXCOORD ) ) // Note that you can save VT as WT if you really really want it...
|
||||
{
|
||||
fprintf(fpout,
|
||||
"property list uchar float texcoord\n"
|
||||
);
|
||||
|
||||
if(multit)
|
||||
}
|
||||
// The texture index information has to be saved for each face (if necessary) both for PerVert and PerWedg
|
||||
if( saveTexIndexFlag &&
|
||||
( ( HasPerWedgeTexCoord(m) && (pi.mask & Mask::IOM_WEDGTEXCOORD) ) ||
|
||||
( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_VERTTEXCOORD) ) ||
|
||||
( HasPerVertexTexCoord(m) && (!HasPerWedgeTexCoord(m)) && (pi.mask & Mask::IOM_WEDGTEXCOORD) )
|
||||
)
|
||||
)
|
||||
{
|
||||
fprintf(fpout,
|
||||
"property int texnumber\n"
|
||||
);
|
||||
|
@ -262,8 +269,8 @@ namespace vcg {
|
|||
fprintf(fpout,"property %s quality\n",fqtp);
|
||||
}
|
||||
|
||||
for(i=0;i<pi.fdn;i++)
|
||||
fprintf(fpout,"property %s %s\n",pi.FaceData[i].stotypename(),pi.FaceData[i].propname);
|
||||
for(size_t i=0;i<pi.FaceDescriptorVec.size();i++)
|
||||
fprintf(fpout,"property %s %s\n",pi.FaceDescriptorVec[i].stotypename(),pi.FaceDescriptorVec[i].propname);
|
||||
// Saving of edges is enabled if requested
|
||||
if( m.en>0 && (pi.mask & Mask::IOM_EDGEINDEX) )
|
||||
fprintf(fpout,
|
||||
|
@ -345,6 +352,58 @@ namespace vcg {
|
|||
VertexIterator vi;
|
||||
SimpleTempData<typename SaveMeshType::VertContainer,int> indices(m.vert);
|
||||
|
||||
std::vector<typename SaveMeshType:: template PerVertexAttributeHandle<float > > thfv(pi.VertDescriptorVec.size());
|
||||
std::vector<typename SaveMeshType:: template PerVertexAttributeHandle<double> > thdv(pi.VertDescriptorVec.size());
|
||||
std::vector<typename SaveMeshType:: template PerVertexAttributeHandle<int > > thiv(pi.VertDescriptorVec.size());
|
||||
std::vector<typename SaveMeshType:: template PerVertexAttributeHandle<short > > thsv(pi.VertDescriptorVec.size());
|
||||
std::vector<typename SaveMeshType:: template PerVertexAttributeHandle<char > > thcv(pi.VertDescriptorVec.size());
|
||||
std::vector<typename SaveMeshType:: template PerVertexAttributeHandle<unsigned char> > thuv(pi.VertDescriptorVec.size());
|
||||
|
||||
for(size_t i=0;i<pi.VertDescriptorVec.size();i++)
|
||||
{
|
||||
if(!pi.VertAttrNameVec.empty() && !pi.VertAttrNameVec[i].empty())
|
||||
{ // trying to use named attribute to retrieve the value to store
|
||||
assert(vcg::tri::HasPerVertexAttribute(m,pi.VertAttrNameVec[i]));
|
||||
switch (pi.VertDescriptorVec[i].stotype1)
|
||||
{
|
||||
case ply::T_FLOAT : thfv[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerVertexAttribute<float>(m,pi.VertAttrNameVec[i]); break;
|
||||
case ply::T_DOUBLE : thdv[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerVertexAttribute<double>(m,pi.VertAttrNameVec[i]); break;
|
||||
case ply::T_INT : thiv[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerVertexAttribute<int >(m,pi.VertAttrNameVec[i]); break;
|
||||
case ply::T_SHORT : thsv[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerVertexAttribute<short >(m,pi.VertAttrNameVec[i]); break;
|
||||
case ply::T_CHAR : thcv[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerVertexAttribute<char>(m,pi.VertAttrNameVec[i]); break;
|
||||
case ply::T_UCHAR : thuv[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerVertexAttribute<unsigned char>(m,pi.VertAttrNameVec[i]); break;
|
||||
default : assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
std::vector<typename SaveMeshType:: template PerFaceAttributeHandle<float > > thff(pi.FaceDescriptorVec.size());
|
||||
std::vector<typename SaveMeshType:: template PerFaceAttributeHandle<double> > thdf(pi.FaceDescriptorVec.size());
|
||||
std::vector<typename SaveMeshType:: template PerFaceAttributeHandle<int > > thif(pi.FaceDescriptorVec.size());
|
||||
std::vector<typename SaveMeshType:: template PerFaceAttributeHandle<short > > thsf(pi.FaceDescriptorVec.size());
|
||||
std::vector<typename SaveMeshType:: template PerFaceAttributeHandle<char > > thcf(pi.FaceDescriptorVec.size());
|
||||
std::vector<typename SaveMeshType:: template PerFaceAttributeHandle<unsigned char> > thuf(pi.FaceDescriptorVec.size());
|
||||
|
||||
for(size_t i=0;i<pi.FaceDescriptorVec.size();i++)
|
||||
{
|
||||
if(!pi.FaceAttrNameVec.empty() && !pi.FaceAttrNameVec[i].empty())
|
||||
{ // trying to use named attribute to retrieve the value to store
|
||||
assert(vcg::tri::HasPerFaceAttribute(m,pi.FaceAttrNameVec[i]));
|
||||
switch (pi.FaceDescriptorVec[i].stotype1)
|
||||
{
|
||||
case ply::T_FLOAT : thff[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerFaceAttribute<float>(m,pi.FaceAttrNameVec[i]); break;
|
||||
case ply::T_DOUBLE : thdf[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerFaceAttribute<double>(m,pi.FaceAttrNameVec[i]); break;
|
||||
case ply::T_INT : thif[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerFaceAttribute<int >(m,pi.FaceAttrNameVec[i]); break;
|
||||
case ply::T_SHORT : thsf[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerFaceAttribute<short >(m,pi.FaceAttrNameVec[i]); break;
|
||||
case ply::T_CHAR : thcf[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerFaceAttribute<char>(m,pi.FaceAttrNameVec[i]); break;
|
||||
case ply::T_UCHAR : thuf[i] = vcg::tri::Allocator<SaveMeshType>::template FindPerFaceAttribute<unsigned char>(m,pi.FaceAttrNameVec[i]); break;
|
||||
default : assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
for(j=0,vi=m.vert.begin();vi!=m.vert.end();++vi){
|
||||
vp=&(*vi);
|
||||
indices[vi] = j;
|
||||
|
@ -381,22 +440,39 @@ namespace vcg {
|
|||
|
||||
if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_VERTTEXCOORD) )
|
||||
{
|
||||
t = float(vp->T().u()); fwrite(&t,sizeof(float),1,fpout);
|
||||
t = float(vp->T().v()); fwrite(&t,sizeof(float),1,fpout);
|
||||
t = ScalarType(vp->T().u()); fwrite(&t,sizeof(ScalarType),1,fpout);
|
||||
t = ScalarType(vp->T().v()); fwrite(&t,sizeof(ScalarType),1,fpout);
|
||||
}
|
||||
|
||||
for(i=0;i<pi.vdn;i++)
|
||||
for(size_t i=0;i<pi.VertDescriptorVec.size();i++)
|
||||
{
|
||||
double td(0); float tf(0);int ti;short ts; char tc; unsigned char tuc;
|
||||
switch (pi.VertexData[i].stotype1)
|
||||
double td(0); float tf(0);int ti;short ts; char tc; unsigned char tu;
|
||||
if(!pi.VertAttrNameVec.empty() && !pi.VertAttrNameVec[i].empty())
|
||||
{ // trying to use named attribute to retrieve the value to store
|
||||
assert(vcg::tri::HasPerVertexAttribute(m,pi.VertAttrNameVec[i]));
|
||||
switch (pi.VertDescriptorVec[i].stotype1)
|
||||
{
|
||||
case ply::T_FLOAT : tf=thfv[i][vp]; fwrite(&tf, sizeof(float),1,fpout); break;
|
||||
case ply::T_DOUBLE : td=thdv[i][vp]; fwrite(&td, sizeof(double),1,fpout); break;
|
||||
case ply::T_INT : ti=thiv[i][vp]; fwrite(&ti, sizeof(int),1,fpout); break;
|
||||
case ply::T_SHORT : ts=thsv[i][vp]; fwrite(&ts, sizeof(short),1,fpout); break;
|
||||
case ply::T_CHAR : tc=thcv[i][vp]; fwrite(&tc, sizeof(char),1,fpout); break;
|
||||
case ply::T_UCHAR : tu=thuv[i][vp]; fwrite(&tu,sizeof(unsigned char),1,fpout); break;
|
||||
default : assert(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
case ply::T_FLOAT : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, tf ); fwrite(&tf, sizeof(float),1,fpout); break;
|
||||
case ply::T_DOUBLE : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, td ); fwrite(&td, sizeof(double),1,fpout); break;
|
||||
case ply::T_INT : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, ti ); fwrite(&ti, sizeof(int),1,fpout); break;
|
||||
case ply::T_SHORT : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, ts ); fwrite(&ts, sizeof(short),1,fpout); break;
|
||||
case ply::T_CHAR : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, tc ); fwrite(&tc, sizeof(char),1,fpout); break;
|
||||
case ply::T_UCHAR : PlyConv(pi.VertexData[i].memtype1, ((char *)vp)+pi.VertexData[i].offset1, tuc); fwrite(&tuc,sizeof(unsigned char),1,fpout); break;
|
||||
default : assert(0);
|
||||
switch (pi.VertDescriptorVec[i].stotype1)
|
||||
{
|
||||
case ply::T_FLOAT : PlyConv(pi.VertDescriptorVec[i].memtype1, ((char *)vp)+pi.VertDescriptorVec[i].offset1, tf ); fwrite(&tf, sizeof(float),1,fpout); break;
|
||||
case ply::T_DOUBLE : PlyConv(pi.VertDescriptorVec[i].memtype1, ((char *)vp)+pi.VertDescriptorVec[i].offset1, td ); fwrite(&td, sizeof(double),1,fpout); break;
|
||||
case ply::T_INT : PlyConv(pi.VertDescriptorVec[i].memtype1, ((char *)vp)+pi.VertDescriptorVec[i].offset1, ti ); fwrite(&ti, sizeof(int),1,fpout); break;
|
||||
case ply::T_SHORT : PlyConv(pi.VertDescriptorVec[i].memtype1, ((char *)vp)+pi.VertDescriptorVec[i].offset1, ts ); fwrite(&ts, sizeof(short),1,fpout); break;
|
||||
case ply::T_CHAR : PlyConv(pi.VertDescriptorVec[i].memtype1, ((char *)vp)+pi.VertDescriptorVec[i].offset1, tc ); fwrite(&tc, sizeof(char),1,fpout); break;
|
||||
case ply::T_UCHAR : PlyConv(pi.VertDescriptorVec[i].memtype1, ((char *)vp)+pi.VertDescriptorVec[i].offset1, tu ); fwrite(&tu,sizeof(unsigned char),1,fpout); break;
|
||||
default : assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -422,19 +498,35 @@ namespace vcg {
|
|||
if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_VERTTEXCOORD) )
|
||||
fprintf(fpout,"%f %f",vp->T().u(),vp->T().v());
|
||||
|
||||
for(i=0;i<pi.vdn;i++)
|
||||
for(size_t i=0;i<pi.VertDescriptorVec.size();i++)
|
||||
{
|
||||
float tf(0); double td(0);
|
||||
int ti;
|
||||
switch (pi.VertexData[i].memtype1)
|
||||
float tf(0); double td(0); int ti;
|
||||
if(!pi.VertAttrNameVec.empty() && !pi.VertAttrNameVec[i].empty())
|
||||
{ // trying to use named attribute to retrieve the value to store
|
||||
assert(vcg::tri::HasPerVertexAttribute(m,pi.VertAttrNameVec[i]));
|
||||
switch (pi.VertDescriptorVec[i].stotype1)
|
||||
{
|
||||
case ply::T_FLOAT : tf=thfv[i][vp]; fprintf(fpout,"%f ",tf); break;
|
||||
case ply::T_DOUBLE : td=thdv[i][vp]; fprintf(fpout,"%lf ",td); break;
|
||||
case ply::T_INT : ti=thiv[i][vp]; fprintf(fpout,"%i ",ti); break;
|
||||
case ply::T_SHORT : ti=thsv[i][vp]; fprintf(fpout,"%i ",ti); break;
|
||||
case ply::T_CHAR : ti=thcv[i][vp]; fprintf(fpout,"%i ",ti); break;
|
||||
case ply::T_UCHAR : ti=thuv[i][vp]; fprintf(fpout,"%i ",ti); break;
|
||||
default : assert(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
case ply::T_FLOAT : tf=*( (float *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%f ",tf); break;
|
||||
case ply::T_DOUBLE : td=*( (double *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%f ",tf); break;
|
||||
case ply::T_INT : ti=*( (int *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||
case ply::T_SHORT : ti=*( (short *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||
case ply::T_CHAR : ti=*( (char *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||
case ply::T_UCHAR : ti=*( (unsigned char *) (((char *)vp)+pi.VertexData[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||
default : assert(0);
|
||||
switch (pi.VertDescriptorVec[i].memtype1)
|
||||
{
|
||||
case ply::T_FLOAT : tf=*( (float *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%f ",tf); break;
|
||||
case ply::T_DOUBLE : td=*( (double *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%f ",tf); break;
|
||||
case ply::T_INT : ti=*( (int *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||
case ply::T_SHORT : ti=*( (short *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||
case ply::T_CHAR : ti=*( (char *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||
case ply::T_UCHAR : ti=*( (unsigned char *) (((char *)vp)+pi.VertDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||
default : assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -447,9 +539,9 @@ namespace vcg {
|
|||
// this assert triggers when the vn != number of vertexes in vert that are not deleted.
|
||||
assert(j==m.vn);
|
||||
|
||||
char c = 3;
|
||||
unsigned char b9 = 9;
|
||||
unsigned char b6 = 6;
|
||||
unsigned char b3char = 3;
|
||||
unsigned char b9char = 9;
|
||||
unsigned char b6char = 6;
|
||||
FacePointer fp;
|
||||
int vv[3];
|
||||
FaceIterator fi;
|
||||
|
@ -468,15 +560,15 @@ namespace vcg {
|
|||
vv[0]=indices[fp->cV(0)];
|
||||
vv[1]=indices[fp->cV(1)];
|
||||
vv[2]=indices[fp->cV(2)];
|
||||
fwrite(&c,1,1,fpout);
|
||||
fwrite(&b3char,sizeof(char),1,fpout);
|
||||
fwrite(vv,sizeof(int),3,fpout);
|
||||
|
||||
if(HasPerFaceFlags(m)&&( pi.mask & Mask::IOM_FACEFLAGS) )
|
||||
fwrite(&(fp->Flags()),sizeof(int),1,fpout);
|
||||
|
||||
if( HasPerVertexTexCoord(m) && (pi.mask & Mask::IOM_VERTTEXCOORD) )
|
||||
if( HasPerVertexTexCoord(m) && (!HasPerWedgeTexCoord(m)) && (pi.mask & Mask::IOM_WEDGTEXCOORD) ) // Note that you can save VT as WT if you really want it...
|
||||
{
|
||||
fwrite(&b6,sizeof(char),1,fpout);
|
||||
fwrite(&b6char,sizeof(char),1,fpout);
|
||||
float t[6];
|
||||
for(int k=0;k<3;++k)
|
||||
{
|
||||
|
@ -487,7 +579,7 @@ namespace vcg {
|
|||
}
|
||||
else if( HasPerWedgeTexCoord(m) && (pi.mask & Mask::IOM_WEDGTEXCOORD) )
|
||||
{
|
||||
fwrite(&b6,sizeof(char),1,fpout);
|
||||
fwrite(&b6char,sizeof(char),1,fpout);
|
||||
float t[6];
|
||||
for(int k=0;k<3;++k)
|
||||
{
|
||||
|
@ -497,7 +589,7 @@ namespace vcg {
|
|||
fwrite(t,sizeof(float),6,fpout);
|
||||
}
|
||||
|
||||
if(multit)
|
||||
if(saveTexIndexFlag)
|
||||
{
|
||||
int t = fp->WT(0).n();
|
||||
fwrite(&t,sizeof(int),1,fpout);
|
||||
|
@ -509,7 +601,7 @@ namespace vcg {
|
|||
|
||||
if( HasPerWedgeColor(m) && (pi.mask & Mask::IOM_WEDGCOLOR) )
|
||||
{
|
||||
fwrite(&b9,sizeof(char),1,fpout);
|
||||
fwrite(&b9char,sizeof(char),1,fpout);
|
||||
float t[3];
|
||||
for(int z=0;z<3;++z)
|
||||
{
|
||||
|
@ -524,17 +616,34 @@ namespace vcg {
|
|||
fwrite( &(fp->Q()),sizeof(typename FaceType::ScalarType),1,fpout);
|
||||
|
||||
|
||||
for(i=0;i<pi.fdn;i++)
|
||||
for(size_t i=0;i<pi.FaceDescriptorVec.size();i++)
|
||||
{
|
||||
double td(0); float tf(0);int ti;short ts; char tc; unsigned char tuc;
|
||||
switch (pi.FaceData[i].stotype1){
|
||||
case ply::T_FLOAT : PlyConv(pi.FaceData[i].memtype1, ((char *)fp)+pi.FaceData[i].offset1, tf ); fwrite(&tf, sizeof(float),1,fpout); break;
|
||||
case ply::T_DOUBLE : PlyConv(pi.FaceData[i].memtype1, ((char *)fp)+pi.FaceData[i].offset1, td ); fwrite(&td, sizeof(double),1,fpout); break;
|
||||
case ply::T_INT : PlyConv(pi.FaceData[i].memtype1, ((char *)fp)+pi.FaceData[i].offset1, ti ); fwrite(&ti, sizeof(int),1,fpout); break;
|
||||
case ply::T_SHORT : PlyConv(pi.FaceData[i].memtype1, ((char *)fp)+pi.FaceData[i].offset1, ts ); fwrite(&ts, sizeof(short),1,fpout); break;
|
||||
case ply::T_CHAR : PlyConv(pi.FaceData[i].memtype1, ((char *)fp)+pi.FaceData[i].offset1, tc ); fwrite(&tc, sizeof(char),1,fpout); break;
|
||||
case ply::T_UCHAR : PlyConv(pi.FaceData[i].memtype1, ((char *)fp)+pi.FaceData[i].offset1, tuc); fwrite(&tuc,sizeof(unsigned char),1,fpout); break;
|
||||
default : assert(0);
|
||||
double td(0); float tf(0);int ti;short ts; char tc; unsigned char tu;
|
||||
if(!pi.FaceAttrNameVec.empty() && !pi.FaceAttrNameVec[i].empty())
|
||||
{ // trying to use named attribute to retrieve the value to store
|
||||
assert(vcg::tri::HasPerFaceAttribute(m,pi.FaceAttrNameVec[i]));
|
||||
switch (pi.FaceDescriptorVec[i].stotype1)
|
||||
{
|
||||
case ply::T_FLOAT : tf=thff[i][fp]; fwrite(&tf, sizeof(float),1,fpout); break;
|
||||
case ply::T_DOUBLE : td=thdf[i][fp]; fwrite(&td, sizeof(double),1,fpout); break;
|
||||
case ply::T_INT : ti=thif[i][fp]; fwrite(&ti, sizeof(int),1,fpout); break;
|
||||
case ply::T_SHORT : ts=thsf[i][fp]; fwrite(&ts, sizeof(short),1,fpout); break;
|
||||
case ply::T_CHAR : tc=thcf[i][fp]; fwrite(&tc, sizeof(char),1,fpout); break;
|
||||
case ply::T_UCHAR : tu=thuf[i][fp]; fwrite(&tu,sizeof(unsigned char),1,fpout); break;
|
||||
default : assert(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (pi.FaceDescriptorVec[i].stotype1){
|
||||
case ply::T_FLOAT : PlyConv(pi.FaceDescriptorVec[i].memtype1, ((char *)fp)+pi.FaceDescriptorVec[i].offset1, tf ); fwrite(&tf, sizeof(float),1,fpout); break;
|
||||
case ply::T_DOUBLE : PlyConv(pi.FaceDescriptorVec[i].memtype1, ((char *)fp)+pi.FaceDescriptorVec[i].offset1, td ); fwrite(&td, sizeof(double),1,fpout); break;
|
||||
case ply::T_INT : PlyConv(pi.FaceDescriptorVec[i].memtype1, ((char *)fp)+pi.FaceDescriptorVec[i].offset1, ti ); fwrite(&ti, sizeof(int),1,fpout); break;
|
||||
case ply::T_SHORT : PlyConv(pi.FaceDescriptorVec[i].memtype1, ((char *)fp)+pi.FaceDescriptorVec[i].offset1, ts ); fwrite(&ts, sizeof(short),1,fpout); break;
|
||||
case ply::T_CHAR : PlyConv(pi.FaceDescriptorVec[i].memtype1, ((char *)fp)+pi.FaceDescriptorVec[i].offset1, tc ); fwrite(&tc, sizeof(char),1,fpout); break;
|
||||
case ply::T_UCHAR : PlyConv(pi.FaceDescriptorVec[i].memtype1, ((char *)fp)+pi.FaceDescriptorVec[i].offset1, tu ); fwrite(&tu, sizeof(unsigned char),1,fpout); break;
|
||||
default : assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -566,7 +675,7 @@ namespace vcg {
|
|||
);
|
||||
}
|
||||
|
||||
if(multit)
|
||||
if(saveTexIndexFlag)
|
||||
{
|
||||
fprintf(fpout,"%d ",fp->WT(0).n());
|
||||
}
|
||||
|
@ -589,20 +698,36 @@ namespace vcg {
|
|||
if( HasPerFaceQuality(m) && (pi.mask & Mask::IOM_FACEQUALITY) )
|
||||
fprintf(fpout,"%.*g ",DGTFQ,fp->Q());
|
||||
|
||||
for(i=0;i<pi.fdn;i++)
|
||||
for(size_t i=0;i<pi.FaceDescriptorVec.size();i++)
|
||||
{
|
||||
float tf(0); double td(0);
|
||||
int ti;
|
||||
switch (pi.FaceData[i].memtype1)
|
||||
float tf(0); double td(0); int ti;
|
||||
if(!pi.FaceAttrNameVec.empty() && !pi.FaceAttrNameVec[i].empty())
|
||||
{ // trying to use named attribute to retrieve the value to store
|
||||
assert(vcg::tri::HasPerFaceAttribute(m,pi.FaceAttrNameVec[i]));
|
||||
switch (pi.FaceDescriptorVec[i].stotype1)
|
||||
{
|
||||
case ply::T_FLOAT : tf=*( (float *) (((char *)fp)+pi.FaceData[i].offset1)); fprintf(fpout,"%g ",tf); break;
|
||||
case ply::T_DOUBLE : td=*( (double *) (((char *)fp)+pi.FaceData[i].offset1)); fprintf(fpout,"%g ",tf); break;
|
||||
case ply::T_INT : ti=*( (int *) (((char *)fp)+pi.FaceData[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||
case ply::T_SHORT : ti=*( (short *) (((char *)fp)+pi.FaceData[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||
case ply::T_CHAR : ti=*( (char *) (((char *)fp)+pi.FaceData[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||
case ply::T_UCHAR : ti=*( (unsigned char *) (((char *)fp)+pi.FaceData[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||
case ply::T_FLOAT : tf=thff[i][fp]; fprintf(fpout,"%f ",tf); break;
|
||||
case ply::T_DOUBLE : td=thdf[i][fp]; fprintf(fpout,"%g ",td); break;
|
||||
case ply::T_INT : ti=thif[i][fp]; fprintf(fpout,"%i ",ti); break;
|
||||
case ply::T_SHORT : ti=thsf[i][fp]; fprintf(fpout,"%i ",ti); break;
|
||||
case ply::T_CHAR : ti=thcf[i][fp]; fprintf(fpout,"%i ",ti); break;
|
||||
case ply::T_UCHAR : ti=thuf[i][fp]; fprintf(fpout,"%i ",ti); break;
|
||||
default : assert(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (pi.FaceDescriptorVec[i].memtype1)
|
||||
{
|
||||
case ply::T_FLOAT : tf=*( (float *) (((char *)fp)+pi.FaceDescriptorVec[i].offset1)); fprintf(fpout,"%g ",tf); break;
|
||||
case ply::T_DOUBLE : td=*( (double *) (((char *)fp)+pi.FaceDescriptorVec[i].offset1)); fprintf(fpout,"%g ",tf); break;
|
||||
case ply::T_INT : ti=*( (int *) (((char *)fp)+pi.FaceDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||
case ply::T_SHORT : ti=*( (short *) (((char *)fp)+pi.FaceDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||
case ply::T_CHAR : ti=*( (char *) (((char *)fp)+pi.FaceDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||
case ply::T_UCHAR : ti=*( (unsigned char *) (((char *)fp)+pi.FaceDescriptorVec[i].offset1)); fprintf(fpout,"%i ",ti); break;
|
||||
default : assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(fpout,"\n");
|
||||
|
|
|
@ -65,7 +65,7 @@ namespace vcg {
|
|||
typedef typename SaveMeshType::FaceIterator FaceIterator;
|
||||
|
||||
///Standard call for saving a mesh
|
||||
static int Save(SaveMeshType &m, const char * filename, const int &mask, CallBackPos */*cb=0*/)
|
||||
static int Save(SaveMeshType &m, const char * filename, const int &mask, CallBackPos * /*cb=0*/)
|
||||
{
|
||||
FILE *fp;
|
||||
fp = fopen(filename,"wb");
|
||||
|
|
|
@ -87,7 +87,7 @@ static const char* ErrorMsg(int error)
|
|||
};
|
||||
|
||||
|
||||
static int Open( OpenMeshType &m, const char * filename, int &loadmask, CallBackPos */*cb*/=0)
|
||||
static int Open( OpenMeshType &m, const char * filename, int &loadmask, CallBackPos * /*cb*/=0)
|
||||
{
|
||||
CTMcontext context;
|
||||
|
||||
|
|
|
@ -154,7 +154,7 @@ static int Open( OpenMeshType &m, std::vector<Shot<ScalarType> > & shots,
|
|||
shots[i].Intrinsics.FocalMm = f/100.0f;
|
||||
shots[i].Intrinsics.k[0] = 0.0;//k1; To be uncommented when distortion is taken into account reliably
|
||||
shots[i].Intrinsics.k[1] = 0.0;//k2;
|
||||
shots[i].Intrinsics.PixelSizeMm = vcg::Point2<ScalarType>(0.01,0.01);
|
||||
shots[i].Intrinsics.PixelSizeMm = vcg::Point2<ScalarType>(ScalarType(0.01), ScalarType(0.01));
|
||||
QImageReader sizeImg(QString::fromStdString(image_filenames[i]));
|
||||
QSize size=sizeImg.size();
|
||||
shots[i].Intrinsics.ViewportPx = vcg::Point2i(size.width(),size.height());
|
||||
|
|
|
@ -615,6 +615,15 @@ namespace vcg {
|
|||
}
|
||||
else if ((header.compare("usemtl")==0) && (tokens.size() > 1)) // material usage
|
||||
{
|
||||
// emergency check. If there are no materials, the materail library failed to load or was not specified
|
||||
// but there are tools that save the material library with the same name of the file, but do not add the
|
||||
// "mtllib" definition in the header. So, we can try to see if this is the case
|
||||
if ((materials.size() == 1)&&(materials[0].materialName == "")){
|
||||
std::string materialFileName(filename);
|
||||
materialFileName.replace(materialFileName.end()-4, materialFileName.end(), ".mtl");
|
||||
LoadMaterials(materialFileName.c_str(), materials, m.textures);
|
||||
}
|
||||
|
||||
std::string materialName;
|
||||
if (tokens.size() == 2)
|
||||
materialName = tokens[1]; //play it safe
|
||||
|
@ -887,6 +896,7 @@ namespace vcg {
|
|||
oi.numNormals=0;
|
||||
int lineCount=0;
|
||||
int totRead=0;
|
||||
bool firstV = true;
|
||||
std::string line;
|
||||
while (!stream.eof())
|
||||
{
|
||||
|
@ -899,11 +909,20 @@ namespace vcg {
|
|||
{
|
||||
if(line[0]=='v')
|
||||
{
|
||||
if(line[1]==' ')
|
||||
if ((line[1] == ' ') || (line[1] == '\t'))
|
||||
{
|
||||
oi.numVertices++;
|
||||
if(line.size()>=7)
|
||||
bHasPerVertexColor = true;
|
||||
if (firstV)
|
||||
{
|
||||
int sepN = 0;
|
||||
for (size_t lit = 0; lit < line.size(); lit++){
|
||||
if ((line[lit] == ' ') || (line[lit] == '\t'))
|
||||
sepN++;
|
||||
}
|
||||
if (sepN >= 6)
|
||||
bHasPerVertexColor = true;
|
||||
firstV = false;
|
||||
}
|
||||
}
|
||||
if(line[1]=='t') oi.numTexCoords++;
|
||||
if(line[1]=='n') {
|
||||
|
@ -930,8 +949,8 @@ namespace vcg {
|
|||
// Usually if you have tex coords you also have materials
|
||||
oi.mask |= vcg::tri::io::Mask::IOM_FACECOLOR;
|
||||
}
|
||||
if(bHasPerFaceColor) oi.mask |= vcg::tri::io::Mask::IOM_FACECOLOR;
|
||||
if(bHasPerVertexColor) oi.mask |= vcg::tri::io::Mask::IOM_VERTCOLOR;
|
||||
if(bHasPerFaceColor) oi.mask |= vcg::tri::io::Mask::IOM_FACECOLOR;
|
||||
if(bHasPerVertexColor) oi.mask |= vcg::tri::io::Mask::IOM_VERTCOLOR;
|
||||
if (bHasNormals) {
|
||||
if (oi.numNormals == oi.numVertices)
|
||||
oi.mask |= vcg::tri::io::Mask::IOM_VERTNORMAL;
|
||||
|
|
|
@ -210,8 +210,8 @@ static const PropDescriptor &FaceDesc(int i)
|
|||
/* 5 */ {"face", "texnumber", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,texcoordind), 0,0,0,0,0 ,0},
|
||||
/* 6 */ {"face", "red" , ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,r), 0,0,0,0,0 ,0},
|
||||
/* 7 */ {"face", "green", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,g), 0,0,0,0,0 ,0},
|
||||
/* 8 */ {"face", "blue", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,b), 0,0,0,0,0 ,0},
|
||||
/* 9 */ {"face", "alpha", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,a), 0,0,0,0,0 ,0},
|
||||
/* 8 */ {"face", "blue", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,b), 0,0,0,0,0 ,0},
|
||||
/* 9 */ {"face", "alpha", ply::T_UCHAR, ply::T_UCHAR, offsetof(LoadPly_FaceAux,a), 0,0,0,0,0 ,0},
|
||||
/* 10 */ {"face", "vertex_index", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_UCHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0},
|
||||
/* 11 */ {"face", "vertex_index", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_CHAR, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0},
|
||||
/* 12 */ {"face", "vertex_index", ply::T_INT, ply::T_INT, offsetof(LoadPly_FaceAux,v), 1,0,ply::T_INT, ply::T_CHAR,offsetof(LoadPly_FaceAux,size) ,0},
|
||||
|
@ -547,15 +547,15 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
|
|||
}
|
||||
|
||||
// User defined descriptors
|
||||
std::vector<PropDescriptor> VPV(pi.vdn); // property descriptor relative al tipo LoadPly_VertexAux
|
||||
std::vector<PropDescriptor> FPV(pi.fdn); // property descriptor relative al tipo LoadPly_FaceAux
|
||||
if(pi.vdn>0){
|
||||
std::vector<PropDescriptor> VPV(pi.VertDescriptorVec.size()); // property descriptor relative al tipo LoadPly_VertexAux
|
||||
std::vector<PropDescriptor> FPV(pi.FaceDescriptorVec.size()); // property descriptor relative al tipo LoadPly_FaceAux
|
||||
if(pi.VertDescriptorVec.size()>0){
|
||||
// Compute the total size needed to load additional per vertex data.
|
||||
size_t totsz=0;
|
||||
for(int i=0;i<pi.vdn;i++){
|
||||
VPV[i] = pi.VertexData[i];
|
||||
for(size_t i=0;i<pi.VertDescriptorVec.size();i++){
|
||||
VPV[i] = pi.VertDescriptorVec[i];
|
||||
VPV[i].offset1=offsetof(LoadPly_VertAux<ScalarType>,data)+totsz;
|
||||
totsz+=pi.VertexData[i].memtypesize();
|
||||
totsz+=pi.VertDescriptorVec[i].memtypesize();
|
||||
if( pf.AddToRead(VPV[i])==-1 ) { pi.status = pf.GetError(); return pi.status; }
|
||||
}
|
||||
if(totsz > MAX_USER_DATA)
|
||||
|
@ -564,12 +564,12 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
|
|||
return pi.status;
|
||||
}
|
||||
}
|
||||
if(pi.fdn>0){
|
||||
if(pi.FaceDescriptorVec.size()>0){
|
||||
size_t totsz=0;
|
||||
for(int i=0;i<pi.fdn;i++){
|
||||
FPV[i] = pi.FaceData[i];
|
||||
for(size_t i=0;i<pi.FaceDescriptorVec.size();i++){
|
||||
FPV[i] = pi.FaceDescriptorVec[i];
|
||||
FPV[i].offset1=offsetof(LoadPly_FaceAux,data)+totsz;
|
||||
totsz+=pi.FaceData[i].memtypesize();
|
||||
totsz+=pi.FaceDescriptorVec[i].memtypesize();
|
||||
if( pf.AddToRead(FPV[i])==-1 ) { pi.status = pf.GetError(); return pi.status; }
|
||||
}
|
||||
if(totsz > MAX_USER_DATA)
|
||||
|
@ -583,7 +583,7 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
|
|||
/* Main Reading Loop */
|
||||
/**************************************************************/
|
||||
m.Clear();
|
||||
for(int i=0;i<int(pf.elements.size());i++)
|
||||
for(size_t i=0;i<pf.elements.size();i++)
|
||||
{
|
||||
int n = pf.ElemNumber(i);
|
||||
|
||||
|
@ -695,8 +695,8 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
|
|||
(*vi).R() = va.radius;
|
||||
|
||||
|
||||
for(int k=0;k<pi.vdn;k++)
|
||||
memcpy((char *)(&*vi) + pi.VertexData[k].offset1,
|
||||
for(size_t k=0;k<pi.VertDescriptorVec.size();k++)
|
||||
memcpy((char *)(&*vi) + pi.VertDescriptorVec[k].offset1,
|
||||
(char *)(&va) + VPV[k].offset1,
|
||||
VPV[k].memtypesize());
|
||||
++vi;
|
||||
|
@ -756,7 +756,7 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
|
|||
}
|
||||
}
|
||||
|
||||
if(HasPolyInfo(m)) (*fi).Alloc(3);
|
||||
if(HasPolyInfo(m)) (*fi).Alloc(fa.size);
|
||||
|
||||
if(HasPerFaceFlags(m) &&( pi.mask & Mask::IOM_FACEFLAGS) )
|
||||
{
|
||||
|
@ -805,6 +805,22 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
|
|||
(*fi).C()[2] = (unsigned char)((fa.colors[0*3+2]*255+fa.colors[1*3+2]*255+fa.colors[2*3+2]*255)/3.0f);
|
||||
}
|
||||
}
|
||||
|
||||
if (HasPolyInfo(m))
|
||||
{
|
||||
for(k=0; k<fa.size; ++k)
|
||||
{
|
||||
if( fa.v[k]<0 || fa.v[k]>=m.vn )
|
||||
{
|
||||
pi.status = PlyInfo::E_BAD_VERT_INDEX;
|
||||
return pi.status;
|
||||
}
|
||||
(*fi).V(k) = index[ fa.v[k] ];
|
||||
}
|
||||
fi++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/// Now the temporary struct 'fa' is ready to be copied into the real face '*fi'
|
||||
/// This loop
|
||||
for(k=0;k<3;++k)
|
||||
|
@ -820,8 +836,8 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
|
|||
// tag faux vertices of first face
|
||||
if (fa.size>3) fi->SetF(2);
|
||||
|
||||
for(k=0;k<pi.fdn;k++)
|
||||
memcpy((char *)(&(*fi)) + pi.FaceData[k].offset1,
|
||||
for(size_t k=0;k<pi.FaceDescriptorVec.size();k++)
|
||||
memcpy((char *)(&(*fi)) + pi.FaceDescriptorVec[k].offset1,
|
||||
(char *)(&fa) + FPV[k].offset1,
|
||||
FPV[k].memtypesize());
|
||||
|
||||
|
@ -861,8 +877,8 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
|
|||
fi->SetF(0);
|
||||
if(qq<(fa.size-4)) fi->SetF(2);
|
||||
|
||||
for(k=0;k<pi.fdn;k++)
|
||||
memcpy((char *)(&(*fi)) + pi.FaceData[k].offset1,
|
||||
for(size_t k=0;k<pi.FaceDescriptorVec.size();k++)
|
||||
memcpy((char *)(&(*fi)) + pi.FaceDescriptorVec[k].offset1,
|
||||
(char *)(&fa) + FPV[k].offset1, FPV[k].memtypesize());
|
||||
++fi;
|
||||
}
|
||||
|
@ -911,7 +927,7 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
|
|||
//qDebug("Starting Reading of Range Grid");
|
||||
if(RangeGridCols==0) // not initialized.
|
||||
{
|
||||
for(int co=0;co<int(pf.comments.size());++co)
|
||||
for(size_t co=0;co< pf.comments.size();++co)
|
||||
{
|
||||
std::string num_cols = "num_cols";
|
||||
std::string num_rows = "num_rows";
|
||||
|
@ -974,20 +990,20 @@ static int Open( OpenMeshType &m, const char * filename, PlyInfo &pi )
|
|||
m.textures.clear();
|
||||
m.normalmaps.clear();
|
||||
|
||||
for(int co=0;co<int(pf.comments.size());++co)
|
||||
for(size_t co=0;co<pf.comments.size();++co)
|
||||
{
|
||||
std::string TFILE = "TextureFile";
|
||||
std::string NFILE = "TextureNormalFile";
|
||||
std::string &c = pf.comments[co];
|
||||
// char buf[256];
|
||||
std::string bufstr,bufclean;
|
||||
int i,n;
|
||||
int n;
|
||||
|
||||
if( TFILE == c.substr(0,TFILE.length()) )
|
||||
{
|
||||
bufstr = c.substr(TFILE.length()+1);
|
||||
n = static_cast<int>(bufstr.length());
|
||||
for(i=0;i<n;i++)
|
||||
for(int i=0;i<n;i++)
|
||||
if( bufstr[i]!=' ' && bufstr[i]!='\t' && bufstr[i]>32 && bufstr[i]<125 ) bufclean.push_back(bufstr[i]);
|
||||
|
||||
char buf2[255];
|
||||
|
@ -1036,8 +1052,7 @@ int LoadCamera(const char * filename)
|
|||
|
||||
|
||||
bool found = true;
|
||||
int i;
|
||||
for(i=0;i<23;++i)
|
||||
for(int i=0;i<23;++i)
|
||||
{
|
||||
if( pf.AddToRead(CameraDesc(i))==-1 )
|
||||
{
|
||||
|
@ -1049,7 +1064,7 @@ int LoadCamera(const char * filename)
|
|||
if(!found)
|
||||
return this->pi.status;
|
||||
|
||||
for(i=0;i<int(pf.elements.size());i++)
|
||||
for(size_t i=0;i<pf.elements.size();i++)
|
||||
{
|
||||
int n = pf.ElemNumber(i);
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#ifndef __VCGLIB_IMPORT_STL
|
||||
#define __VCGLIB_IMPORT_STL
|
||||
#include <stdio.h>
|
||||
#include<algorithm>
|
||||
#include <wrap/io_trimesh/io_mask.h>
|
||||
|
||||
namespace vcg {
|
||||
|
@ -60,10 +61,11 @@ public:
|
|||
};
|
||||
|
||||
enum STLError {
|
||||
E_NOERROR, // 0
|
||||
// Errori di open
|
||||
E_CANTOPEN, // 1
|
||||
E_UNESPECTEDEOF // 2
|
||||
E_NOERROR, // 0
|
||||
E_CANTOPEN, // 1
|
||||
E_UNESPECTEDEOF, // 2
|
||||
E_MALFORMED, // 3
|
||||
E_LAST
|
||||
};
|
||||
|
||||
static const char *ErrorMsg(int error)
|
||||
|
@ -72,20 +74,23 @@ static const char *ErrorMsg(int error)
|
|||
{
|
||||
"No errors",
|
||||
"Can't open file",
|
||||
"Premature End of file",
|
||||
"Premature end of file",
|
||||
"Malformed file",
|
||||
};
|
||||
|
||||
if(error>2 || error<0) return "Unknown error";
|
||||
if(error>=E_LAST || error<0) return "Unknown error";
|
||||
else return stl_error_msg[error];
|
||||
};
|
||||
}
|
||||
|
||||
static bool LoadMask(const char * filename, int &mask)
|
||||
{
|
||||
bool magicMode;
|
||||
bool magicMode,colored;
|
||||
mask = Mask::IOM_VERTCOORD | Mask::IOM_FACEINDEX;
|
||||
if(IsSTLColored(filename,magicMode))
|
||||
mask |= Mask::IOM_FACECOLOR;
|
||||
return true;
|
||||
if(!IsSTLColored(filename, colored, magicMode))
|
||||
return false;
|
||||
|
||||
if(colored) mask |= Mask::IOM_FACECOLOR;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Try to guess if a stl has color
|
||||
|
@ -94,11 +99,19 @@ static bool LoadMask(const char * filename, int &mask)
|
|||
* - It has to be binary
|
||||
* - The per face attribute should be not zero
|
||||
*
|
||||
* return false in case of malformed files
|
||||
*/
|
||||
static bool IsSTLColored(const char * filename, bool &magicsMode)
|
||||
static bool IsSTLColored(const char * filename, bool &coloredFlag, bool &magicsMode)
|
||||
{
|
||||
if(IsSTLBinary(filename)==false)
|
||||
coloredFlag=false;
|
||||
magicsMode=false;
|
||||
bool binaryFlag;
|
||||
if(IsSTLBinary(filename,binaryFlag)==false)
|
||||
return false;
|
||||
|
||||
if(binaryFlag==false)
|
||||
return true;
|
||||
|
||||
FILE *fp = fopen(filename, "rb");
|
||||
char buf[STL_LABEL_SIZE+1];
|
||||
fread(buf,sizeof(char),STL_LABEL_SIZE,fp);
|
||||
|
@ -123,39 +136,54 @@ static bool IsSTLColored(const char * filename, bool &magicsMode)
|
|||
if(attr!=0)
|
||||
{
|
||||
if(Color4b::FromUnsignedR5G5B5(attr) != Color4b(Color4b::White))
|
||||
return true;
|
||||
coloredFlag=true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool IsSTLBinary(const char * filename)
|
||||
/* Try to guess if a stl is in binary format
|
||||
*
|
||||
* return false in case of malformed files
|
||||
*/
|
||||
static bool IsSTLBinary(const char * filename, bool &binaryFlag)
|
||||
{
|
||||
bool binary=false;
|
||||
binaryFlag=false;
|
||||
FILE *fp = fopen(filename, "r");
|
||||
/* Find size of file */
|
||||
fseek(fp, 0, SEEK_END);
|
||||
int file_size = ftell(fp);
|
||||
int facenum;
|
||||
long file_size = ftell(fp);
|
||||
unsigned int facenum;
|
||||
/* Check for binary or ASCII file */
|
||||
fseek(fp, STL_LABEL_SIZE, SEEK_SET);
|
||||
fread(&facenum, sizeof(int), 1, fp);
|
||||
fread(&facenum, sizeof(unsigned int), 1, fp);
|
||||
|
||||
int expected_file_size=STL_LABEL_SIZE + 4 + (sizeof(short)+sizeof(STLFacet) )*facenum ;
|
||||
if(file_size == expected_file_size) binary = true;
|
||||
unsigned char tmpbuf[128];
|
||||
fread(tmpbuf,sizeof(tmpbuf),1,fp);
|
||||
for(unsigned int i = 0; i < sizeof(tmpbuf); i++)
|
||||
if(file_size == expected_file_size)
|
||||
{
|
||||
binaryFlag = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
// second check, sometimes the size is a bit wrong,
|
||||
// lets'make a test to check that we find only ascii stuff before assuming it is ascii
|
||||
unsigned char tmpbuf[1000];
|
||||
int byte_to_read = std::min(int(sizeof(tmpbuf)), int(file_size - 80));
|
||||
fread(tmpbuf, byte_to_read,1,fp);
|
||||
fclose(fp);
|
||||
for(int i = 0; i < byte_to_read; i++)
|
||||
{
|
||||
if(tmpbuf[i] > 127)
|
||||
{
|
||||
binary=true;
|
||||
binaryFlag=true;
|
||||
if(abs(file_size-expected_file_size) > file_size/20 )
|
||||
return false; //
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Now we know if the stl file is ascii or binary.
|
||||
fclose(fp);
|
||||
return binary;
|
||||
return true;
|
||||
}
|
||||
|
||||
static int Open( OpenMeshType &m, const char * filename, int &loadMask, CallBackPos *cb=0)
|
||||
|
@ -165,8 +193,11 @@ static int Open( OpenMeshType &m, const char * filename, int &loadMask, CallBack
|
|||
return E_CANTOPEN;
|
||||
fclose(fp);
|
||||
loadMask |= Mask::IOM_VERTCOORD | Mask::IOM_FACEINDEX;
|
||||
bool binaryFlag;
|
||||
if(!IsSTLBinary(filename,binaryFlag))
|
||||
return E_MALFORMED;
|
||||
|
||||
if(IsSTLBinary(filename)) return OpenBinary(m,filename,loadMask,cb);
|
||||
if(binaryFlag) return OpenBinary(m,filename,loadMask,cb);
|
||||
else return OpenAscii(m,filename,cb);
|
||||
}
|
||||
|
||||
|
@ -179,8 +210,10 @@ static int OpenBinary( OpenMeshType &m, const char * filename, int &loadMask, Ca
|
|||
return E_CANTOPEN;
|
||||
}
|
||||
|
||||
bool magicsMode;
|
||||
if(!IsSTLColored(filename,magicsMode))
|
||||
bool magicsMode,coloredFlag;
|
||||
if(!IsSTLColored(filename,coloredFlag, magicsMode))
|
||||
return E_MALFORMED;
|
||||
if(!coloredFlag)
|
||||
loadMask = loadMask & (~Mask::IOM_FACECOLOR);
|
||||
|
||||
int facenum;
|
||||
|
|
|
@ -53,6 +53,8 @@ namespace tri {
|
|||
namespace io {
|
||||
|
||||
|
||||
|
||||
|
||||
/** Additional data needed or useful for parsing a ply mesh.
|
||||
This class can be passed to the ImporterPLY::Open() function for
|
||||
- retrieving additional per-vertex per-face data
|
||||
|
@ -64,13 +66,65 @@ class PlyInfo
|
|||
public:
|
||||
typedef ::vcg::ply::PropDescriptor PropDescriptor ;
|
||||
|
||||
void AddPerElemFloatAttribute(int elemType, const char *attrName, const char * propName=0)
|
||||
{
|
||||
static const char *elemStr[2]={"vertex","face"};
|
||||
static std::vector<PropDescriptor> *elemDescVec[2]={&(this->VertDescriptorVec), &(this->FaceDescriptorVec)};
|
||||
static std::vector<std::string > *elemNameVec[2]={&(this->VertAttrNameVec), &(this->FaceAttrNameVec)};
|
||||
|
||||
if(propName==0) propName=attrName;
|
||||
elemDescVec[elemType]->push_back(PropDescriptor());
|
||||
elemNameVec[elemType]->push_back(attrName);
|
||||
elemDescVec[elemType]->back().elemname=elemStr[elemType];
|
||||
elemDescVec[elemType]->back().propname=strdup(propName);
|
||||
elemDescVec[elemType]->back().stotype1 = vcg::ply::T_FLOAT;
|
||||
elemDescVec[elemType]->back().memtype1 = vcg::ply::T_FLOAT;
|
||||
}
|
||||
|
||||
void AddPerVertexFloatAttribute(const char *attrName, const char *propName=0) {
|
||||
AddPerElemFloatAttribute(0,attrName,propName);
|
||||
}
|
||||
void AddPerFaceFloatAttribute(const char *attrName, const char *propName=0) {
|
||||
AddPerElemFloatAttribute(1,attrName,propName);
|
||||
}
|
||||
|
||||
|
||||
/* Note that saving a per vertex point3 attribute is a mess.
|
||||
* Actually require to allocate 3 float attribute and save them. And they are never deallocated... */
|
||||
template<class MeshType>
|
||||
void AddPerVertexPoint3fAttribute(MeshType &m, const char *attrName, const char *propName="")
|
||||
{
|
||||
if(propName==0) propName=attrName;
|
||||
|
||||
const char *attrxyz[3] = {
|
||||
strdup((std::string(attrName)+std::string("_x")).c_str()),
|
||||
strdup((std::string(attrName)+std::string("_y")).c_str()),
|
||||
strdup((std::string(attrName)+std::string("_z")).c_str()),
|
||||
};
|
||||
typename MeshType::template PerVertexAttributeHandle <vcg::Point3f>
|
||||
ht = vcg::tri::Allocator<MeshType>:: template GetPerVertexAttribute <vcg::Point3f> (m,attrName);
|
||||
|
||||
typename MeshType::template PerVertexAttributeHandle <float> htt[3];
|
||||
|
||||
for(int i=0;i<3;++i)
|
||||
{
|
||||
htt[i] = vcg::tri::Allocator<MeshType>:: template GetPerVertexAttribute<float> (m,std::string(attrxyz[i]));
|
||||
// ForEachVertex (m, [&](typename MeshType::VertexType &v) {
|
||||
// htt[i][v] = ht[v][i];
|
||||
// });
|
||||
for(auto vi=m.vert.begin();vi!=m.vert.end();++vi)
|
||||
if(!vi->IsD())
|
||||
htt[i][vi] = ht[vi][i];
|
||||
AddPerVertexFloatAttribute(attrxyz[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PlyInfo()
|
||||
{
|
||||
status=0;
|
||||
mask=0;
|
||||
cb=0;
|
||||
vdn=fdn=0;
|
||||
VertexData=FaceData=0;
|
||||
}
|
||||
/// Store the error codes enconutered when parsing a ply
|
||||
int status;
|
||||
|
@ -81,15 +135,16 @@ public:
|
|||
// it returns the current position, and formats a string with a description of what th efunction is doing (loading vertexes, faces...)
|
||||
CallBackPos *cb;
|
||||
|
||||
/// the number of per-vertex descriptor (usually 0)
|
||||
int vdn;
|
||||
/// The additional vertex descriptor that a user can specify to load additional per-vertex non-standard data stored in a ply
|
||||
PropDescriptor *VertexData;
|
||||
/// the number of per-face descriptor (usually 0)
|
||||
int fdn;
|
||||
std::vector<PropDescriptor> VertDescriptorVec;
|
||||
/// AttributeName is an array, externally allocated, containing the names of the attributes to be saved (loaded).
|
||||
/// We assume that AttributeName[], if not empty, is exactly of the same size of VertexdData[]
|
||||
/// If AttributeName[i] is not empty we use it to retrieve/store the info instead of the offsetted space in the current vertex
|
||||
std::vector<std::string> VertAttrNameVec;
|
||||
|
||||
/// The additional vertex descriptor that a user can specify to load additional per-face non-standard data stored in a ply
|
||||
PropDescriptor *FaceData;
|
||||
std::vector<PropDescriptor> FaceDescriptorVec;
|
||||
std::vector<std::string> FaceAttrNameVec;
|
||||
|
||||
/// a string containing the current ply header. Useful for showing it to the user.
|
||||
std::string header;
|
||||
|
|
Loading…
Reference in New Issue