Fixed a small bug causing not preservation of border vertex coordinates in some cases during polychord collapse.
This commit is contained in:
parent
75534804cf
commit
d2b0ac56c7
|
@ -68,15 +68,17 @@ public:
|
||||||
* @brief The PC_ResultCode enum codifies the result type of a polychord collapse operation.
|
* @brief The PC_ResultCode enum codifies the result type of a polychord collapse operation.
|
||||||
*/
|
*/
|
||||||
enum PC_ResultCode {
|
enum PC_ResultCode {
|
||||||
PC_SUCCESS = 0x00,
|
PC_SUCCESS = 0x000,
|
||||||
PC_NOTMANIF = 0x01,
|
PC_NOTMANIF = 0x001,
|
||||||
PC_NOTQUAD = 0x02,
|
PC_NOTQUAD = 0x002,
|
||||||
PC_NOLINKCOND = 0x04,
|
PC_NOLINKCOND = 0x004,
|
||||||
PC_SINGBOTH = 0x08,
|
PC_SINGSIDEA = 0x008,
|
||||||
PC_SELFINTERSECT = 0x10,
|
PC_SINGSIDEB = 0x010,
|
||||||
PC_NOMOREMANIF = 0x20,
|
PC_SINGBOTH = 0x020,
|
||||||
PC_VOID = 0x40,
|
PC_SELFINTERSECT = 0x040,
|
||||||
PC_OTHER = 0x80
|
PC_NOMOREMANIF = 0x080,
|
||||||
|
PC_VOID = 0x100,
|
||||||
|
PC_OTHER = 0x100
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -647,14 +649,12 @@ public:
|
||||||
if (pos.IsNull())
|
if (pos.IsNull())
|
||||||
return PC_VOID;
|
return PC_VOID;
|
||||||
|
|
||||||
// vcg::tri::io::Exporter<PolyMeshType>::Save(mesh, "current_step.obj");
|
|
||||||
|
|
||||||
vcg::face::Pos<FaceType> tempPos, startPos;
|
vcg::face::Pos<FaceType> tempPos, startPos;
|
||||||
|
|
||||||
// check if the sequence of facets is a polychord and find the starting coord
|
// check if the sequence of facets is a polychord and find the starting coord
|
||||||
PC_ResultCode resultCode = CheckPolychordFindStartPosition(pos, startPos, checkSing);
|
PC_ResultCode resultCode = CheckPolychordFindStartPosition(pos, startPos, checkSing);
|
||||||
// if not successful, visit the sequence for marking it and return
|
// if not successful, visit the sequence for marking it and return
|
||||||
if (resultCode != PC_SUCCESS) {
|
if (resultCode != PC_SUCCESS && resultCode != PC_SINGSIDEA && resultCode != PC_SINGSIDEB) {
|
||||||
// if not manifold, visit the entire polychord ending on the non-manifold edge
|
// if not manifold, visit the entire polychord ending on the non-manifold edge
|
||||||
if (resultCode == PC_NOTMANIF) {
|
if (resultCode == PC_NOTMANIF) {
|
||||||
tempPos = pos;
|
tempPos = pos;
|
||||||
|
@ -708,10 +708,10 @@ public:
|
||||||
|
|
||||||
// now collapse
|
// now collapse
|
||||||
CoordType point;
|
CoordType point;
|
||||||
int valenceA = 0, valenceB = 0;
|
// int valenceA = 0, valenceB = 0;
|
||||||
vcg::face::Pos<FaceType> runPos = startPos;
|
vcg::face::Pos<FaceType> runPos = startPos;
|
||||||
vcg::face::JumpingPos<FaceType> tmpPos;
|
vcg::face::JumpingPos<FaceType> tmpPos;
|
||||||
bool onSideA = false, onSideB = false;
|
// bool onSideA = false, onSideB = false;
|
||||||
vcg::face::Pos<FaceType> sideA, sideB;
|
vcg::face::Pos<FaceType> sideA, sideB;
|
||||||
typedef std::queue<VertexPointer *> FacesVertex;
|
typedef std::queue<VertexPointer *> FacesVertex;
|
||||||
typedef std::pair<VertexPointer, FacesVertex> FacesVertexPair;
|
typedef std::pair<VertexPointer, FacesVertex> FacesVertexPair;
|
||||||
|
@ -725,43 +725,14 @@ public:
|
||||||
std::queue<VertexPointer> verticesToDeleteQueue;
|
std::queue<VertexPointer> verticesToDeleteQueue;
|
||||||
std::queue<FacePointer> facesToDeleteQueue;
|
std::queue<FacePointer> facesToDeleteQueue;
|
||||||
|
|
||||||
if (checkSing) {
|
|
||||||
do {
|
|
||||||
runPos.FlipV();
|
|
||||||
valenceB = runPos.NumberOfIncidentVertices();
|
|
||||||
tmpPos.Set(runPos.F(), runPos.E(), runPos.V());
|
|
||||||
if (tmpPos.FindBorder())
|
|
||||||
++valenceB;
|
|
||||||
runPos.FlipV();
|
|
||||||
valenceA = runPos.NumberOfIncidentVertices();
|
|
||||||
tmpPos.Set(runPos.F(), runPos.E(), runPos.V());
|
|
||||||
if (tmpPos.FindBorder())
|
|
||||||
++valenceA;
|
|
||||||
if (valenceA != 4)
|
|
||||||
onSideA = true;
|
|
||||||
if (valenceB != 4)
|
|
||||||
onSideB = true;
|
|
||||||
assert(!onSideA || !onSideB);
|
|
||||||
|
|
||||||
if (runPos != startPos && runPos.IsBorder())
|
|
||||||
break;
|
|
||||||
|
|
||||||
// go on next edge/face
|
|
||||||
runPos.FlipE();
|
|
||||||
runPos.FlipV();
|
|
||||||
runPos.FlipE();
|
|
||||||
runPos.FlipF();
|
|
||||||
} while (runPos != startPos);
|
|
||||||
}
|
|
||||||
|
|
||||||
runPos = startPos;
|
runPos = startPos;
|
||||||
do {
|
do {
|
||||||
// compute new vertex
|
// compute new vertex
|
||||||
point = (runPos.V()->P() + runPos.VFlip()->P()) / 2.f;
|
point = (runPos.V()->P() + runPos.VFlip()->P()) / 2.f;
|
||||||
if (checkSing) {
|
if (checkSing) {
|
||||||
if (onSideA)
|
if (resultCode == PC_SINGSIDEA)
|
||||||
point = runPos.V()->P();
|
point = runPos.V()->P();
|
||||||
if (onSideB)
|
else if (resultCode == PC_SINGSIDEB)
|
||||||
point = runPos.VFlip()->P();
|
point = runPos.VFlip()->P();
|
||||||
}
|
}
|
||||||
runPos.V()->P() = point;
|
runPos.V()->P() = point;
|
||||||
|
@ -829,9 +800,9 @@ public:
|
||||||
// compute new vertex on the last (border) edge
|
// compute new vertex on the last (border) edge
|
||||||
point = (runPos.V()->P() + runPos.VFlip()->P()) / 2.f;
|
point = (runPos.V()->P() + runPos.VFlip()->P()) / 2.f;
|
||||||
if (checkSing) {
|
if (checkSing) {
|
||||||
if (onSideA)
|
if (resultCode == PC_SINGSIDEA)
|
||||||
point = runPos.V()->P();
|
point = runPos.V()->P();
|
||||||
if (onSideB)
|
else if (resultCode == PC_SINGSIDEB)
|
||||||
point = runPos.VFlip()->P();
|
point = runPos.VFlip()->P();
|
||||||
}
|
}
|
||||||
runPos.V()->P() = point;
|
runPos.V()->P() = point;
|
||||||
|
@ -878,12 +849,6 @@ public:
|
||||||
verticesToDeleteQueue.pop();
|
verticesToDeleteQueue.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (!CheckConsistent(mesh)) {
|
|
||||||
// int mask = vcg::tri::io::Mask::IOM_FACECOLOR;
|
|
||||||
// vcg::tri::io::Exporter<PolyMeshType>::Save(mesh, "current_step_failed.obj", mask);
|
|
||||||
// assert(false);
|
|
||||||
// }
|
|
||||||
|
|
||||||
return PC_SUCCESS;
|
return PC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -960,7 +925,7 @@ public:
|
||||||
// check and find start pos
|
// check and find start pos
|
||||||
resultCode = CheckPolychordFindStartPosition(pos, startPos, false);
|
resultCode = CheckPolychordFindStartPosition(pos, startPos, false);
|
||||||
// visit the polychord
|
// visit the polychord
|
||||||
if (resultCode == PC_SUCCESS || resultCode == PC_SINGBOTH) {
|
if (resultCode == PC_SUCCESS || resultCode == PC_SINGBOTH || resultCode == PC_SINGSIDEA || resultCode == PC_SINGSIDEB) {
|
||||||
VisitPolychord(mesh, startPos, chords, mark, PC_OTHER);
|
VisitPolychord(mesh, startPos, chords, mark, PC_OTHER);
|
||||||
// store a new polychord
|
// store a new polychord
|
||||||
if (!loopsOnly)
|
if (!loopsOnly)
|
||||||
|
@ -968,6 +933,27 @@ public:
|
||||||
else if (!startPos.IsBorder())
|
else if (!startPos.IsBorder())
|
||||||
polychords.push_back(startPos);
|
polychords.push_back(startPos);
|
||||||
} else {
|
} else {
|
||||||
|
if (resultCode == PC_NOTMANIF) {
|
||||||
|
pos = startPos;
|
||||||
|
VisitPolychord(mesh, pos, chords, mark, resultCode);
|
||||||
|
if (pos.IsManifold() && !pos.IsBorder()) {
|
||||||
|
pos.FlipF();
|
||||||
|
VisitPolychord(mesh, pos, chords, mark, resultCode);
|
||||||
|
}
|
||||||
|
} else if (resultCode == PC_NOTQUAD) {
|
||||||
|
// if not quad, visit all the polychords passing through this coord
|
||||||
|
pos = startPos;
|
||||||
|
do {
|
||||||
|
if (!pos.IsBorder()) {
|
||||||
|
pos.FlipF();
|
||||||
|
VisitPolychord(mesh, pos, chords, mark, resultCode);
|
||||||
|
pos.FlipF();
|
||||||
|
}
|
||||||
|
pos.FlipV();
|
||||||
|
pos.FlipE();
|
||||||
|
} while (pos != startPos);
|
||||||
|
VisitPolychord(mesh, startPos, chords, mark, resultCode);
|
||||||
|
}
|
||||||
VisitPolychord(mesh, startPos, chords, mark, resultCode);
|
VisitPolychord(mesh, startPos, chords, mark, resultCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1007,7 +993,7 @@ public:
|
||||||
|
|
||||||
vcg::face::Pos<FaceType> startPos, runPos;
|
vcg::face::Pos<FaceType> startPos, runPos;
|
||||||
PC_ResultCode result = CheckPolychordFindStartPosition(pos, startPos, false);
|
PC_ResultCode result = CheckPolychordFindStartPosition(pos, startPos, false);
|
||||||
if (result != PC_SUCCESS && result != PC_SINGBOTH)
|
if (result != PC_SUCCESS && result != PC_SINGBOTH && result != PC_SINGSIDEA && result != PC_SINGSIDEB)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// since every face has an orientation, ensure that the new polychords are inserted on the right of the starting pos
|
// since every face has an orientation, ensure that the new polychords are inserted on the right of the starting pos
|
||||||
|
@ -1694,6 +1680,13 @@ public:
|
||||||
if (!polyBorderFound && borderSideA && borderSideB)
|
if (!polyBorderFound && borderSideA && borderSideB)
|
||||||
return PC_SINGBOTH;
|
return PC_SINGBOTH;
|
||||||
|
|
||||||
|
// if there are singularities or borders on the side A, remember to keep coordinates on it
|
||||||
|
if (singSideA || borderSideA)
|
||||||
|
return PC_SINGSIDEA;
|
||||||
|
// if there are singularities or borders on the side B, remember to keep coordinates on it
|
||||||
|
if (singSideB || borderSideB)
|
||||||
|
return PC_SINGSIDEB;
|
||||||
|
|
||||||
return PC_SUCCESS;
|
return PC_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue