Sketch: Refactor SketchAnalysis

Refactor detectMissingPointOnPointConstraints()
This commit is contained in:
wmayer
2024-05-28 15:28:53 +02:00
parent 7e5b0d570a
commit ddfc21afc1

View File

@@ -151,10 +151,6 @@ private:
struct PointConstraints
{
explicit PointConstraints(std::vector<VertexIds>& vertexIds)
: vertexIds {vertexIds}
{}
void addGeometry(const Part::Geometry* geo, int index)
{
if (const auto* segm = dynamic_cast<const Part::GeomLineSegment*>(geo)) {
@@ -255,8 +251,136 @@ struct PointConstraints
vertexIds.push_back(id);
}
std::list<ConstraintIds> getMissingCoincidences(std::vector<Sketcher::Constraint*>& allcoincid,
double precision)
{
std::list<ConstraintIds> missingCoincidences; // Holds the list of missing coincidences
// Sort points in geographic order
std::sort(vertexIds.begin(), vertexIds.end(), Vertex_Less(precision));
auto vt = vertexIds.begin();
Vertex_EqualTo pred(precision);
// Comparing existing constraints and find missing ones
while (vt < vertexIds.end()) {
// Seeking for adjacent group of vertices
vt = std::adjacent_find(vt, vertexIds.end(), pred);
if (vt < vertexIds.end()) { // If one found
std::vector<VertexIds>::iterator vn;
// Holds a single group of adjacent vertices
std::set<VertexIds, VertexID_Less> vertexGrp;
// Extract the group of adjacent vertices
vertexGrp.insert(*vt);
for (vn = vt + 1; vn < vertexIds.end(); ++vn) {
if (pred(*vt, *vn)) {
vertexGrp.insert(*vn);
}
else {
break;
}
}
// Holds groups of coincident vertices
std::vector<std::set<VertexIds, VertexID_Less>> coincVertexGrps;
// Decompose the group of adjacent vertices into groups of coincident vertices
// Going through existent coincidences
for (auto& coincidence : allcoincid) {
VertexIds v1;
VertexIds v2;
v1.GeoId = coincidence->First;
v1.PosId = coincidence->FirstPos;
v2.GeoId = coincidence->Second;
v2.PosId = coincidence->SecondPos;
// Look if coincident vertices are in the group of adjacent ones we are
// processing
auto nv1 = vertexGrp.extract(v1);
auto nv2 = vertexGrp.extract(v2);
// Maybe if both empty, they already have been extracted by other coincidences
// We have to check in existing coincident groups and eventually merge
if (nv1.empty() && nv2.empty()) {
std::set<VertexIds, VertexID_Less>* tempGrp = nullptr;
for (auto it = coincVertexGrps.begin(); it < coincVertexGrps.end(); ++it) {
if ((it->find(v1) != it->end()) || (it->find(v2) != it->end())) {
if (!tempGrp) {
tempGrp = &*it;
}
else {
tempGrp->insert(it->begin(), it->end());
coincVertexGrps.erase(it);
break;
}
}
}
continue;
}
// Look if one of the constrained vertices is already in a group of coincident
// vertices
for (std::set<VertexIds, VertexID_Less>& grp : coincVertexGrps) {
if ((grp.find(v1) != grp.end()) || (grp.find(v2) != grp.end())) {
// If yes add them to the existing group
if (!nv1.empty()) {
grp.insert(nv1.value());
}
if (!nv2.empty()) {
grp.insert(nv2.value());
}
continue;
}
}
if (nv1.empty() || nv2.empty()) {
continue;
}
// If no, create a new group of coincident vertices
std::set<VertexIds, VertexID_Less> newGrp;
newGrp.insert(nv1.value());
newGrp.insert(nv2.value());
coincVertexGrps.push_back(newGrp);
}
// If there are remaining vertices in the adjacent group (not in any existing
// constraint) add them as being each a separate coincident group
for (auto& lonept : vertexGrp) {
std::set<VertexIds, VertexID_Less> newGrp;
newGrp.insert(lonept);
coincVertexGrps.push_back(newGrp);
}
// If there is more than 1 coincident group into adjacent group, constraint(s)
// is(are) missing Virtually generate the missing constraint(s)
if (coincVertexGrps.size() > 1) {
std::vector<std::set<VertexIds, VertexID_Less>>::iterator vn;
// Starting from the 2nd coincident group, generate a constraint between
// this group first vertex, and previous group first vertex
for (vn = coincVertexGrps.begin() + 1; vn < coincVertexGrps.end(); ++vn) {
ConstraintIds id;
id.Type = Coincident; // default point on point restriction
id.v = (vn - 1)->begin()->v;
id.First = (vn - 1)->begin()->GeoId;
id.FirstPos = (vn - 1)->begin()->PosId;
id.Second = vn->begin()->GeoId;
id.SecondPos = vn->begin()->PosId;
missingCoincidences.push_back(id);
}
}
vt = vn;
}
}
return missingCoincidences;
}
private:
std::vector<VertexIds>& vertexIds;
// Holds a list of all vertices in the sketch
std::vector<VertexIds> vertexIds;
};
struct EqualityConstraints
@@ -380,8 +504,7 @@ private:
int SketchAnalysis::detectMissingPointOnPointConstraints(double precision,
bool includeconstruction /*=true*/)
{
std::vector<VertexIds> vertexIds; // Holds a list of all vertices in the sketch
PointConstraints pointConstr(vertexIds);
PointConstraints pointConstr;
// Build the list of sketch vertices
const std::vector<Part::Geometry*>& geom = sketch->getInternalGeometry();
@@ -396,13 +519,9 @@ int SketchAnalysis::detectMissingPointOnPointConstraints(double precision,
// TODO take into account single vertices ?
}
// Sort points in geographic order
std::sort(vertexIds.begin(), vertexIds.end(), Vertex_Less(precision));
// Build a list of all coincidence in the sketch
// Build a list of all coincidences in the sketch
std::vector<Sketcher::Constraint*> coincidences = sketch->Constraints.getValues();
for (auto& constraint : sketch->Constraints.getValues()) {
// clang-format off
if (constraint->Type == Sketcher::Coincident ||
@@ -414,122 +533,9 @@ int SketchAnalysis::detectMissingPointOnPointConstraints(double precision,
// TODO optimizing by removing constraints not applying on vertices ?
}
std::list<ConstraintIds> missingCoincidences; // Holds the list of missing coincidences
auto vt = vertexIds.begin();
Vertex_EqualTo pred(precision);
// Comparing existing constraints and find missing ones
while (vt < vertexIds.end()) {
// Seeking for adjacent group of vertices
vt = std::adjacent_find(vt, vertexIds.end(), pred);
if (vt < vertexIds.end()) { // If one found
std::vector<VertexIds>::iterator vn;
// Holds a single group of adjacent vertices
std::set<VertexIds, VertexID_Less> vertexGrp;
// Extract the group of adjacent vertices
vertexGrp.insert(*vt);
for (vn = vt + 1; vn < vertexIds.end(); ++vn) {
if (pred(*vt, *vn)) {
vertexGrp.insert(*vn);
}
else {
break;
}
}
// Holds groups of coincident vertices
std::vector<std::set<VertexIds, VertexID_Less>> coincVertexGrps;
// Decompose the group of adjacent vertices into groups of coincident vertices
// Going through existent coincidences
for (auto& coincidence : coincidences) {
VertexIds v1;
VertexIds v2;
v1.GeoId = coincidence->First;
v1.PosId = coincidence->FirstPos;
v2.GeoId = coincidence->Second;
v2.PosId = coincidence->SecondPos;
// Look if coincident vertices are in the group of adjacent ones we are processing
auto nv1 = vertexGrp.extract(v1);
auto nv2 = vertexGrp.extract(v2);
// Maybe if both empty, they already have been extracted by other coincidences
// We have to check in existing coincident groups and eventually merge
if (nv1.empty() && nv2.empty()) {
std::set<VertexIds, VertexID_Less>* tempGrp = nullptr;
for (auto it = coincVertexGrps.begin(); it < coincVertexGrps.end(); ++it) {
if ((it->find(v1) != it->end()) || (it->find(v2) != it->end())) {
if (!tempGrp) {
tempGrp = &*it;
}
else {
tempGrp->insert(it->begin(), it->end());
coincVertexGrps.erase(it);
break;
}
}
}
continue;
}
// Look if one of the constrained vertices is already in a group of coincident
// vertices
for (std::set<VertexIds, VertexID_Less>& grp : coincVertexGrps) {
if ((grp.find(v1) != grp.end()) || (grp.find(v2) != grp.end())) {
// If yes add them to the existing group
if (!nv1.empty()) {
grp.insert(nv1.value());
}
if (!nv2.empty()) {
grp.insert(nv2.value());
}
continue;
}
}
if (nv1.empty() || nv2.empty()) {
continue;
}
// If no, create a new group of coincident vertices
std::set<VertexIds, VertexID_Less> newGrp;
newGrp.insert(nv1.value());
newGrp.insert(nv2.value());
coincVertexGrps.push_back(newGrp);
}
// If there are remaining vertices in the adjacent group (not in any existing
// constraint) add them as being each a separate coincident group
for (auto& lonept : vertexGrp) {
std::set<VertexIds, VertexID_Less> newGrp;
newGrp.insert(lonept);
coincVertexGrps.push_back(newGrp);
}
// If there is more than 1 coincident group into adjacent group, constraint(s) is(are)
// missing Virtually generate the missing constraint(s)
if (coincVertexGrps.size() > 1) {
std::vector<std::set<VertexIds, VertexID_Less>>::iterator vn;
// Starting from the 2nd coincident group, generate a constraint between
// this group first vertex, and previous group first vertex
for (vn = coincVertexGrps.begin() + 1; vn < coincVertexGrps.end(); ++vn) {
ConstraintIds id;
id.Type = Coincident; // default point on point restriction
id.v = (vn - 1)->begin()->v;
id.First = (vn - 1)->begin()->GeoId;
id.FirstPos = (vn - 1)->begin()->PosId;
id.Second = vn->begin()->GeoId;
id.SecondPos = vn->begin()->PosId;
missingCoincidences.push_back(id);
}
}
vt = vn;
}
}
// Holds the list of missing coincidences
std::list<ConstraintIds> missingCoincidences =
pointConstr.getMissingCoincidences(coincidences, precision);
// Update list of missing constraints stored as member variable of sketch
this->vertexConstraints.clear();