Added FillSelectedFaceEdgeVector FaceEdgeSelCrease and BuildFromFaceEdgeSel function

It is much more meaningful to create a poly mesh from selected edges instead abusing of the faux edges bit
Similarly it much butter to select crease edges for subsuequent uses
This commit is contained in:
Paolo Cignoni 2018-05-05 00:36:43 +02:00
parent e78d9c252c
commit 884faa97c1
3 changed files with 35 additions and 24 deletions

View File

@ -768,11 +768,11 @@ void BuildMeshFromCoordVector( MeshType & in, const V & v)
template <class TriMeshType,class EdgeMeshType >
void BuildFromNonFaux(TriMeshType &in, EdgeMeshType &out)
void BuildFromFaceEdgeSel(TriMeshType &in, EdgeMeshType &out)
{
tri::RequireCompactness(in);
std::vector<typename tri::UpdateTopology<TriMeshType>::PEdge> edgevec;
tri::UpdateTopology<TriMeshType>::FillUniqueEdgeVector(in, edgevec, false);
tri::UpdateTopology<TriMeshType>::FillSelectedFaceEdgeVector(in, edgevec);
out.Clear();
for(size_t i=0;i<in.vert.size();++i)
tri::Allocator<EdgeMeshType>::AddVertex(out, in.vert[i].P());

View File

@ -122,10 +122,7 @@ public:
static void FaceClearB(MeshType &m) { FaceClear(m,FaceType::BORDER012);}
static void FaceClearS(MeshType &m) {FaceClear(m,FaceType::SELECTED);}
static void FaceClearF(MeshType &m) { FaceClear(m,FaceType::FAUX012);}
static void FaceClearCreases(MeshType &m) { FaceClear(m,FaceType::CREASE0);
FaceClear(m,FaceType::CREASE1);
FaceClear(m,FaceType::CREASE2);
}
static void FaceClearFaceEdgeS(MeshType &m) { FaceClear(m,FaceType::FACEEDGESEL012 ); }
static void EdgeSetV(MeshType &m) { EdgeSet(m,EdgeType::VISITED);}
static void VertexSetV(MeshType &m) { VertexSet(m,VertexType::VISITED);}
@ -380,20 +377,20 @@ public:
/// \brief Marks feature edges according to two signed dihedral angles.
/// Actually it marks as fauxedges all the non feature edges,
/// e.g. the edges where the signed dihedral angle between the normal of two incident faces ,
/// is between the two given thresholds.
/// In this way all the edges that are almost planar are marked as Faux Edges (e.g. edges to be ignored)
/// Actually it uses the face_edge selection bit on faces,
/// we select the edges where the signed dihedral angle between the normal of two incident faces ,
/// is outside the two given thresholds.
/// In this way all the edges that are almost planar are marked as non selected (e.g. edges to be ignored)
/// Note that it uses the signed dihedral angle convention (negative for concave edges and positive for convex ones);
///
/// Optionally it can also mark as feature edges also the boundary edges.
///
static void FaceFauxSignedCrease(MeshType &m, float AngleRadNeg, float AngleRadPos, bool MarkBorderFlag = false )
static void FaceEdgeSelSignedCrease(MeshType &m, float AngleRadNeg, float AngleRadPos, bool MarkBorderFlag = false )
{
RequirePerFaceFlags(m);
RequireFFAdjacency(m);
//initially Nothing is faux (e.g all crease)
FaceClearF(m);
FaceClearFaceEdgeS(m);
// Then mark faux only if the signed angle is the range.
for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
{
@ -402,12 +399,12 @@ public:
if(!face::IsBorder(*fi,z) )
{
ScalarType angle = DihedralAngleRad(*fi,z);
if(angle>AngleRadNeg && angle<AngleRadPos)
(*fi).SetF(z);
if(angle<AngleRadNeg || angle>AngleRadPos)
(*fi).SetFaceEdgeS(z);
}
else
{
if(MarkBorderFlag) (*fi).SetF(z);
if(MarkBorderFlag) (*fi).SetFaceEdgeS(z);
}
}
}
@ -416,29 +413,30 @@ public:
/// \brief Marks feature edges according to border flag.
/// Actually it marks as fauxedges all the non border edges,
///
static void FaceFauxBorder(MeshType &m)
static void FaceEdgeSelBorder(MeshType &m)
{
RequirePerFaceFlags(m);
RequireFFAdjacency(m);
//initially Nothing is faux (e.g all crease)
FaceClearF(m);
FaceClearFaceEdgeS(m);
// Then mark faux only if the signed angle is the range.
for(FaceIterator fi=m.face.begin();fi!=m.face.end();++fi) if(!(*fi).IsD())
{
for(int z=0;z<(*fi).VN();++z)
{
if(!face::IsBorder(*fi,z) ) (*fi).SetF(z);
if(!face::IsBorder(*fi,z) ) (*fi).SetFaceEdgeS(z);
}
}
}
/// \brief Marks feature edges according to a given angle
/// Actually it marks as fauxedges all the non feature edges,
/// e.g. the edge such that the angle between the normal of two faces sharing it is less than the given threshold.
/// In this way all the near planar edges are marked as Faux Edges (e.g. edges to be ignored)
static void FaceFauxCrease(MeshType &m,float AngleRad)
/// Actually it uses the face_edge selection bit on faces,
/// we select the edges where the dihedral angle between the normal of two incident faces is larger than ,
/// the given thresholds.
/// In this way all the near planar edges are marked remains not selected (e.g. edges to be ignored)
static void FaceEdgeSelCrease(MeshType &m,float AngleRad)
{
FaceFauxSignedCrease(m,-AngleRad,AngleRad);
FaceEdgeSelSignedCrease(m,-AngleRad,AngleRad);
}

View File

@ -138,6 +138,20 @@ static void FillUniqueEdgeVector(MeshType &m, std::vector<PEdge> &edgeVec, bool
edgeVec.resize(newEnd-edgeVec.begin()); // redundant! remove?
}
static void FillSelectedFaceEdgeVector(MeshType &m, std::vector<PEdge> &edgeVec)
{
edgeVec.reserve(m.fn*3);
ForEachFace(m, [&](FaceType &f){
for(int j=0;j<f.VN();++j)
if(f.IsFaceEdgeS(j))
edgeVec.push_back(PEdge(&f,j));
});
sort(edgeVec.begin(), edgeVec.end()); // oredering by vertex
edgeVec.erase(std::unique(edgeVec.begin(), edgeVec.end()),edgeVec.end());
}
/*! \brief Initialize the edge vector all the edges that can be inferred from current face vector, setting up all the current adjacency relations
*
@ -431,7 +445,6 @@ static void TestVertexEdge(MeshType &m)
int cnt =0;
for(edge::VEIterator<EdgeType> vei(&*vi);!vei.End();++vei)
cnt++;
EdgeType *vep = vi->VEp();
assert((numVertex[tri::Index(m,*vi)] == 0) == (vi->VEp()==0) );
assert(cnt==numVertex[tri::Index(m,*vi)]);
}