Updated to reflect the Normal() -> TriangleNormal() change
Updated to reflect the changes to the UpdateFlags (new function names ::VertexBorderFromFaceAdj ::VertexBorderFromFaceBorder)
This commit is contained in:
parent
4b0e72293f
commit
9d89004760
vcg/complex/algorithms
|
@ -255,10 +255,10 @@ class Clustering
|
||||||
else
|
else
|
||||||
Grid.siz = Point3i::Construct(Grid.dim / _cellsize);
|
Grid.siz = Point3i::Construct(Grid.dim / _cellsize);
|
||||||
|
|
||||||
// find voxel size
|
// find voxel size
|
||||||
Grid.voxel[0] = Grid.dim[0]/Grid.siz[0];
|
Grid.voxel[0] = Grid.dim[0]/Grid.siz[0];
|
||||||
Grid.voxel[1] = Grid.dim[1]/Grid.siz[1];
|
Grid.voxel[1] = Grid.dim[1]/Grid.siz[1];
|
||||||
Grid.voxel[2] = Grid.dim[2]/Grid.siz[2];
|
Grid.voxel[2] = Grid.dim[2]/Grid.siz[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicGrid<ScalarType> Grid;
|
BasicGrid<ScalarType> Grid;
|
||||||
|
@ -277,18 +277,18 @@ class Clustering
|
||||||
STDEXT::hash_map<HashedPoint3i,CellType> GridCell;
|
STDEXT::hash_map<HashedPoint3i,CellType> GridCell;
|
||||||
|
|
||||||
|
|
||||||
void AddPointSet(MeshType &m, bool UseOnlySelected=false)
|
void AddPointSet(MeshType &m, bool UseOnlySelected=false)
|
||||||
{
|
{
|
||||||
VertexIterator vi;
|
VertexIterator vi;
|
||||||
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
||||||
if(!(*vi).IsD())
|
if(!(*vi).IsD())
|
||||||
if(!UseOnlySelected || (*vi).IsS())
|
if(!UseOnlySelected || (*vi).IsS())
|
||||||
{
|
{
|
||||||
HashedPoint3i pi;
|
HashedPoint3i pi;
|
||||||
Grid.PToIP((*vi).cP(), pi );
|
Grid.PToIP((*vi).cP(), pi );
|
||||||
GridCell[pi].AddVertex(m,Grid,pi,*(vi));
|
GridCell[pi].AddVertex(m,Grid,pi,*(vi));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddMesh(MeshType &m)
|
void AddMesh(MeshType &m)
|
||||||
{
|
{
|
||||||
|
@ -377,7 +377,7 @@ class Clustering
|
||||||
// the best orientation according to the averaged normal
|
// the best orientation according to the averaged normal
|
||||||
if(!DuplicateFaceParam)
|
if(!DuplicateFaceParam)
|
||||||
{
|
{
|
||||||
CoordType N=vcg::Normal(m.face[i]);
|
CoordType N=TriangleNormal(m.face[i]);
|
||||||
int badOrient=0;
|
int badOrient=0;
|
||||||
if( N.dot((*ti).v[0]->N()) <0) ++badOrient;
|
if( N.dot((*ti).v[0]->N()) <0) ++badOrient;
|
||||||
if( N.dot((*ti).v[1]->N()) <0) ++badOrient;
|
if( N.dot((*ti).v[1]->N()) <0) ++badOrient;
|
||||||
|
|
|
@ -66,7 +66,7 @@ template <class MESH> class AdvancingFront {
|
||||||
|
|
||||||
|
|
||||||
UpdateFlags<MESH>::FaceBorderFromNone(mesh);
|
UpdateFlags<MESH>::FaceBorderFromNone(mesh);
|
||||||
UpdateFlags<MESH>::VertexBorderFromFace(mesh);
|
UpdateFlags<MESH>::VertexBorderFromFaceBorder(mesh);
|
||||||
|
|
||||||
nb.clear();
|
nb.clear();
|
||||||
nb.resize(mesh.vert.size(), 0);
|
nb.resize(mesh.vert.size(), 0);
|
||||||
|
@ -343,7 +343,7 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void AddFace(int v0, int v1, int v2) {
|
void AddFace(int v0, int v1, int v2) {
|
||||||
FaceIterator fi = vcg::tri::Allocator<MESH>::AddFace(mesh,v0,v1,v2);
|
FaceIterator fi = vcg::tri::Allocator<MESH>::AddFace(mesh,v0,v1,v2);
|
||||||
ComputeNormalizedNormal(*fi);
|
fi->N() = TriangleNormal(*fi).Normalize();
|
||||||
if(tri::HasVFAdjacency(mesh))
|
if(tri::HasVFAdjacency(mesh))
|
||||||
{
|
{
|
||||||
for(int j=0;j<3;++j)
|
for(int j=0;j<3;++j)
|
||||||
|
|
|
@ -376,7 +376,7 @@ void SphericalCap(MeshType &in, float angleRad, const int subdiv = 3 )
|
||||||
tri::Refine(in, MidPoint<MeshType>(&in));
|
tri::Refine(in, MidPoint<MeshType>(&in));
|
||||||
|
|
||||||
tri::UpdateFlags<MeshType>::FaceBorderFromFF(in);
|
tri::UpdateFlags<MeshType>::FaceBorderFromFF(in);
|
||||||
tri::UpdateFlags<MeshType>::VertexBorderFromFace(in);
|
tri::UpdateFlags<MeshType>::VertexBorderFromFaceBorder(in);
|
||||||
|
|
||||||
for(int i=0;i<in.vn;++i)
|
for(int i=0;i<in.vn;++i)
|
||||||
if(in.vert[i].IsB())
|
if(in.vert[i].IsB())
|
||||||
|
@ -1015,6 +1015,7 @@ void BuildPrismFaceShell(MeshType &mIn, MeshType &mOut, float height=0, float in
|
||||||
typedef typename MeshType::CoordType CoordType;
|
typedef typename MeshType::CoordType CoordType;
|
||||||
if(height==0) height = mIn.bbox.Diag()/100.0f;
|
if(height==0) height = mIn.bbox.Diag()/100.0f;
|
||||||
if(inset==0) inset = mIn.bbox.Diag()/200.0f;
|
if(inset==0) inset = mIn.bbox.Diag()/200.0f;
|
||||||
|
tri::UpdateTopology<MeshType>::FaceFace(mIn);
|
||||||
tri::UpdateFlags<MeshType>::FaceClearV(mIn);
|
tri::UpdateFlags<MeshType>::FaceClearV(mIn);
|
||||||
for(size_t i=0;i<mIn.face.size();++i) if(!mIn.face[i].IsV())
|
for(size_t i=0;i<mIn.face.size();++i) if(!mIn.face[i].IsV())
|
||||||
{
|
{
|
||||||
|
@ -1065,6 +1066,7 @@ void BuildPrismFaceShell(MeshType &mIn, MeshType &mOut, float height=0, float in
|
||||||
|
|
||||||
if(smoothFlag)
|
if(smoothFlag)
|
||||||
{
|
{
|
||||||
|
faceM.face.EnableFFAdjacency();
|
||||||
tri::UpdateTopology<MeshType>::FaceFace(faceM);
|
tri::UpdateTopology<MeshType>::FaceFace(faceM);
|
||||||
tri::UpdateFlags<MeshType>::FaceBorderFromFF(faceM);
|
tri::UpdateFlags<MeshType>::FaceBorderFromFF(faceM);
|
||||||
tri::Refine(faceM, MidPoint<MeshType>(&faceM),0,true);
|
tri::Refine(faceM, MidPoint<MeshType>(&faceM),0,true);
|
||||||
|
|
|
@ -94,7 +94,7 @@ public:
|
||||||
assert(e0.IsBorder());
|
assert(e0.IsBorder());
|
||||||
e1=e0;
|
e1=e0;
|
||||||
e1.NextB();
|
e1.NextB();
|
||||||
n=vcg::Normal<TrivialEar>(*this);
|
n=TriangleNormal<TrivialEar>(*this);
|
||||||
ComputeQuality();
|
ComputeQuality();
|
||||||
ComputeAngle();
|
ComputeAngle();
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,7 @@ public:
|
||||||
(*f).V(0) = e0.VFlip();
|
(*f).V(0) = e0.VFlip();
|
||||||
(*f).V(1) = e0.v;
|
(*f).V(1) = e0.v;
|
||||||
(*f).V(2) = e1.v;
|
(*f).V(2) = e1.v;
|
||||||
face::ComputeNormalizedNormal(*f);
|
f->N() = TriangleNormal(*f).Normalize();
|
||||||
|
|
||||||
face::FFAttachManifold(f,0,e0.f,e0.z);
|
face::FFAttachManifold(f,0,e0.f,e0.z);
|
||||||
face::FFAttachManifold(f,1,e1.f,e1.z);
|
face::FFAttachManifold(f,1,e1.f,e1.z);
|
||||||
|
@ -644,8 +644,8 @@ template<class EAR>
|
||||||
|
|
||||||
static float ComputeDihedralAngle(CoordType p1,CoordType p2,CoordType p3,CoordType p4)
|
static float ComputeDihedralAngle(CoordType p1,CoordType p2,CoordType p3,CoordType p4)
|
||||||
{
|
{
|
||||||
CoordType n1 = NormalizedNormal(p1,p3,p2);
|
CoordType n1 = Normal(p1,p3,p2);
|
||||||
CoordType n2 = NormalizedNormal(p1,p2,p4);
|
CoordType n2 = Normal(p1,p2,p4);
|
||||||
return math::ToDeg(AngleN(n1,n2));
|
return math::ToDeg(AngleN(n1,n2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
* \ *
|
* \ *
|
||||||
* All rights reserved. *
|
* All rights reserved. *
|
||||||
* *
|
* *
|
||||||
* This program is free software; you can redistribute it and/or modify *
|
* 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 *
|
* it under the terms of the GNU General Public License as published by *
|
||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
|
@ -89,40 +89,40 @@ namespace tri{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This class describe Quadric based collapse operation.
|
This class describe Quadric based collapse operation.
|
||||||
|
|
||||||
Requirements:
|
Requirements:
|
||||||
|
|
||||||
Vertex
|
Vertex
|
||||||
must have:
|
must have:
|
||||||
incremental mark
|
incremental mark
|
||||||
VF topology
|
VF topology
|
||||||
|
|
||||||
must have:
|
must have:
|
||||||
members
|
members
|
||||||
|
|
||||||
QuadricType Qd();
|
QuadricType Qd();
|
||||||
|
|
||||||
ScalarType W() const;
|
ScalarType W() const;
|
||||||
A per-vertex Weight that can be used in simplification
|
A per-vertex Weight that can be used in simplification
|
||||||
lower weight means that error is lowered,
|
lower weight means that error is lowered,
|
||||||
standard: return W==1.0
|
standard: return W==1.0
|
||||||
|
|
||||||
void Merge(MESH_TYPE::vertex_type const & v);
|
void Merge(MESH_TYPE::vertex_type const & v);
|
||||||
Merges the attributes of the current vertex with the ones of v
|
Merges the attributes of the current vertex with the ones of v
|
||||||
(e.g. its weight with the one of the given vertex, the color ect).
|
(e.g. its weight with the one of the given vertex, the color ect).
|
||||||
Standard: void function;
|
Standard: void function;
|
||||||
|
|
||||||
OtherWise the class should be templated with a static helper class that helps to retrieve these functions.
|
OtherWise the class should be templated with a static helper class that helps to retrieve these functions.
|
||||||
If the vertex class exposes these functions a default static helper class is provided.
|
If the vertex class exposes these functions a default static helper class is provided.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
//**Helper CLASSES**//
|
//**Helper CLASSES**//
|
||||||
template <class VERTEX_TYPE>
|
template <class VERTEX_TYPE>
|
||||||
class QInfoStandard
|
class QInfoStandard
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
QInfoStandard(){}
|
QInfoStandard(){}
|
||||||
static void Init(){}
|
static void Init(){}
|
||||||
static math::Quadric<double> &Qd(VERTEX_TYPE &v) {return v.Qd();}
|
static math::Quadric<double> &Qd(VERTEX_TYPE &v) {return v.Qd();}
|
||||||
|
@ -130,7 +130,7 @@ namespace tri{
|
||||||
static typename VERTEX_TYPE::ScalarType W(VERTEX_TYPE */*v*/) {return 1.0;}
|
static typename VERTEX_TYPE::ScalarType W(VERTEX_TYPE */*v*/) {return 1.0;}
|
||||||
static typename VERTEX_TYPE::ScalarType W(VERTEX_TYPE &/*v*/) {return 1.0;}
|
static typename VERTEX_TYPE::ScalarType W(VERTEX_TYPE &/*v*/) {return 1.0;}
|
||||||
static void Merge(VERTEX_TYPE & /*v_dest*/, VERTEX_TYPE const & /*v_del*/){}
|
static void Merge(VERTEX_TYPE & /*v_dest*/, VERTEX_TYPE const & /*v_del*/){}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class TriEdgeCollapseQuadricParameter : public BaseParameterClass
|
class TriEdgeCollapseQuadricParameter : public BaseParameterClass
|
||||||
|
@ -189,11 +189,11 @@ public:
|
||||||
// typedef typename TEC::EdgeType EdgeType;
|
// typedef typename TEC::EdgeType EdgeType;
|
||||||
typedef typename TriEdgeCollapse<TriMeshType, VertexPair, MYTYPE>::HeapType HeapType;
|
typedef typename TriEdgeCollapse<TriMeshType, VertexPair, MYTYPE>::HeapType HeapType;
|
||||||
typedef typename TriEdgeCollapse<TriMeshType, VertexPair, MYTYPE>::HeapElem HeapElem;
|
typedef typename TriEdgeCollapse<TriMeshType, VertexPair, MYTYPE>::HeapElem HeapElem;
|
||||||
typedef typename TriMeshType::CoordType CoordType;
|
typedef typename TriMeshType::CoordType CoordType;
|
||||||
typedef typename TriMeshType::ScalarType ScalarType;
|
typedef typename TriMeshType::ScalarType ScalarType;
|
||||||
typedef math::Quadric< double > QuadricType;
|
typedef math::Quadric< double > QuadricType;
|
||||||
typedef typename TriMeshType::FaceType FaceType;
|
typedef typename TriMeshType::FaceType FaceType;
|
||||||
typedef typename TriMeshType::VertexType VertexType;
|
typedef typename TriMeshType::VertexType VertexType;
|
||||||
typedef TriEdgeCollapseQuadricParameter QParameter;
|
typedef TriEdgeCollapseQuadricParameter QParameter;
|
||||||
typedef HelperType QH;
|
typedef HelperType QH;
|
||||||
|
|
||||||
|
@ -203,19 +203,19 @@ public:
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
// puntatori ai vertici che sono stati messi non-w per preservare il boundary
|
// puntatori ai vertici che sono stati messi non-w per preservare il boundary
|
||||||
static std::vector<typename TriMeshType::VertexPointer> & WV(){
|
static std::vector<typename TriMeshType::VertexPointer> & WV(){
|
||||||
static std::vector<typename TriMeshType::VertexPointer> _WV; return _WV;
|
static std::vector<typename TriMeshType::VertexPointer> _WV; return _WV;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline TriEdgeCollapseQuadric(){}
|
inline TriEdgeCollapseQuadric(){}
|
||||||
|
|
||||||
inline TriEdgeCollapseQuadric(const VertexPair &p, int i, BaseParameterClass *pp)
|
inline TriEdgeCollapseQuadric(const VertexPair &p, int i, BaseParameterClass *pp)
|
||||||
{
|
{
|
||||||
this->localMark = i;
|
this->localMark = i;
|
||||||
this->pos=p;
|
this->pos=p;
|
||||||
this->_priority = ComputePriority(pp);
|
this->_priority = ComputePriority(pp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline bool IsFeasible(BaseParameterClass *_pp){
|
inline bool IsFeasible(BaseParameterClass *_pp){
|
||||||
|
@ -238,8 +238,8 @@ public:
|
||||||
EdgeCollapser<TriMeshType,VertexPair>::Do(m, this->pos, newPos); // v0 is deleted and v1 take the new position
|
EdgeCollapser<TriMeshType,VertexPair>::Do(m, this->pos, newPos); // v0 is deleted and v1 take the new position
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Final Clean up after the end of the simplification process
|
// Final Clean up after the end of the simplification process
|
||||||
static void Finalize(TriMeshType &m, HeapType& /*h_ret*/, BaseParameterClass *_pp)
|
static void Finalize(TriMeshType &m, HeapType& /*h_ret*/, BaseParameterClass *_pp)
|
||||||
{
|
{
|
||||||
|
@ -249,7 +249,7 @@ public:
|
||||||
if(pp->FastPreserveBoundary)
|
if(pp->FastPreserveBoundary)
|
||||||
{
|
{
|
||||||
typename TriMeshType::VertexIterator vi;
|
typename TriMeshType::VertexIterator vi;
|
||||||
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
||||||
if(!(*vi).IsD()) (*vi).SetW();
|
if(!(*vi).IsD()) (*vi).SetW();
|
||||||
}
|
}
|
||||||
if(pp->PreserveBoundary)
|
if(pp->PreserveBoundary)
|
||||||
|
@ -324,31 +324,31 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // if the collapse is A-symmetric (e.g. u->v != v->u)
|
{ // if the collapse is A-symmetric (e.g. u->v != v->u)
|
||||||
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
for(vi=m.vert.begin();vi!=m.vert.end();++vi)
|
||||||
if(!(*vi).IsD() && (*vi).IsRW())
|
if(!(*vi).IsD() && (*vi).IsRW())
|
||||||
{
|
{
|
||||||
vcg::face::VFIterator<FaceType> x;
|
vcg::face::VFIterator<FaceType> x;
|
||||||
UnMarkAll(m);
|
UnMarkAll(m);
|
||||||
for( x.F() = (*vi).VFp(), x.I() = (*vi).VFi(); x.F()!=0; ++ x)
|
for( x.F() = (*vi).VFp(), x.I() = (*vi).VFi(); x.F()!=0; ++ x)
|
||||||
{
|
{
|
||||||
assert(x.F()->V(x.I())==&(*vi));
|
assert(x.F()->V(x.I())==&(*vi));
|
||||||
if(x.V()->IsRW() && x.V1()->IsRW() && !IsMarked(m,x.F()->V1(x.I()))){
|
if(x.V()->IsRW() && x.V1()->IsRW() && !IsMarked(m,x.F()->V1(x.I()))){
|
||||||
h_ret.push_back( HeapElem( new MYTYPE( VertexPair (x.V(),x.V1()),TriEdgeCollapse< TriMeshType,VertexPair,MYTYPE>::GlobalMark(),_pp)));
|
h_ret.push_back( HeapElem( new MYTYPE( VertexPair (x.V(),x.V1()),TriEdgeCollapse< TriMeshType,VertexPair,MYTYPE>::GlobalMark(),_pp)));
|
||||||
}
|
}
|
||||||
if(x.V()->IsRW() && x.V2()->IsRW() && !IsMarked(m,x.F()->V2(x.I()))){
|
if(x.V()->IsRW() && x.V2()->IsRW() && !IsMarked(m,x.F()->V2(x.I()))){
|
||||||
h_ret.push_back( HeapElem( new MYTYPE( VertexPair (x.V(),x.V2()),TriEdgeCollapse< TriMeshType,VertexPair,MYTYPE>::GlobalMark(),_pp)));
|
h_ret.push_back( HeapElem( new MYTYPE( VertexPair (x.V(),x.V2()),TriEdgeCollapse< TriMeshType,VertexPair,MYTYPE>::GlobalMark(),_pp)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static float HeapSimplexRatio(BaseParameterClass *_pp) {return IsSymmetric(_pp)?5.0f:9.0f;}
|
static float HeapSimplexRatio(BaseParameterClass *_pp) {return IsSymmetric(_pp)?5.0f:9.0f;}
|
||||||
static bool IsSymmetric(BaseParameterClass *_pp) {return ((QParameter *)_pp)->OptimalPlacement;}
|
static bool IsSymmetric(BaseParameterClass *_pp) {return ((QParameter *)_pp)->OptimalPlacement;}
|
||||||
static bool IsVertexStable(BaseParameterClass *_pp) {return !((QParameter *)_pp)->OptimalPlacement;}
|
static bool IsVertexStable(BaseParameterClass *_pp) {return !((QParameter *)_pp)->OptimalPlacement;}
|
||||||
|
|
||||||
|
|
||||||
///*
|
///*
|
||||||
// Funzione principale di valutazione dell'errore del collasso.
|
// Funzione principale di valutazione dell'errore del collasso.
|
||||||
// In pratica simula il collasso vero e proprio.
|
// In pratica simula il collasso vero e proprio.
|
||||||
|
@ -358,96 +358,96 @@ public:
|
||||||
ScalarType ComputePriority(BaseParameterClass *_pp)
|
ScalarType ComputePriority(BaseParameterClass *_pp)
|
||||||
{
|
{
|
||||||
QParameter *pp=(QParameter *)_pp;
|
QParameter *pp=(QParameter *)_pp;
|
||||||
ScalarType error;
|
ScalarType error;
|
||||||
typename vcg::face::VFIterator<FaceType> x;
|
typename vcg::face::VFIterator<FaceType> x;
|
||||||
std::vector<CoordType> on; // original normals
|
std::vector<CoordType> on; // original normals
|
||||||
typename TriMeshType::VertexType * v[2];
|
typename TriMeshType::VertexType * v[2];
|
||||||
v[0] = this->pos.V(0);
|
v[0] = this->pos.V(0);
|
||||||
v[1] = this->pos.V(1);
|
v[1] = this->pos.V(1);
|
||||||
|
|
||||||
if(pp->NormalCheck){ // Compute maximal normal variation
|
if(pp->NormalCheck){ // Compute maximal normal variation
|
||||||
// store the old normals for non-collapsed face in v0
|
// store the old normals for non-collapsed face in v0
|
||||||
for(x.F() = v[0]->VFp(), x.I() = v[0]->VFi(); x.F()!=0; ++x ) // for all faces in v0
|
for(x.F() = v[0]->VFp(), x.I() = v[0]->VFi(); x.F()!=0; ++x ) // for all faces in v0
|
||||||
if(x.F()->V(0)!=v[1] && x.F()->V(1)!=v[1] && x.F()->V(2)!=v[1] ) // skip faces with v1
|
if(x.F()->V(0)!=v[1] && x.F()->V(1)!=v[1] && x.F()->V(2)!=v[1] ) // skip faces with v1
|
||||||
on.push_back(NormalizedNormal(*x.F()));
|
on.push_back(TriangleNormal(*x.F()).Normalize());
|
||||||
// store the old normals for non-collapsed face in v1
|
// store the old normals for non-collapsed face in v1
|
||||||
for(x.F() = v[1]->VFp(), x.I() = v[1]->VFi(); x.F()!=0; ++x ) // for all faces in v1
|
for(x.F() = v[1]->VFp(), x.I() = v[1]->VFi(); x.F()!=0; ++x ) // for all faces in v1
|
||||||
if(x.F()->V(0)!=v[0] && x.F()->V(1)!=v[0] && x.F()->V(2)!=v[0] ) // skip faces with v0
|
if(x.F()->V(0)!=v[0] && x.F()->V(1)!=v[0] && x.F()->V(2)!=v[0] ) // skip faces with v0
|
||||||
on.push_back(NormalizedNormal(*x.F()));
|
on.push_back(TriangleNormal(*x.F()).Normalize());
|
||||||
}
|
}
|
||||||
|
|
||||||
//// Move the two vertexe into new position (storing the old ones)
|
//// Move the two vertexe into new position (storing the old ones)
|
||||||
CoordType OldPos0=v[0]->P();
|
CoordType OldPos0=v[0]->P();
|
||||||
CoordType OldPos1=v[1]->P();
|
CoordType OldPos1=v[1]->P();
|
||||||
if(pp->OptimalPlacement) { v[0]->P() = ComputeMinimal(); v[1]->P()=v[0]->P();}
|
if(pp->OptimalPlacement) { v[0]->P() = ComputeMinimal(); v[1]->P()=v[0]->P();}
|
||||||
else v[0]->P() = v[1]->P();
|
else v[0]->P() = v[1]->P();
|
||||||
|
|
||||||
//// Rescan faces and compute quality and difference between normals
|
//// Rescan faces and compute quality and difference between normals
|
||||||
int i;
|
int i;
|
||||||
double ndiff,MinCos = 1e100; // minimo coseno di variazione di una normale della faccia
|
double ndiff,MinCos = 1e100; // minimo coseno di variazione di una normale della faccia
|
||||||
// (e.g. max angle) Mincos varia da 1 (normali coincidenti) a
|
// (e.g. max angle) Mincos varia da 1 (normali coincidenti) a
|
||||||
// -1 (normali opposte);
|
// -1 (normali opposte);
|
||||||
double qt, MinQual = 1e100;
|
double qt, MinQual = 1e100;
|
||||||
CoordType nn;
|
CoordType nn;
|
||||||
for(x.F() = v[0]->VFp(), x.I() = v[0]->VFi(),i=0; x.F()!=0; ++x ) // for all faces in v0
|
for(x.F() = v[0]->VFp(), x.I() = v[0]->VFi(),i=0; x.F()!=0; ++x ) // for all faces in v0
|
||||||
if(x.F()->V(0)!=v[1] && x.F()->V(1)!=v[1] && x.F()->V(2)!=v[1] ) // skip faces with v1
|
if(x.F()->V(0)!=v[1] && x.F()->V(1)!=v[1] && x.F()->V(2)!=v[1] ) // skip faces with v1
|
||||||
{
|
{
|
||||||
if(pp->NormalCheck){
|
if(pp->NormalCheck){
|
||||||
nn=NormalizedNormal(*x.F());
|
nn=TriangleNormal(*x.F()).Normalize();
|
||||||
ndiff=nn.dot(on[i++]);
|
ndiff=nn.dot(on[i++]);
|
||||||
if(ndiff<MinCos) MinCos=ndiff;
|
if(ndiff<MinCos) MinCos=ndiff;
|
||||||
}
|
}
|
||||||
if(pp->QualityCheck){
|
if(pp->QualityCheck){
|
||||||
qt= QualityFace(*x.F());
|
qt= QualityFace(*x.F());
|
||||||
if(qt<MinQual) MinQual=qt;
|
if(qt<MinQual) MinQual=qt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(x.F() = v[1]->VFp(), x.I() = v[1]->VFi(),i=0; x.F()!=0; ++x ) // for all faces in v1
|
for(x.F() = v[1]->VFp(), x.I() = v[1]->VFi(),i=0; x.F()!=0; ++x ) // for all faces in v1
|
||||||
if(x.F()->V(0)!=v[0] && x.F()->V(1)!=v[0] && x.F()->V(2)!=v[0] ) // skip faces with v0
|
if(x.F()->V(0)!=v[0] && x.F()->V(1)!=v[0] && x.F()->V(2)!=v[0] ) // skip faces with v0
|
||||||
{
|
{
|
||||||
if(pp->NormalCheck){
|
if(pp->NormalCheck){
|
||||||
nn=NormalizedNormal(*x.F());
|
nn=TriangleNormal(*x.F()).Normalize();
|
||||||
ndiff=nn.dot(on[i++]);
|
ndiff=nn.dot(on[i++]);
|
||||||
if(ndiff<MinCos) MinCos=ndiff;
|
if(ndiff<MinCos) MinCos=ndiff;
|
||||||
}
|
}
|
||||||
if(pp->QualityCheck){
|
if(pp->QualityCheck){
|
||||||
qt= QualityFace(*x.F());
|
qt= QualityFace(*x.F());
|
||||||
if(qt<MinQual) MinQual=qt;
|
if(qt<MinQual) MinQual=qt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QuadricType qq=QH::Qd(v[0]);
|
QuadricType qq=QH::Qd(v[0]);
|
||||||
qq+=QH::Qd(v[1]);
|
qq+=QH::Qd(v[1]);
|
||||||
Point3d tpd=Point3d::Construct(v[1]->P());
|
Point3d tpd=Point3d::Construct(v[1]->P());
|
||||||
double QuadErr = pp->ScaleFactor*qq.Apply(tpd);
|
double QuadErr = pp->ScaleFactor*qq.Apply(tpd);
|
||||||
|
|
||||||
// All collapses involving triangles with quality larger than <QualityThr> has no penalty;
|
// All collapses involving triangles with quality larger than <QualityThr> has no penalty;
|
||||||
if(MinQual>pp->QualityThr) MinQual=pp->QualityThr;
|
if(MinQual>pp->QualityThr) MinQual=pp->QualityThr;
|
||||||
|
|
||||||
if(pp->NormalCheck){
|
if(pp->NormalCheck){
|
||||||
// All collapses where the normal vary less than <NormalThr> (e.g. more than CosineThr)
|
// All collapses where the normal vary less than <NormalThr> (e.g. more than CosineThr)
|
||||||
// have no penalty
|
// have no penalty
|
||||||
if(MinCos>pp->CosineThr) MinCos=pp->CosineThr;
|
if(MinCos>pp->CosineThr) MinCos=pp->CosineThr;
|
||||||
MinCos=(MinCos+1)/2.0; // Now it is in the range 0..1 with 0 very dangerous!
|
MinCos=(MinCos+1)/2.0; // Now it is in the range 0..1 with 0 very dangerous!
|
||||||
}
|
}
|
||||||
|
|
||||||
if(QuadErr<pp->QuadricEpsilon) QuadErr=pp->QuadricEpsilon;
|
if(QuadErr<pp->QuadricEpsilon) QuadErr=pp->QuadricEpsilon;
|
||||||
|
|
||||||
if( pp->UseVertexWeight ) QuadErr *= (QH::W(v[1])+QH::W(v[0]))/2;
|
if( pp->UseVertexWeight ) QuadErr *= (QH::W(v[1])+QH::W(v[0]))/2;
|
||||||
|
|
||||||
if(!pp->QualityCheck && !pp->NormalCheck) error = (ScalarType)(QuadErr);
|
if(!pp->QualityCheck && !pp->NormalCheck) error = (ScalarType)(QuadErr);
|
||||||
if( pp->QualityCheck && !pp->NormalCheck) error = (ScalarType)(QuadErr / MinQual);
|
if( pp->QualityCheck && !pp->NormalCheck) error = (ScalarType)(QuadErr / MinQual);
|
||||||
if(!pp->QualityCheck && pp->NormalCheck) error = (ScalarType)(QuadErr / MinCos);
|
if(!pp->QualityCheck && pp->NormalCheck) error = (ScalarType)(QuadErr / MinCos);
|
||||||
if( pp->QualityCheck && pp->NormalCheck) error = (ScalarType)(QuadErr / (MinQual*MinCos));
|
if( pp->QualityCheck && pp->NormalCheck) error = (ScalarType)(QuadErr / (MinQual*MinCos));
|
||||||
|
|
||||||
//Rrestore old position of v0 and v1
|
|
||||||
v[0]->P()=OldPos0;
|
|
||||||
v[1]->P()=OldPos1;
|
|
||||||
this->_priority = error;
|
|
||||||
return this->_priority;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//Rrestore old position of v0 and v1
|
||||||
|
v[0]->P()=OldPos0;
|
||||||
|
v[1]->P()=OldPos1;
|
||||||
|
this->_priority = error;
|
||||||
|
return this->_priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
//static double MaxError() {return 1e100;}
|
//static double MaxError() {return 1e100;}
|
||||||
//
|
//
|
||||||
inline void UpdateHeap(HeapType & h_ret,BaseParameterClass *_pp)
|
inline void UpdateHeap(HeapType & h_ret,BaseParameterClass *_pp)
|
||||||
|
@ -510,72 +510,72 @@ public:
|
||||||
static void InitQuadric(TriMeshType &m,BaseParameterClass *_pp)
|
static void InitQuadric(TriMeshType &m,BaseParameterClass *_pp)
|
||||||
{
|
{
|
||||||
QParameter *pp=(QParameter *)_pp;
|
QParameter *pp=(QParameter *)_pp;
|
||||||
typename TriMeshType::FaceIterator pf;
|
typename TriMeshType::FaceIterator pf;
|
||||||
typename TriMeshType::VertexIterator pv;
|
typename TriMeshType::VertexIterator pv;
|
||||||
int j;
|
int j;
|
||||||
QH::Init();
|
QH::Init();
|
||||||
// m.ClearFlags();
|
// m.ClearFlags();
|
||||||
for(pv=m.vert.begin();pv!=m.vert.end();++pv) // Azzero le quadriche
|
for(pv=m.vert.begin();pv!=m.vert.end();++pv) // Azzero le quadriche
|
||||||
if( ! (*pv).IsD() && (*pv).IsW())
|
if( ! (*pv).IsD() && (*pv).IsW())
|
||||||
QH::Qd(*pv).SetZero();
|
QH::Qd(*pv).SetZero();
|
||||||
|
|
||||||
|
|
||||||
for(pf=m.face.begin();pf!=m.face.end();++pf)
|
for(pf=m.face.begin();pf!=m.face.end();++pf)
|
||||||
if( !(*pf).IsD() && (*pf).IsR() )
|
if( !(*pf).IsD() && (*pf).IsR() )
|
||||||
if((*pf).V(0)->IsR() &&(*pf).V(1)->IsR() &&(*pf).V(2)->IsR())
|
if((*pf).V(0)->IsR() &&(*pf).V(1)->IsR() &&(*pf).V(2)->IsR())
|
||||||
{
|
{
|
||||||
QuadricType q;
|
QuadricType q;
|
||||||
Plane3<ScalarType,false> p;
|
Plane3<ScalarType,false> p;
|
||||||
// Calcolo piano
|
// Calcolo piano
|
||||||
p.SetDirection( ( (*pf).V(1)->cP() - (*pf).V(0)->cP() ) ^ ( (*pf).V(2)->cP() - (*pf).V(0)->cP() ));
|
p.SetDirection( ( (*pf).V(1)->cP() - (*pf).V(0)->cP() ) ^ ( (*pf).V(2)->cP() - (*pf).V(0)->cP() ));
|
||||||
// Se normalizzo non dipende dall'area
|
// Se normalizzo non dipende dall'area
|
||||||
|
|
||||||
if(!pp->UseArea)
|
if(!pp->UseArea)
|
||||||
p.Normalize();
|
p.Normalize();
|
||||||
|
|
||||||
p.SetOffset( p.Direction().dot((*pf).V(0)->cP()));
|
p.SetOffset( p.Direction().dot((*pf).V(0)->cP()));
|
||||||
|
|
||||||
// Calcolo quadrica delle facce
|
// Calcolo quadrica delle facce
|
||||||
q.ByPlane(p);
|
q.ByPlane(p);
|
||||||
|
|
||||||
for(j=0;j<3;++j)
|
for(j=0;j<3;++j)
|
||||||
if( (*pf).V(j)->IsW() )
|
if( (*pf).V(j)->IsW() )
|
||||||
{
|
{
|
||||||
if(pp->QualityWeight)
|
if(pp->QualityWeight)
|
||||||
q*=(*pf).V(j)->Q();
|
q*=(*pf).V(j)->Q();
|
||||||
QH::Qd((*pf).V(j)) += q; // Sommo la quadrica ai vertici
|
QH::Qd((*pf).V(j)) += q; // Sommo la quadrica ai vertici
|
||||||
}
|
}
|
||||||
|
|
||||||
for(j=0;j<3;++j)
|
|
||||||
if( (*pf).IsB(j) || pp->QualityQuadric ) // Bordo!
|
|
||||||
{
|
|
||||||
Plane3<ScalarType,false> pb; // Piano di bordo
|
|
||||||
|
|
||||||
// Calcolo la normale al piano di bordo e la sua distanza
|
for(j=0;j<3;++j)
|
||||||
// Nota che la lunghezza dell'edge DEVE essere Normalizzata
|
if( (*pf).IsB(j) || pp->QualityQuadric ) // Bordo!
|
||||||
// poiche' la pesatura in funzione dell'area e'gia fatta in p.Direction()
|
{
|
||||||
// Senza la normalize il bordo e' pesato in funzione della grandezza della mesh (mesh grandi non decimano sul bordo)
|
Plane3<ScalarType,false> pb; // Piano di bordo
|
||||||
pb.SetDirection(p.Direction() ^ ( (*pf).V1(j)->cP() - (*pf).V(j)->cP() ).normalized());
|
|
||||||
|
// Calcolo la normale al piano di bordo e la sua distanza
|
||||||
|
// Nota che la lunghezza dell'edge DEVE essere Normalizzata
|
||||||
|
// poiche' la pesatura in funzione dell'area e'gia fatta in p.Direction()
|
||||||
|
// Senza la normalize il bordo e' pesato in funzione della grandezza della mesh (mesh grandi non decimano sul bordo)
|
||||||
|
pb.SetDirection(p.Direction() ^ ( (*pf).V1(j)->cP() - (*pf).V(j)->cP() ).normalized());
|
||||||
if( (*pf).IsB(j) ) pb.SetDirection(pb.Direction()* (ScalarType)pp->BoundaryWeight); // amplify border planes
|
if( (*pf).IsB(j) ) pb.SetDirection(pb.Direction()* (ScalarType)pp->BoundaryWeight); // amplify border planes
|
||||||
else pb.SetDirection(pb.Direction()* (ScalarType)(pp->BoundaryWeight/100.0)); // and consider much less quadric for quality
|
else pb.SetDirection(pb.Direction()* (ScalarType)(pp->BoundaryWeight/100.0)); // and consider much less quadric for quality
|
||||||
pb.SetOffset(pb.Direction().dot((*pf).V(j)->cP()));
|
pb.SetOffset(pb.Direction().dot((*pf).V(j)->cP()));
|
||||||
q.ByPlane(pb);
|
q.ByPlane(pb);
|
||||||
|
|
||||||
|
if( (*pf).V (j)->IsW() ) QH::Qd((*pf).V (j)) += q; // Sommo le quadriche
|
||||||
|
if( (*pf).V1(j)->IsW() ) QH::Qd((*pf).V1(j)) += q;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( (*pf).V (j)->IsW() ) QH::Qd((*pf).V (j)) += q; // Sommo le quadriche
|
|
||||||
if( (*pf).V1(j)->IsW() ) QH::Qd((*pf).V1(j)) += q;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pp->ScaleIndependent)
|
if(pp->ScaleIndependent)
|
||||||
{
|
{
|
||||||
vcg::tri::UpdateBounding<TriMeshType>::Box(m);
|
vcg::tri::UpdateBounding<TriMeshType>::Box(m);
|
||||||
//Make all quadric independent from mesh size
|
//Make all quadric independent from mesh size
|
||||||
pp->ScaleFactor = 1e8*pow(1.0/m.bbox.Diag(),6); // scaling factor
|
pp->ScaleFactor = 1e8*pow(1.0/m.bbox.Diag(),6); // scaling factor
|
||||||
//pp->ScaleFactor *=pp->ScaleFactor ;
|
//pp->ScaleFactor *=pp->ScaleFactor ;
|
||||||
//pp->ScaleFactor *=pp->ScaleFactor ;
|
//pp->ScaleFactor *=pp->ScaleFactor ;
|
||||||
//printf("Scale factor =%f\n",pp->ScaleFactor );
|
//printf("Scale factor =%f\n",pp->ScaleFactor );
|
||||||
//printf("bb (%5.2f %5.2f %5.2f)-(%5.2f %5.2f %5.2f) Diag %f\n",m.bbox.min[0],m.bbox.min[1],m.bbox.min[2],m.bbox.max[0],m.bbox.max[1],m.bbox.max[2],m.bbox.Diag());
|
//printf("bb (%5.2f %5.2f %5.2f)-(%5.2f %5.2f %5.2f) Diag %f\n",m.bbox.min[0],m.bbox.min[1],m.bbox.min[2],m.bbox.max[0],m.bbox.max[1],m.bbox.max[2],m.bbox.Diag());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -594,33 +594,33 @@ public:
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
CoordType ComputeMinimal()
|
CoordType ComputeMinimal()
|
||||||
{
|
{
|
||||||
typename TriMeshType::VertexType * v[2];
|
typename TriMeshType::VertexType * v[2];
|
||||||
v[0] = this->pos.V(0);
|
v[0] = this->pos.V(0);
|
||||||
v[1] = this->pos.V(1);
|
v[1] = this->pos.V(1);
|
||||||
QuadricType q=QH::Qd(v[0]);
|
QuadricType q=QH::Qd(v[0]);
|
||||||
q+=QH::Qd(v[1]);
|
q+=QH::Qd(v[1]);
|
||||||
|
|
||||||
Point3<QuadricType::ScalarType> x;
|
Point3<QuadricType::ScalarType> x;
|
||||||
|
|
||||||
bool rt=q.Minimum(x);
|
bool rt=q.Minimum(x);
|
||||||
if(!rt) { // if the computation of the minimum fails we choose between the two edge points and the middle one.
|
if(!rt) { // if the computation of the minimum fails we choose between the two edge points and the middle one.
|
||||||
Point3<QuadricType::ScalarType> x0=Point3d::Construct(v[0]->P());
|
Point3<QuadricType::ScalarType> x0=Point3d::Construct(v[0]->P());
|
||||||
Point3<QuadricType::ScalarType> x1=Point3d::Construct(v[1]->P());
|
Point3<QuadricType::ScalarType> x1=Point3d::Construct(v[1]->P());
|
||||||
x.Import((v[0]->P()+v[1]->P())/2);
|
x.Import((v[0]->P()+v[1]->P())/2);
|
||||||
double qvx=q.Apply(x);
|
double qvx=q.Apply(x);
|
||||||
double qv0=q.Apply(x0);
|
double qv0=q.Apply(x0);
|
||||||
double qv1=q.Apply(x1);
|
double qv1=q.Apply(x1);
|
||||||
if(qv0<qvx) x=x0;
|
if(qv0<qvx) x=x0;
|
||||||
if(qv1<qvx && qv1<qv0) x=x1;
|
if(qv1<qvx && qv1<qv0) x=x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return CoordType::Construct(x);
|
return CoordType::Construct(x);
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
};
|
};
|
||||||
} // namespace tri
|
} // namespace tri
|
||||||
} // namespace vcg
|
} // namespace vcg
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -340,7 +340,7 @@ class TriEdgeCollapseQuadricTex: public vcg::tri::TriEdgeCollapse< TriMeshType,
|
||||||
qt= QualityFace(*x.F());
|
qt= QualityFace(*x.F());
|
||||||
if(qt<MinQual) MinQual=qt;
|
if(qt<MinQual) MinQual=qt;
|
||||||
if(pp->NormalCheck){
|
if(pp->NormalCheck){
|
||||||
CoordType nn=NormalizedNormal(*x.F());
|
CoordType nn=TriangleNormal(*x.F()).Normalize();
|
||||||
ndiff=nn.dot(x.F()->N()) / x.F()->N().Norm();
|
ndiff=nn.dot(x.F()->N()) / x.F()->N().Norm();
|
||||||
if(ndiff<MinCos) MinCos=ndiff;
|
if(ndiff<MinCos) MinCos=ndiff;
|
||||||
assert(!math::IsNAN(ndiff));
|
assert(!math::IsNAN(ndiff));
|
||||||
|
@ -352,7 +352,7 @@ class TriEdgeCollapseQuadricTex: public vcg::tri::TriEdgeCollapse< TriMeshType,
|
||||||
qt= QualityFace(*x.F());
|
qt= QualityFace(*x.F());
|
||||||
if(qt<MinQual) MinQual=qt;
|
if(qt<MinQual) MinQual=qt;
|
||||||
if(pp->NormalCheck){
|
if(pp->NormalCheck){
|
||||||
CoordType nn=NormalizedNormal(*x.F());
|
CoordType nn=TriangleNormal(*x.F()).Normalize();
|
||||||
ndiff=nn.dot(x.F()->N() / x.F()->N().Norm());
|
ndiff=nn.dot(x.F()->N() / x.F()->N().Norm());
|
||||||
if(ndiff<MinCos) MinCos=ndiff;
|
if(ndiff<MinCos) MinCos=ndiff;
|
||||||
assert(!math::IsNAN(ndiff));
|
assert(!math::IsNAN(ndiff));
|
||||||
|
|
|
@ -247,7 +247,7 @@ So it just require that you have correctly computed the flags; one way could be
|
||||||
\code
|
\code
|
||||||
vcg::tri::UpdateTopology<Mesh>::FaceFace(m.cm);
|
vcg::tri::UpdateTopology<Mesh>::FaceFace(m.cm);
|
||||||
vcg::tri::UpdateFlags<Mesh>::FaceBorderFromFF(m.cm);
|
vcg::tri::UpdateFlags<Mesh>::FaceBorderFromFF(m.cm);
|
||||||
vcg::tri::UpdateFlags<Mesh>::VertexBorderFromFace (m.cm);
|
vcg::tri::UpdateFlags<Mesh>::VertexBorderFromFaceBorder (m.cm);
|
||||||
vcg::tri::UpdateColor<Mesh>::PerVertexBorderFlag(m.cm);
|
vcg::tri::UpdateColor<Mesh>::PerVertexBorderFlag(m.cm);
|
||||||
\endcode
|
\endcode
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -503,7 +503,7 @@ static void ConvertVoronoiDiagramToMesh(MeshType &m,
|
||||||
if(vpp.triangulateRegion)
|
if(vpp.triangulateRegion)
|
||||||
{
|
{
|
||||||
tri::UpdateFlags<MeshType>::FaceBorderFromFF(outMesh);
|
tri::UpdateFlags<MeshType>::FaceBorderFromFF(outMesh);
|
||||||
tri::UpdateFlags<MeshType>::VertexBorderFromFace(outMesh);
|
tri::UpdateFlags<MeshType>::VertexBorderFromFaceBorder(outMesh);
|
||||||
for(FaceIterator fi=outMesh.face.begin();fi!=outMesh.face.end();++fi) if(!fi->IsD())
|
for(FaceIterator fi=outMesh.face.begin();fi!=outMesh.face.end();++fi) if(!fi->IsD())
|
||||||
{
|
{
|
||||||
for(int i=0;i<3;++i)
|
for(int i=0;i<3;++i)
|
||||||
|
@ -734,7 +734,7 @@ static void ConvertVoronoiDiagramToMeshOld(MeshType &m,
|
||||||
tri::Allocator<MeshType>::CompactEveryVector(outMesh);
|
tri::Allocator<MeshType>::CompactEveryVector(outMesh);
|
||||||
tri::UpdateTopology<MeshType>::FaceFace(outMesh);
|
tri::UpdateTopology<MeshType>::FaceFace(outMesh);
|
||||||
tri::UpdateFlags<MeshType>::FaceBorderFromFF(outMesh);
|
tri::UpdateFlags<MeshType>::FaceBorderFromFF(outMesh);
|
||||||
tri::UpdateFlags<MeshType>::VertexBorderFromFace(outMesh);
|
tri::UpdateFlags<MeshType>::VertexBorderFromFaceBorder(outMesh);
|
||||||
|
|
||||||
// 3) set up faux bits
|
// 3) set up faux bits
|
||||||
for(FaceIterator fi=outMesh.face.begin();fi!=outMesh.face.end();++fi)
|
for(FaceIterator fi=outMesh.face.begin();fi!=outMesh.face.end();++fi)
|
||||||
|
@ -1282,7 +1282,7 @@ static int VoronoiRelaxing(MeshType &m, std::vector<VertexType *> &seedVec,
|
||||||
}
|
}
|
||||||
|
|
||||||
tri::UpdateFlags<MeshType>::FaceBorderFromVF(m);
|
tri::UpdateFlags<MeshType>::FaceBorderFromVF(m);
|
||||||
tri::UpdateFlags<MeshType>::VertexBorderFromFace(m);
|
tri::UpdateFlags<MeshType>::VertexBorderFromFaceBorder(m);
|
||||||
PerVertexPointerHandle sources = tri::Allocator<MeshType>:: template GetPerVertexAttribute<VertexPointer> (m,"sources");
|
PerVertexPointerHandle sources = tri::Allocator<MeshType>:: template GetPerVertexAttribute<VertexPointer> (m,"sources");
|
||||||
PerVertexBoolHandle fixed = tri::Allocator<MeshType>:: template GetPerVertexAttribute<bool> (m,"fixed");
|
PerVertexBoolHandle fixed = tri::Allocator<MeshType>:: template GetPerVertexAttribute<bool> (m,"fixed");
|
||||||
int iter;
|
int iter;
|
||||||
|
|
Loading…
Reference in New Issue