added multisampling distance field evaluation
This commit is contained in:
parent
f001af1c5c
commit
0e037cabc1
vcg/complex/trimesh/create
|
@ -92,6 +92,7 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
float max_dim; // the limit value of the search (that takes into account of the offset)
|
float 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
|
float 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;
|
||||||
Walker(const Box3f &_bbox, Point3i _siz )
|
Walker(const Box3f &_bbox, Point3i _siz )
|
||||||
{
|
{
|
||||||
this->bbox= _bbox;
|
this->bbox= _bbox;
|
||||||
|
@ -102,6 +103,7 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
CurrentSlice = 0;
|
CurrentSlice = 0;
|
||||||
offset=0;
|
offset=0;
|
||||||
DiscretizeFlag=false;
|
DiscretizeFlag=false;
|
||||||
|
MultiSampleFlag=false;
|
||||||
|
|
||||||
_x_cs = new VertexIndex[ SliceSize ];
|
_x_cs = new VertexIndex[ SliceSize ];
|
||||||
_y_cs = new VertexIndex[ SliceSize ];
|
_y_cs = new VertexIndex[ SliceSize ];
|
||||||
|
@ -144,13 +146,13 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
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
|
||||||
bool DistanceFromMesh(int x,int y,int z,Old_Mesh *mesh, float &dist)
|
field_value DistanceFromMesh(Point3f &pp,Old_Mesh *mesh)
|
||||||
{
|
{
|
||||||
|
float dist;
|
||||||
typename Old_Mesh::FaceType *f=NULL;
|
typename Old_Mesh::FaceType *f=NULL;
|
||||||
const float max_dist = max_dim;
|
const float max_dist = max_dim;
|
||||||
vcg::Point3f testPt;
|
vcg::Point3f testPt;
|
||||||
this->IPiToPf(Point3i(x,y,z),testPt);
|
this->IPfToPf(pp,testPt);
|
||||||
|
|
||||||
vcg::Point3f closestNormV,closestNormF;
|
vcg::Point3f closestNormV,closestNormF;
|
||||||
vcg::Point3f closestPt;
|
vcg::Point3f closestPt;
|
||||||
|
@ -162,7 +164,7 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
DISTFUNCTOR PDistFunct;
|
DISTFUNCTOR PDistFunct;
|
||||||
f = _g.GetClosest(PDistFunct,markerFunctor,testPt,max_dist,dist,closestPt);
|
f = _g.GetClosest(PDistFunct,markerFunctor,testPt,max_dist,dist,closestPt);
|
||||||
|
|
||||||
if (f==NULL) return false;
|
if (f==NULL) return field_value(false,0);
|
||||||
assert(!f->IsD());
|
assert(!f->IsD());
|
||||||
bool retIP;
|
bool retIP;
|
||||||
|
|
||||||
|
@ -183,7 +185,7 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
float signV = dir.dot(closestNormV) ;
|
float signV = dir.dot(closestNormV) ;
|
||||||
float signF = dir.dot(closestNormF) ;
|
float signF = dir.dot(closestNormF) ;
|
||||||
|
|
||||||
// Note that the two sings could be discordant.
|
// Note that the two signs could be discordant.
|
||||||
// Always choose the best one according to the magnitude.
|
// Always choose the best one according to the magnitude.
|
||||||
float signBest;
|
float signBest;
|
||||||
if(fabs(signV) > fabs(signF)) signBest = signV;
|
if(fabs(signV) > fabs(signF)) signBest = signV;
|
||||||
|
@ -191,34 +193,54 @@ template <class OLD_MESH_TYPE,class NEW_MESH_TYPE, class FLT, class DISTFUNCTOR
|
||||||
|
|
||||||
if(signBest<0) dist=-dist;
|
if(signBest<0) dist=-dist;
|
||||||
|
|
||||||
return true;
|
return field_value(true,dist);
|
||||||
|
}
|
||||||
|
|
||||||
|
field_value MultiDistanceFromMesh(Point3f &pp,Old_Mesh *mesh)
|
||||||
|
{
|
||||||
|
float distSum=0;
|
||||||
|
int posCnt=0; // positive results counter
|
||||||
|
const int MultiSample=7;
|
||||||
|
const Point3f delta[7]={Point3f(0,0,0),
|
||||||
|
Point3f( 0.2, -0.01, -0.02),
|
||||||
|
Point3f(-0.2, 0.01, 0.02),
|
||||||
|
Point3f( 0.01, 0.2, 0.01),
|
||||||
|
Point3f( 0.03, -0.2, -0.03),
|
||||||
|
Point3f(-0.02, -0.03, 0.2 ),
|
||||||
|
Point3f(-0.01, 0.01, -0.2 )};
|
||||||
|
|
||||||
|
for(int qq=0;qq<MultiSample;++qq)
|
||||||
|
{
|
||||||
|
Point3f pp2=pp+delta[qq];
|
||||||
|
field_value ff= DistanceFromMesh(pp2,_oldM);
|
||||||
|
if(ff.first==false) return field_value(false,0);
|
||||||
|
distSum += fabs(ff.second);
|
||||||
|
if(ff.second>0) posCnt ++;
|
||||||
|
}
|
||||||
|
if(posCnt<=MultiSample/2) distSum = -distSum;
|
||||||
|
return field_value(true, distSum/MultiSample);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// compute the values if an entire slice (per y) distances>dig of a cell are signed with double of
|
/// compute the values if an entire slice (per y) distances>dig of a cell are signed with double of
|
||||||
/// the distance of the bb
|
/// the distance of the bb
|
||||||
void ComputeSliceValues(int slice,field_value *slice_values)
|
void ComputeSliceValues(int slice,field_value *slice_values)
|
||||||
{
|
{
|
||||||
float dist;
|
|
||||||
for (int i=0; i<=this->siz.X(); i++)
|
for (int i=0; i<=this->siz.X(); i++)
|
||||||
{
|
{
|
||||||
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);
|
||||||
if (DistanceFromMesh(i,slice,k,_oldM,dist))///compute the distance,inside volume of the mesh is negative
|
Point3f pp(i,slice,k);
|
||||||
{
|
if(this->MultiSampleFlag) slice_values[index] = MultiDistanceFromMesh(pp,_oldM);
|
||||||
//put computed values in the slice values matrix
|
else slice_values[index] = DistanceFromMesh(pp,_oldM);
|
||||||
slice_values[index]=field_value(true,dist);
|
|
||||||
//end putting values
|
|
||||||
}
|
|
||||||
else
|
|
||||||
slice_values[index]=field_value(false,0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//ComputeConsensus(slice,slice_values);
|
//ComputeConsensus(slice,slice_values);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
For some reasons it can happens that the sign of the computed distance is 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
|
||||||
*/
|
*/
|
||||||
void ComputeConsensus(int slice, field_value *slice_values)
|
void ComputeConsensus(int slice, field_value *slice_values)
|
||||||
{
|
{
|
||||||
|
@ -574,18 +596,17 @@ typedef Walker /*< Old_Mesh,New_Mesh>*/ MyWalker;
|
||||||
typedef vcg::tri::MarchingCubes<New_Mesh, MyWalker> MyMarchingCubes;
|
typedef vcg::tri::MarchingCubes<New_Mesh, 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,vcg::Point3<int> accuracy,float max_dist, float thr=0, bool DiscretizeFlag=false, vcg::CallBackPos *cb=0 )
|
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, 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<Old_Mesh>::Box(old_mesh);
|
||||||
|
|
||||||
Box3f volumeBox = old_mesh.bbox;
|
|
||||||
volumeBox.Offset(volumeBox.Diag()/10.0f);
|
|
||||||
MyWalker walker(volumeBox,accuracy);
|
MyWalker walker(volumeBox,accuracy);
|
||||||
|
|
||||||
walker.max_dim=max_dist+fabs(thr);
|
walker.max_dim=max_dist+fabs(thr);
|
||||||
walker.offset = - thr;
|
walker.offset = - thr;
|
||||||
walker.DiscretizeFlag = DiscretizeFlag;
|
walker.DiscretizeFlag = DiscretizeFlag;
|
||||||
|
walker.MultiSampleFlag = MultiSampleFlag;
|
||||||
MyMarchingCubes mc(new_mesh, walker);
|
MyMarchingCubes mc(new_mesh, walker);
|
||||||
walker.BuildMesh(old_mesh,new_mesh,mc,cb);
|
walker.BuildMesh(old_mesh,new_mesh,mc,cb);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue