Strongly refactored in order to guarantee better independence between the resampled mesh an the original one
This commit is contained in:
parent
3784295ac6
commit
03c2648af1
|
|
@ -40,37 +40,40 @@ namespace tri {
|
||||||
/*@{*/
|
/*@{*/
|
||||||
/*@{*/
|
/*@{*/
|
||||||
/** Class Resampler.
|
/** Class Resampler.
|
||||||
This is class reasmpling a mesh using marching cubes methods
|
This is class resampling a mesh using marching cubes methods
|
||||||
@param OLD_MESH_TYPE (Template Parameter) Specifies the type of mesh to be resampled
|
@param OldMeshType (Template Parameter) Specifies the type of mesh to be resampled
|
||||||
@param NEW_MESH_TYPE (Template Parameter) Specifies the type of output mesh.
|
@param NewMeshType (Template Parameter) Specifies the type of output mesh.
|
||||||
|
All the computations are done in the output mesh scalar type. (e.g. if you have a double mesh and you want to resample int to a float mesh the volume is kept in float)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR = vcg::face::PointDistanceBaseFunctor<typename OLD_MESH_TYPE::ScalarType > >
|
template <class OldMeshType,
|
||||||
class Resampler : public BasicGrid<FLT>
|
class NewMeshType,
|
||||||
|
class DISTFUNCTOR = vcg::face::PointDistanceBaseFunctor<typename OldMeshType::ScalarType > >
|
||||||
|
class Resampler : public BasicGrid<typename NewMeshType::ScalarType>
|
||||||
{
|
{
|
||||||
typedef OLD_MESH_TYPE Old_Mesh;
|
typedef typename NewMeshType::ScalarType NewScalarType;
|
||||||
typedef NEW_MESH_TYPE New_Mesh;
|
typedef typename NewMeshType::BoxType NewBoxType;
|
||||||
|
typedef typename NewMeshType::CoordType NewCoordType;
|
||||||
|
typedef typename NewMeshType::VertexType* NewVertexPointer;
|
||||||
|
typedef typename NewMeshType::VertexIterator NewVertexIterator;
|
||||||
|
typedef typename OldMeshType::CoordType OldCoordType;
|
||||||
|
typedef typename OldMeshType::FaceContainer OldFaceCont;
|
||||||
|
typedef typename OldMeshType::FaceType OldFaceType;
|
||||||
|
typedef typename OldMeshType::ScalarType OldScalarType;
|
||||||
|
|
||||||
//template <class OLD_MESH_TYPE,class NEW_MESH_TYPE>
|
class Walker : BasicGrid<typename NewMeshType::ScalarType>
|
||||||
class Walker : BasicGrid<float>
|
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
typedef int VertexIndex;
|
typedef int VertexIndex;
|
||||||
typedef OLD_MESH_TYPE Old_Mesh;
|
typedef typename vcg::GridStaticPtr<OldFaceType, OldScalarType> GridType;
|
||||||
typedef NEW_MESH_TYPE New_Mesh;
|
|
||||||
typedef typename New_Mesh::CoordType NewCoordType;
|
|
||||||
typedef typename New_Mesh::VertexType* VertexPointer;
|
|
||||||
typedef typename Old_Mesh::FaceContainer FaceCont;
|
|
||||||
typedef typename vcg::GridStaticPtr<typename Old_Mesh::FaceType> GridType;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
int SliceSize;
|
int SliceSize;
|
||||||
int CurrentSlice;
|
int CurrentSlice;
|
||||||
typedef tri::FaceTmark<Old_Mesh> MarkerFace;
|
typedef tri::FaceTmark<OldMeshType> MarkerFace;
|
||||||
MarkerFace markerFunctor;
|
MarkerFace markerFunctor;
|
||||||
|
|
||||||
|
|
||||||
VertexIndex *_x_cs; // indici dell'intersezioni della superficie lungo gli Xedge della fetta corrente
|
VertexIndex *_x_cs; // indici dell'intersezioni della superficie lungo gli Xedge della fetta corrente
|
||||||
VertexIndex *_y_cs; // indici dell'intersezioni della superficie lungo gli Yedge della fetta corrente
|
VertexIndex *_y_cs; // indici dell'intersezioni della superficie lungo gli Yedge della fetta corrente
|
||||||
VertexIndex *_z_cs; // indici dell'intersezioni della superficie lungo gli Zedge della fetta corrente
|
VertexIndex *_z_cs; // indici dell'intersezioni della superficie lungo gli Zedge della fetta corrente
|
||||||
|
|
@ -84,21 +87,21 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
field_value* _v_cs;
|
field_value* _v_cs;
|
||||||
field_value* _v_ns;
|
field_value* _v_ns;
|
||||||
|
|
||||||
New_Mesh *_newM;
|
NewMeshType *_newM;
|
||||||
Old_Mesh *_oldM;
|
OldMeshType *_oldM;
|
||||||
GridType _g;
|
GridType _g;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
float max_dim; // the limit value of the search (that takes into account of the offset)
|
NewScalarType max_dim; // the limit value of the search (that takes into account of the offset)
|
||||||
float offset; // an offset value that is always added to the returned value. Useful for extrarting isosurface at a different threshold
|
NewScalarType offset; // an offset value that is always added to the returned value. Useful for extrarting isosurface at a different threshold
|
||||||
bool DiscretizeFlag; // if the extracted surface should be discretized or not.
|
bool DiscretizeFlag; // if the extracted surface should be discretized or not.
|
||||||
bool MultiSampleFlag;
|
bool MultiSampleFlag;
|
||||||
bool AbsDistFlag; // if true the Distance Field computed is no more a signed one.
|
bool AbsDistFlag; // if true the Distance Field computed is no more a signed one.
|
||||||
Walker(const Box3f &_bbox, Point3i _siz )
|
Walker(const Box3<NewScalarType> &_bbox, Point3i _siz )
|
||||||
{
|
{
|
||||||
this->bbox= _bbox;
|
this->bbox= _bbox;
|
||||||
this->siz=_siz;
|
this->siz=_siz;
|
||||||
ComputeDimAndVoxel();
|
this->ComputeDimAndVoxel();
|
||||||
|
|
||||||
SliceSize = (this->siz.X()+1)*(this->siz.Z()+1);
|
SliceSize = (this->siz.X()+1)*(this->siz.Z()+1);
|
||||||
CurrentSlice = 0;
|
CurrentSlice = 0;
|
||||||
|
|
@ -122,13 +125,13 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
float V(const Point3i &p)
|
NewScalarType V(const Point3i &p)
|
||||||
{
|
{
|
||||||
return V(p.V(0),p.V(1),p.V(2));
|
return V(p.V(0),p.V(1),p.V(2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::pair<bool,float> VV(int x,int y,int z)
|
std::pair<bool,NewScalarType> VV(int x,int y,int z)
|
||||||
{
|
{
|
||||||
assert ((y==CurrentSlice)||(y==(CurrentSlice+1)));
|
assert ((y==CurrentSlice)||(y==(CurrentSlice+1)));
|
||||||
|
|
||||||
|
|
@ -142,53 +145,48 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
else return _v_ns[index];
|
else return _v_ns[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
float V(int x,int y,int z)
|
NewScalarType V(int x,int y,int z)
|
||||||
{
|
{
|
||||||
if(DiscretizeFlag) return VV(x,y,z).second+offset<0?-1:1;
|
if(DiscretizeFlag) return VV(x,y,z).second+offset<0?-1:1;
|
||||||
return VV(x,y,z).second+offset;
|
return VV(x,y,z).second+offset;
|
||||||
}
|
}
|
||||||
///return true if the distance form the mesh is less than maxdim and return distance
|
///return true if the distance form the mesh is less than maxdim and return distance
|
||||||
field_value DistanceFromMesh(Point3f &pp,Old_Mesh */*mesh*/)
|
field_value DistanceFromMesh(OldCoordType &pp)
|
||||||
{
|
{
|
||||||
float dist;
|
OldScalarType dist;
|
||||||
typename Old_Mesh::FaceType *f=NULL;
|
const NewScalarType max_dist = max_dim;
|
||||||
const float max_dist = max_dim;
|
OldCoordType testPt;
|
||||||
vcg::Point3f testPt;
|
|
||||||
this->IPfToPf(pp,testPt);
|
this->IPfToPf(pp,testPt);
|
||||||
|
|
||||||
vcg::Point3f closestNormV,closestNormF;
|
OldCoordType closestPt;
|
||||||
vcg::Point3f closestPt;
|
|
||||||
vcg::Point3f pip(-1,-1,-1);
|
|
||||||
|
|
||||||
// Note that PointDistanceBaseFunctor does not require the edge and plane precomptued.
|
|
||||||
// while the PointDistanceFunctor requires them.
|
|
||||||
|
|
||||||
DISTFUNCTOR PDistFunct;
|
DISTFUNCTOR PDistFunct;
|
||||||
f = _g.GetClosest(PDistFunct,markerFunctor,testPt,max_dist,dist,closestPt);
|
OldFaceType *f = _g.GetClosest(PDistFunct,markerFunctor,testPt,max_dist,dist,closestPt);
|
||||||
if (f==NULL) return field_value(false,0);
|
if (f==NULL) return field_value(false,0);
|
||||||
if(AbsDistFlag) return field_value(true,dist);
|
if(AbsDistFlag) return field_value(true,dist);
|
||||||
assert(!f->IsD());
|
assert(!f->IsD());
|
||||||
bool retIP;
|
bool retIP;
|
||||||
|
|
||||||
// To compute the interpolated normal we use the more robust function that require to know what is the most orhogonal direction of the face.
|
// To compute the interpolated normal we use the more robust function that require to know what is the most orhogonal direction of the face.
|
||||||
|
OldCoordType pip(-1,-1,-1);
|
||||||
retIP=InterpolationParameters(*f,(*f).cN(),closestPt, pip);
|
retIP=InterpolationParameters(*f,(*f).cN(),closestPt, pip);
|
||||||
assert(retIP); // this should happen only if the starting mesh has degenerate faces.
|
assert(retIP); // this should happen only if the starting mesh has degenerate faces.
|
||||||
|
|
||||||
const float InterpolationEpsilon = 0.00001f;
|
const NewScalarType InterpolationEpsilon = 0.00001f;
|
||||||
int zeroCnt=0;
|
int zeroCnt=0;
|
||||||
if(pip[0]<InterpolationEpsilon) ++zeroCnt;
|
if(pip[0]<InterpolationEpsilon) ++zeroCnt;
|
||||||
if(pip[1]<InterpolationEpsilon) ++zeroCnt;
|
if(pip[1]<InterpolationEpsilon) ++zeroCnt;
|
||||||
if(pip[2]<InterpolationEpsilon) ++zeroCnt;
|
if(pip[2]<InterpolationEpsilon) ++zeroCnt;
|
||||||
assert(zeroCnt<3);
|
assert(zeroCnt<3);
|
||||||
|
|
||||||
Point3f dir=(testPt-closestPt).Normalize();
|
OldCoordType dir=(testPt-closestPt).Normalize();
|
||||||
|
|
||||||
// Note that the two signs could be discordant.
|
// Note that the two signs could be discordant.
|
||||||
// Always choose the best one according to where the nearest point falls.
|
// Always choose the best one according to where the nearest point falls.
|
||||||
float signBest;
|
NewScalarType signBest;
|
||||||
|
|
||||||
// Compute test if the point see the surface normal from inside or outside
|
// Compute test if the point see the surface normal from inside or outside
|
||||||
// Surface normal for improved robustness is computed both by face and interpolated from vertices.
|
// Surface normal for improved robustness is computed both by face and interpolated from vertices.
|
||||||
|
OldCoordType closestNormV, closestNormF;
|
||||||
if(zeroCnt>0) // we Not are in the middle of the face so the face normal is NOT reliable.
|
if(zeroCnt>0) // we Not are in the middle of the face so the face normal is NOT reliable.
|
||||||
{
|
{
|
||||||
closestNormV = (f->V(0)->cN())*pip[0] + (f->V(1)->cN())*pip[1] + (f->V(2)->cN())*pip[2] ;
|
closestNormV = (f->V(0)->cN())*pip[0] + (f->V(1)->cN())*pip[1] + (f->V(2)->cN())*pip[2] ;
|
||||||
|
|
@ -205,23 +203,23 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
return field_value(true,dist);
|
return field_value(true,dist);
|
||||||
}
|
}
|
||||||
|
|
||||||
field_value MultiDistanceFromMesh(Point3f &pp, Old_Mesh */*mesh*/)
|
field_value MultiDistanceFromMesh(OldCoordType &pp)
|
||||||
{
|
{
|
||||||
float distSum=0;
|
float distSum=0;
|
||||||
int positiveCnt=0; // positive results counter
|
int positiveCnt=0; // positive results counter
|
||||||
const int MultiSample=7;
|
const int MultiSample=7;
|
||||||
const Point3f delta[7]={Point3f(0,0,0),
|
const OldCoordType delta[7]={OldCoordType(0,0,0),
|
||||||
Point3f( 0.2, -0.01, -0.02),
|
OldCoordType( 0.2, -0.01, -0.02),
|
||||||
Point3f(-0.2, 0.01, 0.02),
|
OldCoordType(-0.2, 0.01, 0.02),
|
||||||
Point3f( 0.01, 0.2, 0.01),
|
OldCoordType( 0.01, 0.2, 0.01),
|
||||||
Point3f( 0.03, -0.2, -0.03),
|
OldCoordType( 0.03, -0.2, -0.03),
|
||||||
Point3f(-0.02, -0.03, 0.2 ),
|
OldCoordType(-0.02, -0.03, 0.2 ),
|
||||||
Point3f(-0.01, 0.01, -0.2 )};
|
OldCoordType(-0.01, 0.01, -0.2 )};
|
||||||
|
|
||||||
for(int qq=0;qq<MultiSample;++qq)
|
for(int qq=0;qq<MultiSample;++qq)
|
||||||
{
|
{
|
||||||
Point3f pp2=pp+delta[qq];
|
OldCoordType pp2=pp+delta[qq];
|
||||||
field_value ff= DistanceFromMesh(pp2,_oldM);
|
field_value ff= DistanceFromMesh(pp2);
|
||||||
if(ff.first==false) return field_value(false,0);
|
if(ff.first==false) return field_value(false,0);
|
||||||
distSum += fabs(ff.second);
|
distSum += fabs(ff.second);
|
||||||
if(ff.second>0) positiveCnt ++;
|
if(ff.second>0) positiveCnt ++;
|
||||||
|
|
@ -239,9 +237,9 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
for (int k=0; k<=this->siz.Z(); k++)
|
for (int k=0; k<=this->siz.Z(); k++)
|
||||||
{
|
{
|
||||||
int index=GetSliceIndex(i,k);
|
int index=GetSliceIndex(i,k);
|
||||||
Point3f pp(i,slice,k);
|
OldCoordType pp(i,slice,k);
|
||||||
if(this->MultiSampleFlag) slice_values[index] = MultiDistanceFromMesh(pp,_oldM);
|
if(this->MultiSampleFlag) slice_values[index] = MultiDistanceFromMesh(pp);
|
||||||
else slice_values[index] = DistanceFromMesh(pp,_oldM);
|
else slice_values[index] = DistanceFromMesh(pp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//ComputeConsensus(slice,slice_values);
|
//ComputeConsensus(slice,slice_values);
|
||||||
|
|
@ -251,7 +249,7 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
For some reasons it can happens that the sign of the computed distance could not correct.
|
For some reasons it can happens that the sign of the computed distance could not correct.
|
||||||
this function tries to correct these issues by flipping the isolated voxels with discordant sign
|
this function tries to correct these issues by flipping the isolated voxels with discordant sign
|
||||||
*/
|
*/
|
||||||
void ComputeConsensus(int slice, field_value *slice_values)
|
void ComputeConsensus(int /*slice*/, field_value *slice_values)
|
||||||
{
|
{
|
||||||
float max_dist = min(min(this->voxel[0],this->voxel[1]),this->voxel[2]);
|
float max_dist = min(min(this->voxel[0],this->voxel[1]),this->voxel[2]);
|
||||||
int flippedCnt=0;
|
int flippedCnt=0;
|
||||||
|
|
@ -321,14 +319,14 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
|
|
||||||
|
|
||||||
template<class EXTRACTOR_TYPE>
|
template<class EXTRACTOR_TYPE>
|
||||||
void BuildMesh(Old_Mesh &old_mesh,New_Mesh &new_mesh,EXTRACTOR_TYPE &extractor,vcg::CallBackPos *cb)
|
void BuildMesh(OldMeshType &old_mesh,NewMeshType &new_mesh,EXTRACTOR_TYPE &extractor,vcg::CallBackPos *cb)
|
||||||
{
|
{
|
||||||
_newM=&new_mesh;
|
_newM=&new_mesh;
|
||||||
_oldM=&old_mesh;
|
_oldM=&old_mesh;
|
||||||
|
|
||||||
// the following two steps are required to be sure that the point-face distance without precomputed data works well.
|
// the following two steps are required to be sure that the point-face distance without precomputed data works well.
|
||||||
tri::UpdateNormal<Old_Mesh>::PerFaceNormalized(old_mesh);
|
tri::UpdateNormal<OldMeshType>::PerFaceNormalized(old_mesh);
|
||||||
tri::UpdateNormal<Old_Mesh>::PerVertexAngleWeighted(old_mesh);
|
tri::UpdateNormal<OldMeshType>::PerVertexAngleWeighted(old_mesh);
|
||||||
int _size=(int)old_mesh.fn*100;
|
int _size=(int)old_mesh.fn*100;
|
||||||
|
|
||||||
_g.Set(_oldM->face.begin(),_oldM->face.end(),_size);
|
_g.Set(_oldM->face.begin(),_oldM->face.end(),_size);
|
||||||
|
|
@ -345,11 +343,10 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
NextSlice();
|
NextSlice();
|
||||||
}
|
}
|
||||||
extractor.Finalize();
|
extractor.Finalize();
|
||||||
typename New_Mesh::VertexIterator vi;
|
for(NewVertexIterator vi=new_mesh.vert.begin();vi!=new_mesh.vert.end();++vi)
|
||||||
for(vi=new_mesh.vert.begin();vi!=new_mesh.vert.end();++vi)
|
|
||||||
if(!(*vi).IsD())
|
if(!(*vi).IsD())
|
||||||
{
|
{
|
||||||
IPfToPf((*vi).cP(),(*vi).P());
|
this->IPfToPf((*vi).cP(),(*vi).P());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -398,7 +395,7 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Exist(const vcg::Point3i &p1, const vcg::Point3i &p2, VertexPointer &v)
|
bool Exist(const vcg::Point3i &p1, const vcg::Point3i &p2, NewVertexPointer &v)
|
||||||
{
|
{
|
||||||
int i = p1.X();// - _bbox.min.X())/_cell_size.X();
|
int i = p1.X();// - _bbox.min.X())/_cell_size.X();
|
||||||
int z = p1.Z();// - _bbox.min.Z())/_cell_size.Z();
|
int z = p1.Z();// - _bbox.min.Z())/_cell_size.Z();
|
||||||
|
|
@ -482,16 +479,16 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
///interpolate
|
///interpolate
|
||||||
NewCoordType Interpolate(const vcg::Point3i &p1, const vcg::Point3i &p2,int dir)
|
NewCoordType Interpolate(const vcg::Point3i &p1, const vcg::Point3i &p2,int dir)
|
||||||
{
|
{
|
||||||
float f1 = (float)V(p1);
|
NewScalarType f1 = V(p1);
|
||||||
float f2 = (float)V(p2);
|
NewScalarType f2 = V(p2);
|
||||||
float u = (float) f1/(f1-f2);
|
NewScalarType u = f1/(f1-f2);
|
||||||
NewCoordType ret=vcg::Point3f((float)p1.V(0),(float)p1.V(1),(float)p1.V(2));
|
NewCoordType ret(p1.V(0),p1.V(1),p1.V(2));
|
||||||
ret.V(dir) = (float) p1.V(dir)*(1.f-u) + u*(float)p2.V(dir);
|
ret.V(dir) = p1.V(dir)*(1.f-u) + u*p2.V(dir);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
///if there is a vertex in z axis of a cell return the vertex or create it
|
///if there is a vertex in z axis of a cell return the vertex or create it
|
||||||
void GetXIntercept(const vcg::Point3i &p1, const vcg::Point3i &p2, VertexPointer &v)
|
void GetXIntercept(const vcg::Point3i &p1, const vcg::Point3i &p2, NewVertexPointer &v)
|
||||||
{
|
{
|
||||||
assert(p1.X()+1 == p2.X());
|
assert(p1.X()+1 == p2.X());
|
||||||
assert(p1.Y() == p2.Y());
|
assert(p1.Y() == p2.Y());
|
||||||
|
|
@ -507,7 +504,7 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
{
|
{
|
||||||
_x_cs[index] = (VertexIndex) _newM->vert.size();
|
_x_cs[index] = (VertexIndex) _newM->vert.size();
|
||||||
pos = _x_cs[index];
|
pos = _x_cs[index];
|
||||||
Allocator<New_Mesh>::AddVertices( *_newM, 1 );
|
Allocator<NewMeshType>::AddVertices( *_newM, 1 );
|
||||||
v = &_newM->vert[pos];
|
v = &_newM->vert[pos];
|
||||||
v->P()=Interpolate(p1,p2,0);
|
v->P()=Interpolate(p1,p2,0);
|
||||||
return;
|
return;
|
||||||
|
|
@ -519,7 +516,7 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
{
|
{
|
||||||
_x_ns[index] = (VertexIndex) _newM->vert.size();
|
_x_ns[index] = (VertexIndex) _newM->vert.size();
|
||||||
pos = _x_ns[index];
|
pos = _x_ns[index];
|
||||||
Allocator<New_Mesh>::AddVertices( *_newM, 1 );
|
Allocator<NewMeshType>::AddVertices( *_newM, 1 );
|
||||||
v = &_newM->vert[pos];
|
v = &_newM->vert[pos];
|
||||||
v->P()=Interpolate(p1,p2,0);
|
v->P()=Interpolate(p1,p2,0);
|
||||||
return;
|
return;
|
||||||
|
|
@ -530,7 +527,7 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
}
|
}
|
||||||
|
|
||||||
///if there is a vertex in y axis of a cell return the vertex or create it
|
///if there is a vertex in y axis of a cell return the vertex or create it
|
||||||
void GetYIntercept(const vcg::Point3i &p1, const vcg::Point3i &p2, VertexPointer &v)
|
void GetYIntercept(const vcg::Point3i &p1, const vcg::Point3i &p2, NewVertexPointer &v)
|
||||||
{
|
{
|
||||||
assert(p1.X() == p2.X());
|
assert(p1.X() == p2.X());
|
||||||
assert(p1.Y()+1 == p2.Y());
|
assert(p1.Y()+1 == p2.Y());
|
||||||
|
|
@ -544,7 +541,7 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
{
|
{
|
||||||
_y_cs[index] = (VertexIndex) _newM->vert.size();
|
_y_cs[index] = (VertexIndex) _newM->vert.size();
|
||||||
pos = _y_cs[index];
|
pos = _y_cs[index];
|
||||||
Allocator<New_Mesh>::AddVertices( *_newM, 1);
|
Allocator<NewMeshType>::AddVertices( *_newM, 1);
|
||||||
v = &_newM->vert[ pos ];
|
v = &_newM->vert[ pos ];
|
||||||
v->P()=Interpolate(p1,p2,1);
|
v->P()=Interpolate(p1,p2,1);
|
||||||
}
|
}
|
||||||
|
|
@ -553,7 +550,7 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
}
|
}
|
||||||
|
|
||||||
///if there is a vertex in z axis of a cell return the vertex or create it
|
///if there is a vertex in z axis of a cell return the vertex or create it
|
||||||
void GetZIntercept(const vcg::Point3i &p1, const vcg::Point3i &p2, VertexPointer &v)
|
void GetZIntercept(const vcg::Point3i &p1, const vcg::Point3i &p2, NewVertexPointer &v)
|
||||||
{
|
{
|
||||||
assert(p1.X() == p2.X());
|
assert(p1.X() == p2.X());
|
||||||
assert(p1.Y() == p2.Y());
|
assert(p1.Y() == p2.Y());
|
||||||
|
|
@ -570,7 +567,7 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
{
|
{
|
||||||
_z_cs[index] = (VertexIndex) _newM->vert.size();
|
_z_cs[index] = (VertexIndex) _newM->vert.size();
|
||||||
pos = _z_cs[index];
|
pos = _z_cs[index];
|
||||||
Allocator<New_Mesh>::AddVertices( *_newM, 1 );
|
Allocator<NewMeshType>::AddVertices( *_newM, 1 );
|
||||||
v = &_newM->vert[pos];
|
v = &_newM->vert[pos];
|
||||||
v->P()=Interpolate(p1,p2,2);
|
v->P()=Interpolate(p1,p2,2);
|
||||||
return;
|
return;
|
||||||
|
|
@ -582,7 +579,7 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
{
|
{
|
||||||
_z_ns[index] = (VertexIndex) _newM->vert.size();
|
_z_ns[index] = (VertexIndex) _newM->vert.size();
|
||||||
pos = _z_ns[index];
|
pos = _z_ns[index];
|
||||||
Allocator<New_Mesh>::AddVertices( *_newM, 1 );
|
Allocator<NewMeshType>::AddVertices( *_newM, 1 );
|
||||||
v = &_newM->vert[pos];
|
v = &_newM->vert[pos];
|
||||||
v->P()=Interpolate(p1,p2,2);
|
v->P()=Interpolate(p1,p2,2);
|
||||||
return;
|
return;
|
||||||
|
|
@ -598,13 +595,13 @@ public:
|
||||||
|
|
||||||
typedef Walker /*< Old_Mesh,New_Mesh>*/ MyWalker;
|
typedef Walker /*< Old_Mesh,New_Mesh>*/ MyWalker;
|
||||||
|
|
||||||
typedef vcg::tri::MarchingCubes<New_Mesh, MyWalker> MyMarchingCubes;
|
typedef vcg::tri::MarchingCubes<NewMeshType, MyWalker> MyMarchingCubes;
|
||||||
|
|
||||||
///resample the mesh using marching cube algorithm ,the accuracy is the dimension of one cell the parameter
|
///resample the mesh using marching cube algorithm ,the accuracy is the dimension of one cell the parameter
|
||||||
static void Resample(Old_Mesh &old_mesh,New_Mesh &new_mesh, Box3f volumeBox, vcg::Point3<int> accuracy,float max_dist, float thr=0, bool DiscretizeFlag=false, bool MultiSampleFlag=false, bool AbsDistFlag=false, vcg::CallBackPos *cb=0 )
|
static void Resample(OldMeshType &old_mesh, NewMeshType &new_mesh, NewBoxType volumeBox, vcg::Point3<int> accuracy,float max_dist, float thr=0, bool DiscretizeFlag=false, bool MultiSampleFlag=false, bool AbsDistFlag=false, vcg::CallBackPos *cb=0 )
|
||||||
{
|
{
|
||||||
///be sure that the bounding box is updated
|
///be sure that the bounding box is updated
|
||||||
vcg::tri::UpdateBounding<Old_Mesh>::Box(old_mesh);
|
vcg::tri::UpdateBounding<OldMeshType>::Box(old_mesh);
|
||||||
|
|
||||||
MyWalker walker(volumeBox,accuracy);
|
MyWalker walker(volumeBox,accuracy);
|
||||||
|
|
||||||
|
|
@ -620,6 +617,6 @@ static void Resample(Old_Mesh &old_mesh,New_Mesh &new_mesh, Box3f volumeBox, vc
|
||||||
|
|
||||||
};//end class resampler
|
};//end class resampler
|
||||||
|
|
||||||
};//end namespace tri
|
}//end namespace tri
|
||||||
};//end namespace vcg
|
}//end namespace vcg
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue