optimized ( distance map are calculated 1 time each point)
This commit is contained in:
parent
06adb386ad
commit
0ebd1f6f91
|
@ -10,6 +10,8 @@
|
||||||
#include <vcg/complex/trimesh/closest.h>
|
#include <vcg/complex/trimesh/closest.h>
|
||||||
#include <vcg/space/box3.h>
|
#include <vcg/space/box3.h>
|
||||||
|
|
||||||
|
//#include <volume_dataset.h>//debugghe
|
||||||
|
|
||||||
namespace vcg {
|
namespace vcg {
|
||||||
namespace trimesh {
|
namespace trimesh {
|
||||||
|
|
||||||
|
@ -48,6 +50,7 @@ class Resampler:RES
|
||||||
typedef typename Old_Mesh::FaceContainer FaceCont;
|
typedef typename Old_Mesh::FaceContainer FaceCont;
|
||||||
typedef typename GridStaticPtr<FaceCont> Grid;
|
typedef typename GridStaticPtr<FaceCont> Grid;
|
||||||
typedef typename vcg::Box3<int> BoundingBox;
|
typedef typename vcg::Box3<int> BoundingBox;
|
||||||
|
//typedef typename std::pair<vcg::Point3i,vcg::Point3i> PointPair;
|
||||||
typedef vcg::tri::Allocator< New_Mesh > Allocator;
|
typedef vcg::tri::Allocator< New_Mesh > Allocator;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -56,6 +59,7 @@ class Resampler:RES
|
||||||
vcg::Point3i _cell_size;
|
vcg::Point3i _cell_size;
|
||||||
|
|
||||||
float max_dim;
|
float max_dim;
|
||||||
|
float dim_diag;
|
||||||
|
|
||||||
int _slice_dimension;
|
int _slice_dimension;
|
||||||
int _current_slice;
|
int _current_slice;
|
||||||
|
@ -67,20 +71,26 @@ class Resampler:RES
|
||||||
VertexIndex *_x_ns; // indici dell'intersezioni della superficie lungo gli Xedge della prossima fetta
|
VertexIndex *_x_ns; // indici dell'intersezioni della superficie lungo gli Xedge della prossima fetta
|
||||||
VertexIndex *_z_ns; // indici dell'intersezioni della superficie lungo gli Zedge della prossima fetta
|
VertexIndex *_z_ns; // indici dell'intersezioni della superficie lungo gli Zedge della prossima fetta
|
||||||
|
|
||||||
|
//float *_v_cs;///values of distance fields for each direction in current slice
|
||||||
|
//float *_v_ns;///values of distance fields for each direction in next slice
|
||||||
|
|
||||||
|
typedef typename std::pair<bool,float> field_value;
|
||||||
|
field_value* _v_cs;
|
||||||
|
field_value* _v_ns;
|
||||||
|
|
||||||
New_Mesh *_newM;
|
New_Mesh *_newM;
|
||||||
Old_Mesh *_oldM;
|
Old_Mesh *_oldM;
|
||||||
Grid _g;
|
Grid _g;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
Walker(const BoundingBox &bbox,vcg::Point3i &resolution)
|
/*Walker(Volume_Dataset <short> *Vo,float in,const BoundingBox &bbox,vcg::Point3i &resolution)
|
||||||
{
|
{*/
|
||||||
assert (resolution.V(0)<=bbox.DimX());
|
/* init=in;
|
||||||
assert (resolution.V(1)<=bbox.DimY());
|
Vol=Vo;*/
|
||||||
assert (resolution.V(2)<=bbox.DimZ());
|
|
||||||
|
|
||||||
_bbox= bbox;
|
void SetBBParameters()
|
||||||
_resolution = resolution;
|
{
|
||||||
_cell_size.X() =_bbox.DimX()/_resolution.X();
|
_cell_size.X() =_bbox.DimX()/_resolution.X();
|
||||||
_cell_size.Y() =_bbox.DimY()/_resolution.Y();
|
_cell_size.Y() =_bbox.DimY()/_resolution.Y();
|
||||||
_cell_size.Z() =_bbox.DimZ()/_resolution.Z();
|
_cell_size.Z() =_bbox.DimZ()/_resolution.Z();
|
||||||
|
@ -118,70 +128,203 @@ class Resampler:RES
|
||||||
Point3f diag=Point3f((float)_cell_size.V(0),(float)_cell_size.V(1),(float)_cell_size.V(2));
|
Point3f diag=Point3f((float)_cell_size.V(0),(float)_cell_size.V(1),(float)_cell_size.V(2));
|
||||||
max_dim=diag.Norm();///diagonal of a cell
|
max_dim=diag.Norm();///diagonal of a cell
|
||||||
|
|
||||||
|
_current_slice = _bbox.min.Y();
|
||||||
|
|
||||||
|
Point3f minD=Point3f((float)_bbox.min.V(0),(float)_bbox.min.V(1),(float)_bbox.min.V(2));
|
||||||
|
Point3f maxD=Point3f((float)_bbox.max.V(0),(float)_bbox.max.V(1),(float)_bbox.max.V(2));
|
||||||
|
Point3f d=(maxD-minD);
|
||||||
|
dim_diag=d.Norm();
|
||||||
|
}
|
||||||
|
|
||||||
|
Walker(const BoundingBox &bbox,vcg::Point3i &resolution)
|
||||||
|
{
|
||||||
|
assert (resolution.V(0)<=bbox.DimX());
|
||||||
|
assert (resolution.V(1)<=bbox.DimY());
|
||||||
|
assert (resolution.V(2)<=bbox.DimZ());
|
||||||
|
|
||||||
|
_bbox= bbox;
|
||||||
|
|
||||||
|
_resolution = resolution;
|
||||||
|
|
||||||
|
SetBBParameters();
|
||||||
|
|
||||||
_x_cs = new VertexIndex[ _slice_dimension ];
|
_x_cs = new VertexIndex[ _slice_dimension ];
|
||||||
_y_cs = new VertexIndex[ _slice_dimension ];
|
_y_cs = new VertexIndex[ _slice_dimension ];
|
||||||
_z_cs = new VertexIndex[ _slice_dimension ];
|
_z_cs = new VertexIndex[ _slice_dimension ];
|
||||||
_x_ns = new VertexIndex[ _slice_dimension ];
|
_x_ns = new VertexIndex[ _slice_dimension ];
|
||||||
_z_ns = new VertexIndex[ _slice_dimension ];
|
_z_ns = new VertexIndex[ _slice_dimension ];
|
||||||
|
|
||||||
|
_v_cs= new field_value[(_resolution.X()+1)*(_resolution.Z()+1)];
|
||||||
|
_v_ns= new field_value[(_resolution.X()+1)*(_resolution.Z()+1)];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
~Walker()
|
~Walker()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
float V(Point3i p)
|
||||||
|
{
|
||||||
|
return (V(p.V(0),p.V(1),p.V(2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
float V(int x,int y,int z)
|
||||||
|
{
|
||||||
|
assert ((y==_current_slice)||(y==(_current_slice+_cell_size.Y())));
|
||||||
|
|
||||||
|
//test if it is outside the bb of the mesh
|
||||||
|
//vcg::Point3f test=vcg::Point3f((float)x,(float)y,(float)z);
|
||||||
|
/*if (!_oldM->bbox.IsIn(test))
|
||||||
|
return (1.f);*/
|
||||||
|
int index=GetSliceIndex(x,z);
|
||||||
|
|
||||||
|
if (y==_current_slice)
|
||||||
|
{
|
||||||
|
//assert(_v_cs[index]<dim_diag);
|
||||||
|
assert(_v_cs[index].first);
|
||||||
|
return _v_cs[index].second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//assert(_v_ns[index]<dim_diag);
|
||||||
|
assert(_v_ns[index].first);
|
||||||
|
return _v_ns[index].second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
///return true if the distance form the mesh is less than maxdim and return distance
|
||||||
|
bool DistanceFromMesh(int x,int y,int z,Old_Mesh *mesh,float &dist)
|
||||||
|
{
|
||||||
|
|
||||||
|
Old_Mesh::FaceType *f=NULL;
|
||||||
|
//float distm=max_dim;
|
||||||
|
dist=max_dim;
|
||||||
|
vcg::Point3f test=vcg::Point3f((float)x,(float)y,(float)z);
|
||||||
|
|
||||||
|
////test if it is outside the bb of the mesh
|
||||||
|
/*if (!_oldM->bbox.IsIn(test))
|
||||||
|
{
|
||||||
|
dist=1.f;
|
||||||
|
return true;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
vcg::Point3f Norm;
|
||||||
|
vcg::Point3f Target;
|
||||||
|
vcg::Point3f pip;
|
||||||
|
|
||||||
|
vcg::trimesh::Closest<Old_Mesh,Grid,float>((*mesh),test,_g,dist,Norm,Target,f,pip);
|
||||||
|
|
||||||
|
if (f==NULL)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Point3f dir=(test-Target);
|
||||||
|
//dist=dir.Norm();
|
||||||
|
|
||||||
|
dir.Normalize();
|
||||||
|
//direction of normal inside the mesh
|
||||||
|
if ((dir*Norm)<0)
|
||||||
|
dist=-dist;
|
||||||
|
//the intersection exist
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///compute the values if an entire slice (per y) distances>dig of a cell are signed with double of
|
||||||
|
/// the distance of the bb
|
||||||
|
void CumputeSliceValues(int slice,field_value *slice_values)
|
||||||
|
{
|
||||||
|
float dist;
|
||||||
|
/*for (int i=_bbox.min.X(); i<=_bbox.max.X()-_cell_size.X(); i+=_cell_size.X())
|
||||||
|
{
|
||||||
|
for (int k=_bbox.min.Z(); k<=_bbox.max.Z()-_cell_size.X(); k+=_cell_size.Z())
|
||||||
|
{
|
||||||
|
*/
|
||||||
|
for (int i=_bbox.min.X(); i<=_bbox.max.X(); i+=_cell_size.X())
|
||||||
|
{
|
||||||
|
for (int k=_bbox.min.Z(); k<=_bbox.max.Z(); k+=_cell_size.Z())
|
||||||
|
{
|
||||||
|
|
||||||
|
int index=GetSliceIndex(i,k);
|
||||||
|
if (DistanceFromMesh(i,slice,k,_oldM,dist))///compute the distance,inside volume of the mesh is negative
|
||||||
|
{
|
||||||
|
//put computed values in the slice values matrix
|
||||||
|
slice_values[index]=field_value(true,dist);
|
||||||
|
//end putting values
|
||||||
|
}
|
||||||
|
else
|
||||||
|
slice_values[index]=field_value(false,dist);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class EXTRACTOR_TYPE>
|
||||||
|
void ProcessSlice(std::vector<vcg::Point3i> cells,EXTRACTOR_TYPE &extractor)
|
||||||
|
{
|
||||||
|
std::vector<vcg::Point3i>::iterator it;
|
||||||
|
|
||||||
|
for (it=cells.begin();it<cells.end();it++)
|
||||||
|
{
|
||||||
|
assert((*it).Y()==_current_slice);
|
||||||
|
assert(V(*it)<=max_dim);
|
||||||
|
assert(_bbox.IsIn(*it));
|
||||||
|
vcg::Point3i p1=(*it)+_cell_size;
|
||||||
|
extractor.ProcessCell((*it), p1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetUGrid()
|
||||||
|
{
|
||||||
|
Point3f min=Point3f((float)_bbox.min.V(0),(float)_bbox.min.V(1),(float)_bbox.min.V(2));
|
||||||
|
Point3f max=Point3f((float)_bbox.max.V(0),(float)_bbox.max.V(1),(float)_bbox.max.V(2));
|
||||||
|
|
||||||
|
Point3f cell=Point3f((float)_cell_size.V(0),(float)_cell_size.V(1),(float)_cell_size.V(2));
|
||||||
|
|
||||||
|
vcg::Box3<float> BBf=vcg::Box3<float>(min-cell,max+cell);
|
||||||
|
|
||||||
|
_g.SetBBox(BBf);
|
||||||
|
|
||||||
|
_g.Set(_oldM->face);
|
||||||
|
}
|
||||||
|
|
||||||
template<class EXTRACTOR_TYPE>
|
template<class EXTRACTOR_TYPE>
|
||||||
void BuildMesh(Old_Mesh &old_mesh,New_Mesh &new_mesh,EXTRACTOR_TYPE &extractor)
|
void BuildMesh(Old_Mesh &old_mesh,New_Mesh &new_mesh,EXTRACTOR_TYPE &extractor)
|
||||||
{
|
{
|
||||||
_newM=&new_mesh;
|
_newM=&new_mesh;
|
||||||
_oldM=&old_mesh;
|
_oldM=&old_mesh;
|
||||||
|
|
||||||
Point3f min=Point3f((float)_bbox.min.V(0),(float)_bbox.min.V(1),(float)_bbox.min.V(2));
|
SetUGrid();
|
||||||
Point3f max=Point3f((float)_bbox.max.V(0),(float)_bbox.max.V(1),(float)_bbox.max.V(2));
|
|
||||||
|
|
||||||
vcg::Box3<float> BBf=vcg::Box3<float>(min,max);
|
|
||||||
|
|
||||||
_g.SetBBox(BBf);
|
|
||||||
|
|
||||||
_g.Set(_oldM->face);
|
|
||||||
|
|
||||||
_newM->Clear();
|
_newM->Clear();
|
||||||
vcg::Point3i p1, p2;
|
|
||||||
|
|
||||||
|
vcg::Point3i p1, p2;
|
||||||
Begin();
|
Begin();
|
||||||
extractor.Initialize();
|
extractor.Initialize();
|
||||||
for (int j=_bbox.min.Y(); j<_bbox.max.Y()-_cell_size.Y(); j+=_cell_size.Y())
|
for (int j=_bbox.min.Y(); j<=_bbox.max.Y()-_cell_size.Y(); j+=_cell_size.Y())
|
||||||
{
|
{
|
||||||
for (int i=_bbox.min.X(); i<_bbox.max.X()-_cell_size.X(); i+=_cell_size.X())
|
ProcessSlice<EXTRACTOR_TYPE>(FindCells(),extractor);//find cells where there is the isosurface and examine it
|
||||||
{
|
|
||||||
for (int k=_bbox.min.Z(); k<_bbox.max.Z()-_cell_size.Z(); k+=_cell_size.Z())
|
|
||||||
{
|
|
||||||
p1.X()=i;
|
|
||||||
p1.Y()=j;
|
|
||||||
p1.Z()=k;
|
|
||||||
p2.X()=i+_cell_size.X();
|
|
||||||
p2.Y()=j+_cell_size.Y();
|
|
||||||
p2.Z()=k+_cell_size.Z();
|
|
||||||
if (ExistIntersection(p1,p2))
|
|
||||||
extractor.ProcessCell(p1, p2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
NextSlice();
|
NextSlice();
|
||||||
}
|
}
|
||||||
extractor.Finalize();
|
extractor.Finalize();
|
||||||
|
|
||||||
/*_newM= NULL;*/
|
/*_newM= NULL;*/
|
||||||
};
|
|
||||||
|
|
||||||
float V(Point3i p)
|
|
||||||
{
|
|
||||||
return (V(p.V(0),p.V(1),p.V(2)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
///control if exist any intersection with the mesh using all points of the cell
|
//return the index of a vertex in slide as it was stored
|
||||||
bool ExistIntersection(Point3i min,Point3i max)
|
int GetSliceIndex(int x,int z)
|
||||||
{
|
{
|
||||||
vcg::Point3i _corners[8];
|
int ii = (x - _bbox.min.X())/_cell_size.X();
|
||||||
|
int zz = (z - _bbox.min.Z())/_cell_size.Z();
|
||||||
|
VertexIndex index = ii+zz*(_resolution.X()+1);
|
||||||
|
return (index);
|
||||||
|
}
|
||||||
|
|
||||||
|
///return true if exist in the cell one value <0 and another one >0
|
||||||
|
bool FindMinMax(vcg::Point3i min,vcg::Point3i max)
|
||||||
|
{
|
||||||
|
assert((min.X()<max.X())&&(min.Y()<max.Y())&&(min.Z()<max.Z()));
|
||||||
|
|
||||||
|
vcg::Point3i _corners[8];
|
||||||
|
///control for each corner of the
|
||||||
_corners[0].X()=min.X(); _corners[0].Y()=min.Y(); _corners[0].Z()=min.Z();
|
_corners[0].X()=min.X(); _corners[0].Y()=min.Y(); _corners[0].Z()=min.Z();
|
||||||
_corners[1].X()=max.X(); _corners[1].Y()=min.Y(); _corners[1].Z()=min.Z();
|
_corners[1].X()=max.X(); _corners[1].Y()=min.Y(); _corners[1].Z()=min.Z();
|
||||||
_corners[2].X()=max.X(); _corners[2].Y()=max.Y(); _corners[2].Z()=min.Z();
|
_corners[2].X()=max.X(); _corners[2].Y()=max.Y(); _corners[2].Z()=min.Z();
|
||||||
|
@ -191,78 +334,203 @@ class Resampler:RES
|
||||||
_corners[6].X()=max.X(); _corners[6].Y()=max.Y(); _corners[6].Z()=max.Z();
|
_corners[6].X()=max.X(); _corners[6].Y()=max.Y(); _corners[6].Z()=max.Z();
|
||||||
_corners[7].X()=min.X(); _corners[7].Y()=max.Y(); _corners[7].Z()=max.Z();
|
_corners[7].X()=min.X(); _corners[7].Y()=max.Y(); _corners[7].Z()=max.Z();
|
||||||
|
|
||||||
////control if there is a face
|
float min_value=max_dim;
|
||||||
vcg::Point3f Norm;
|
float max_value=-max_dim;
|
||||||
Old_Mesh::FaceType *f=NULL;
|
field_value value;
|
||||||
float distm;
|
|
||||||
Point3f pip;
|
|
||||||
Point3f Target;
|
|
||||||
vcg::Point3f test;
|
|
||||||
for (int i=0;i<8;i++)
|
for (int i=0;i<8;i++)
|
||||||
{
|
{
|
||||||
f=NULL;
|
//if one value is > that bbox.diag this value is not valid
|
||||||
distm=max_dim;
|
//that is the mark
|
||||||
test=vcg::Point3f((float)_corners[i].X(),(float)_corners[i].Y(),(float)_corners[i].Z());
|
|
||||||
vcg::trimesh::Closest<Old_Mesh,Grid,float>((*_oldM),test,_g,distm,Norm,Target,f,pip);
|
|
||||||
if (f==NULL)
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
///si potrebbe ottimizzare sfruttando valori che in realta' ho gia' calcolato
|
if (_corners[i].Y()==_current_slice)
|
||||||
float V(int pi, int pj, int pk)
|
value=_v_cs[GetSliceIndex(_corners[i].X(),_corners[i].Z())];
|
||||||
{
|
|
||||||
vcg::Point3f Norm;
|
|
||||||
Old_Mesh::FaceType *f=NULL;
|
|
||||||
float dist=max_dim;;
|
|
||||||
vcg::Point3f test=vcg::Point3f((float)pi,(float)pj,(float)pk);
|
|
||||||
|
|
||||||
Point3f pip;
|
|
||||||
Point3f Target;
|
|
||||||
vcg::trimesh::Closest<Old_Mesh,Grid,float>((*_oldM),test,_g,dist,Norm,Target,f,pip);
|
|
||||||
|
|
||||||
assert(f!=NULL);
|
|
||||||
|
|
||||||
Point3f dir=(test-Target);
|
|
||||||
|
|
||||||
//dist=dir.Norm();
|
|
||||||
dir=dir.Normalize();
|
|
||||||
|
|
||||||
//direction of normal inside or outside the mesh
|
|
||||||
if ((f->N()*dir)>0)
|
|
||||||
return (dist);
|
|
||||||
else
|
else
|
||||||
return (-dist);
|
value=_v_ns[GetSliceIndex(_corners[i].X(),_corners[i].Z())];
|
||||||
|
|
||||||
|
if (value.first==false)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//assign new values of min and max
|
||||||
|
if (value.second<min_value)
|
||||||
|
min_value=value.second;
|
||||||
|
if (value.second>max_value)
|
||||||
|
max_value=value.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////do not test with zero..
|
||||||
|
if ((min_value<=0.f)&&(max_value>=0.f))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
//return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
///filter the cells from to_hexamine vector to the ones that
|
||||||
|
/// min and max of the cell are <0 and >0
|
||||||
|
std::vector<vcg::Point3i> FindCells()
|
||||||
|
{
|
||||||
|
std::vector<vcg::Point3i> res;
|
||||||
|
for (int i=_bbox.min.X(); i<=_bbox.max.X()-_cell_size.X(); i+=_cell_size.X())
|
||||||
|
{
|
||||||
|
for (int k=_bbox.min.Z(); k<=_bbox.max.Z()-_cell_size.Z(); k+=_cell_size.Z())
|
||||||
|
{
|
||||||
|
int x0=i;
|
||||||
|
int y0=_current_slice;
|
||||||
|
int z0=k;
|
||||||
|
int x1=x0+_cell_size.X();
|
||||||
|
int y1=y0+_cell_size.Y();
|
||||||
|
int z1=z0+_cell_size.Z();
|
||||||
|
if (FindMinMax(Point3i(x0,y0,z0),Point3i(x1,y1,z1)))
|
||||||
|
res.push_back(Point3i(x0,y0,z0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
//swap slices , the initial value of distance fields ids set as double of bbox of space
|
||||||
|
void NextSlice()
|
||||||
|
{
|
||||||
|
|
||||||
|
memset(_x_cs, -1, _slice_dimension*sizeof(VertexIndex));
|
||||||
|
memset(_y_cs, -1, _slice_dimension*sizeof(VertexIndex));
|
||||||
|
memset(_z_cs, -1, _slice_dimension*sizeof(VertexIndex));
|
||||||
|
|
||||||
|
|
||||||
|
std::swap(_x_cs, _x_ns);
|
||||||
|
std::swap(_z_cs, _z_ns);
|
||||||
|
|
||||||
|
std::swap(_v_cs, _v_ns);
|
||||||
|
|
||||||
|
_current_slice += _cell_size.Y();
|
||||||
|
|
||||||
|
//memset(_v_ns, dim_diag*2.f, _slice_dimension*sizeof(float));
|
||||||
|
//memset(_v_ns, field_value(false,0.f), _slice_dimension*sizeof(field_value));
|
||||||
|
|
||||||
|
CumputeSliceValues(_current_slice+ _cell_size.Y(),_v_ns);
|
||||||
|
}
|
||||||
|
|
||||||
|
//initialize data strucures , the initial value of distance fields ids set as double of bbox of space
|
||||||
|
void Begin()
|
||||||
|
{
|
||||||
|
|
||||||
|
_current_slice = _bbox.min.Y();
|
||||||
|
|
||||||
|
memset(_x_cs, -1, _slice_dimension*sizeof(VertexIndex));
|
||||||
|
memset(_y_cs, -1, _slice_dimension*sizeof(VertexIndex));
|
||||||
|
memset(_z_cs, -1, _slice_dimension*sizeof(VertexIndex));
|
||||||
|
memset(_x_ns, -1, _slice_dimension*sizeof(VertexIndex));
|
||||||
|
memset(_z_ns, -1, _slice_dimension*sizeof(VertexIndex));
|
||||||
|
|
||||||
|
/*memset(_v_cs, dim_diag*2.f, _slice_dimension*sizeof(float));
|
||||||
|
memset(_v_ns, dim_diag*2.f, _slice_dimension*sizeof(float));*/
|
||||||
|
|
||||||
|
/*memset(_v_cs, field_value(false,0.f), _slice_dimension*sizeof(field_value));
|
||||||
|
memset(_v_ns, field_value(false,0.f), _slice_dimension*sizeof(field_value));*/
|
||||||
|
|
||||||
|
CumputeSliceValues(_current_slice,_v_cs);
|
||||||
|
CumputeSliceValues(_current_slice+_cell_size.Y(),_v_ns);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool Exist(const vcg::Point3i &p1, const vcg::Point3i &p2, VertexPointer &v)
|
bool Exist(const vcg::Point3i &p1, const vcg::Point3i &p2, VertexPointer &v)
|
||||||
{
|
{
|
||||||
return false;
|
int i = (p1.X() - _bbox.min.X())/_cell_size.X();
|
||||||
//int i_idx = p1.X()-_bbox.min.X();
|
int z = (p1.Z() - _bbox.min.Z())/_cell_size.Z();
|
||||||
//int k_idx = p2.Z()-_bbox.min.Z();
|
VertexIndex index = i+z*_resolution.X();
|
||||||
//int index = i_idx+k_idx*_resolution.X();
|
|
||||||
//if (p1.X()!=p2.X()) //intersezione della superficie con un Xedge
|
//VertexIndex index =GetSliceIndex(//
|
||||||
// return (p1.Y()==_current_slice)? _x_cs[index]!=-1 : _x_ns[index]!=-1;
|
int v_ind = 0;
|
||||||
//else if (p1.Y()!=p2.Y()) //intersezione della superficie con un Yedge
|
if (p1.X()!=p2.X()) //intersezione della superficie con un Xedge
|
||||||
// return _y_cs[index]!=-1;
|
{
|
||||||
//else if (p1.Z()!=p2.Z()) //intersezione della superficie con un Zedge
|
if (p1.Y()==_current_slice)
|
||||||
// return (p1.Y()==_current_slice)? _z_cs[index]!=-1 : _z_ns[index]!=-1;
|
{
|
||||||
|
if (_x_cs[index]!=-1)
|
||||||
|
{
|
||||||
|
v_ind = _x_cs[index];
|
||||||
|
v = &_newM->vert[v_ind];
|
||||||
|
assert(!v->IsD());
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_x_ns[index]!=-1)
|
||||||
|
{
|
||||||
|
v_ind = _x_ns[index];
|
||||||
|
v = &_newM->vert[v_ind];
|
||||||
|
assert(!v->IsD());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (p1.Y()!=p2.Y()) //intersezione della superficie con un Yedge
|
||||||
|
{
|
||||||
|
if (_y_cs[index]!=-1)
|
||||||
|
{
|
||||||
|
v_ind =_y_cs[index];
|
||||||
|
v = &_newM->vert[v_ind];
|
||||||
|
assert(!v->IsD());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
v = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (p1.Z()!=p2.Z())
|
||||||
|
//intersezione della superficie con un Zedge
|
||||||
|
{
|
||||||
|
if (p1.Y()==_current_slice)
|
||||||
|
{
|
||||||
|
if ( _z_cs[index]!=-1)
|
||||||
|
{
|
||||||
|
v_ind = _z_cs[index];
|
||||||
|
v = &_newM->vert[v_ind];
|
||||||
|
assert(!v->IsD());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_z_ns[index]!=-1)
|
||||||
|
{
|
||||||
|
v_ind = _z_ns[index];
|
||||||
|
v = &_newM->vert[v_ind];
|
||||||
|
assert(!v->IsD());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
v = NULL;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
assert (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
///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 = V(p1);
|
float f1 = (float)V(p1);
|
||||||
float f2 = V(p2);
|
float f2 = (float)V(p2);
|
||||||
float u = (float) f1/(f1-f2);
|
float u = (float) f1/(f1-f2);
|
||||||
NewCoordType ret=vcg::Point3f((float)p1.V(0),(float)p1.V(1),(float)p1.V(2));
|
NewCoordType ret=vcg::Point3f((float)p1.V(0),(float)p1.V(1),(float)p1.V(2));
|
||||||
ret.V(dir) = (float) p1.V(dir)*(1-u) + u*p2.V(dir);
|
ret.V(dir) = (float) p1.V(dir)*(1.f-u) + u*(float)p2.V(dir);
|
||||||
return (ret);
|
return (ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///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, VertexPointer &v)
|
||||||
{
|
{
|
||||||
|
assert ((p1.Y()==_current_slice)||(p1.Y()==(_current_slice+_cell_size.Y())));
|
||||||
|
|
||||||
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();
|
||||||
VertexIndex index = i+z*_resolution.X();
|
VertexIndex index = i+z*_resolution.X();
|
||||||
|
@ -294,8 +562,11 @@ class Resampler:RES
|
||||||
v = &_newM->vert[pos];
|
v = &_newM->vert[pos];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///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, VertexPointer &v)
|
||||||
{
|
{
|
||||||
|
assert ((p1.Y()==_current_slice)||(p1.Y()==(_current_slice+_cell_size.Y())));
|
||||||
|
|
||||||
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();
|
||||||
VertexIndex index = i+z*_resolution.X();
|
VertexIndex index = i+z*_resolution.X();
|
||||||
|
@ -311,8 +582,11 @@ class Resampler:RES
|
||||||
v = &_newM->vert[pos];
|
v = &_newM->vert[pos];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///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, VertexPointer &v)
|
||||||
{
|
{
|
||||||
|
assert ((p1.Y()==_current_slice)||(p1.Y()==(_current_slice+_cell_size.Y())));
|
||||||
|
|
||||||
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();
|
||||||
VertexIndex index = i+z*_resolution.X();
|
VertexIndex index = i+z*_resolution.X();
|
||||||
|
@ -345,31 +619,6 @@ class Resampler:RES
|
||||||
v = &_newM->vert[pos];
|
v = &_newM->vert[pos];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void NextSlice()
|
|
||||||
{
|
|
||||||
memset(_x_cs, -1, _slice_dimension*sizeof(VertexIndex));
|
|
||||||
memset(_y_cs, -1, _slice_dimension*sizeof(VertexIndex));
|
|
||||||
memset(_z_cs, -1, _slice_dimension*sizeof(VertexIndex));
|
|
||||||
|
|
||||||
std::swap(_x_cs, _x_ns);
|
|
||||||
std::swap(_z_cs, _z_ns);
|
|
||||||
|
|
||||||
_current_slice += _cell_size.Y();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Begin()
|
|
||||||
{
|
|
||||||
_current_slice = _bbox.min.Y();
|
|
||||||
|
|
||||||
memset(_x_cs, -1, _slice_dimension*sizeof(VertexIndex));
|
|
||||||
memset(_y_cs, -1, _slice_dimension*sizeof(VertexIndex));
|
|
||||||
memset(_z_cs, -1, _slice_dimension*sizeof(VertexIndex));
|
|
||||||
memset(_x_ns, -1, _slice_dimension*sizeof(VertexIndex));
|
|
||||||
memset(_z_ns, -1, _slice_dimension*sizeof(VertexIndex));
|
|
||||||
|
|
||||||
}
|
|
||||||
};//end class walker
|
};//end class walker
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -402,11 +651,10 @@ static void Resample(Old_Mesh &old_mesh,New_Mesh &new_mesh,vcg::Point3<int> accu
|
||||||
Point3i min=Point3i((int)ceil(old_mesh.bbox.min.V(0)),(int)ceil(old_mesh.bbox.min.V(1)),(int)ceil(old_mesh.bbox.min.V(2)));
|
Point3i min=Point3i((int)ceil(old_mesh.bbox.min.V(0)),(int)ceil(old_mesh.bbox.min.V(1)),(int)ceil(old_mesh.bbox.min.V(2)));
|
||||||
Point3i max=Point3i((int)ceil(old_mesh.bbox.max.V(0)),(int)ceil(old_mesh.bbox.max.V(1)),(int)ceil(old_mesh.bbox.max.V(2)));
|
Point3i max=Point3i((int)ceil(old_mesh.bbox.max.V(0)),(int)ceil(old_mesh.bbox.max.V(1)),(int)ceil(old_mesh.bbox.max.V(2)));
|
||||||
|
|
||||||
///exetend out to BB for resample the limits of the mesh
|
|
||||||
/*min-=Point3i(1,1,1);
|
|
||||||
max+=Point3i(1,1,1);*/
|
|
||||||
vcg::Box3<int> boxInt=Box3<int>(min,max);
|
vcg::Box3<int> boxInt=Box3<int>(min,max);
|
||||||
|
|
||||||
|
|
||||||
float rx=((float)boxInt.DimX())/(float)accuracy.X();
|
float rx=((float)boxInt.DimX())/(float)accuracy.X();
|
||||||
float ry=((float)boxInt.DimY())/(float)accuracy.Y();
|
float ry=((float)boxInt.DimY())/(float)accuracy.Y();
|
||||||
float rz=((float)boxInt.DimZ())/(float)accuracy.Z();
|
float rz=((float)boxInt.DimZ())/(float)accuracy.Z();
|
||||||
|
@ -418,6 +666,7 @@ static void Resample(Old_Mesh &old_mesh,New_Mesh &new_mesh,vcg::Point3<int> accu
|
||||||
Point3i res=Point3i(rxi,ryi,rzi);
|
Point3i res=Point3i(rxi,ryi,rzi);
|
||||||
|
|
||||||
MyWalker walker(boxInt,res);
|
MyWalker walker(boxInt,res);
|
||||||
|
|
||||||
if (mm==MMarchingCubes)
|
if (mm==MMarchingCubes)
|
||||||
{
|
{
|
||||||
MarchingCubes mc(new_mesh, walker);
|
MarchingCubes mc(new_mesh, walker);
|
||||||
|
|
Loading…
Reference in New Issue