Sketcher: Add line mid-point auto-constraint

This commit is contained in:
PaddleStroke
2024-03-25 16:27:29 +01:00
committed by Chris Hennes
parent f9c9870273
commit 64054d13c4
2 changed files with 63 additions and 41 deletions

View File

@@ -720,6 +720,17 @@ protected:
AutoConstraints.push_back(std::move(c));
}
} break;
case Sketcher::Symmetric: {
auto c = std::make_unique<Sketcher::Constraint>();
c->Type = Sketcher::Symmetric;
c->First = geoId2;
c->FirstPos = Sketcher::PointPos::start;
c->Second = geoId2;
c->SecondPos = Sketcher::PointPos::end;
c->Third = geoId1;
c->ThirdPos = posId1;
AutoConstraints.push_back(std::move(c));
} break;
// In special case of Horizontal/Vertical constraint, geoId2 is normally unused
// and should be 'Constraint::GeoUndef' However it can be used as a way to
// require the function to apply these constraints on another geometry In this

View File

@@ -600,11 +600,9 @@ DrawSketchHandler::suggestedConstraintsPixmaps(std::vector<AutoConstraint>& sugg
{
std::vector<QPixmap> pixmaps;
// Iterate through AutoConstraints types and get their pixmaps
std::vector<AutoConstraint>::iterator it = suggestedConstraints.begin();
int i = 0;
for (; it != suggestedConstraints.end(); ++it, i++) {
for (auto& autoCstr : suggestedConstraints) {
QString iconType;
switch (it->Type) {
switch (autoCstr.Type) {
case Horizontal:
iconType = QString::fromLatin1("Constraint_Horizontal");
break;
@@ -617,6 +615,9 @@ DrawSketchHandler::suggestedConstraintsPixmaps(std::vector<AutoConstraint>& sugg
case PointOnObject:
iconType = QString::fromLatin1("Constraint_PointOnObject");
break;
case Symmetric:
iconType = QString::fromLatin1("Constraint_Symmetric");
break;
case Tangent:
iconType = QString::fromLatin1("Constraint_Tangent");
break;
@@ -644,15 +645,13 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
AutoConstraint::TargetType type)
{
suggestedConstraints.clear();
SketchObject* obj = sketchgui->getSketchObject();
if (!sketchgui->Autoconstraints.getValue()) {
return 0; // If Autoconstraints property is not set quit
}
Base::Vector3d hitShapeDir =
Base::Vector3d(0,
0,
0); // direction of hit shape (if it is a line, the direction of the line)
// direction of hit shape (if it is a line, the direction of the line)
Base::Vector3d hitShapeDir = Base::Vector3d(0, 0, 0);
// Get Preselection
int preSelPnt = getPreselectPoint();
@@ -660,13 +659,13 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
int preSelCrs = getPreselectCross();
int GeoId = GeoEnum::GeoUndef;
Sketcher::PointPos PosId = Sketcher::PointPos::none;
PointPos PosId = PointPos::none;
if (preSelPnt != -1) {
sketchgui->getSketchObject()->getGeoVertexIndex(preSelPnt, GeoId, PosId);
obj->getGeoVertexIndex(preSelPnt, GeoId, PosId);
}
else if (preSelCrv != -1) {
const Part::Geometry* geom = sketchgui->getSketchObject()->getGeometry(preSelCrv);
const Part::Geometry* geom = obj->getGeometry(preSelCrv);
// ensure geom exists in case object was called before preselection is updated
if (geom) {
@@ -679,7 +678,7 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
}
else if (preSelCrs == 0) { // root point
GeoId = Sketcher::GeoEnum::RtPnt;
PosId = Sketcher::PointPos::start;
PosId = PointPos::start;
}
else if (preSelCrs == 1) { // x axis
GeoId = Sketcher::GeoEnum::HAxis;
@@ -696,18 +695,33 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
constr.Type = Sketcher::None;
constr.GeoId = GeoId;
constr.PosId = PosId;
if ((type == AutoConstraint::VERTEX || type == AutoConstraint::VERTEX_NO_TANGENCY)
&& PosId != Sketcher::PointPos::none) {
constr.Type = Sketcher::Coincident;
if (type == AutoConstraint::VERTEX || type == AutoConstraint::VERTEX_NO_TANGENCY) {
if (PosId == PointPos::none) {
bool lineCenter = false;
auto* geo = obj->getGeometry(GeoId);
if (geo->is<Part::GeomLineSegment>()) {
auto* line = static_cast<const Part::GeomLineSegment*>(geo);
Base::Vector2d startPoint = toVector2d(line->getStartPoint());
Base::Vector2d endPoint = toVector2d(line->getEndPoint());
Base::Vector2d midPoint = (startPoint + endPoint) / 2;
// Check if we are at middle of the line
if ((Pos - midPoint).Length() < (endPoint - startPoint).Length() * 0.05) {
lineCenter = true;
}
}
constr.Type = lineCenter ? Sketcher::Symmetric : Sketcher::PointOnObject;
}
else {
constr.Type = Sketcher::Coincident;
}
}
else if (type == AutoConstraint::CURVE && PosId != Sketcher::PointPos::none) {
else if (type == AutoConstraint::CURVE && PosId != PointPos::none) {
constr.Type = Sketcher::PointOnObject;
}
else if ((type == AutoConstraint::VERTEX || type == AutoConstraint::VERTEX_NO_TANGENCY)
&& PosId == Sketcher::PointPos::none) {
constr.Type = Sketcher::PointOnObject;
}
else if (type == AutoConstraint::CURVE && PosId == Sketcher::PointPos::none) {
else if (type == AutoConstraint::CURVE && PosId == PointPos::none) {
constr.Type = Sketcher::Tangent;
}
@@ -750,7 +764,7 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
AutoConstraint constr;
constr.Type = Sketcher::None;
constr.GeoId = GeoEnum::GeoUndef;
constr.PosId = Sketcher::PointPos::none;
constr.PosId = PointPos::none;
double angle = std::abs(atan2(Dir.y, Dir.x));
if (angle < angleDevRad || (M_PI - angle) < angleDevRad) {
// Suggest horizontal constraint
@@ -779,20 +793,18 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
double tangDeviation = 0.1 * sketchgui->getScaleFactor();
// Get geometry list
const std::vector<Part::Geometry*> geomlist =
sketchgui->getSketchObject()->getCompleteGeometry();
const std::vector<Part::Geometry*> geomlist = obj->getCompleteGeometry();
Base::Vector3d tmpPos(Pos.x, Pos.y, 0.f); // Current cursor point
Base::Vector3d tmpDir(Dir.x, Dir.y, 0.f); // Direction of line
Base::Vector3d tmpStart(Pos.x - Dir.x, Pos.y - Dir.y, 0.f); // Start point
// Iterate through geometry
int i = 0;
for (std::vector<Part::Geometry*>::const_iterator it = geomlist.begin(); it != geomlist.end();
++it, i++) {
int i = -1;
for (auto* geo : geomlist) {
i++;
if ((*it)->is<Part::GeomCircle>()) {
const Part::GeomCircle* circle = static_cast<const Part::GeomCircle*>((*it));
if (geo->is<Part::GeomCircle>()) {
auto* circle = static_cast<const Part::GeomCircle*>(geo);
Base::Vector3d center = circle->getCenter();
@@ -813,9 +825,8 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
tangDeviation = projDist;
}
}
else if ((*it)->is<Part::GeomEllipse>()) {
const Part::GeomEllipse* ellipse = static_cast<const Part::GeomEllipse*>((*it));
else if (geo->is<Part::GeomEllipse>()) {
auto* ellipse = static_cast<const Part::GeomEllipse*>(geo);
Base::Vector3d center = ellipse->getCenter();
@@ -832,8 +843,8 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
double distancetoline = norm * (tmpPos - focus1P); // distance focus1 to line
Base::Vector3d focus1PMirrored =
focus1P + 2 * distancetoline * norm; // mirror of focus1 with respect to the line
// mirror of focus1 with respect to the line
Base::Vector3d focus1PMirrored = focus1P + 2 * distancetoline * norm;
double error = fabs((focus1PMirrored - focus2P).Length() - 2 * a);
@@ -842,8 +853,8 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
tangDeviation = error;
}
}
else if ((*it)->is<Part::GeomArcOfCircle>()) {
const Part::GeomArcOfCircle* arc = static_cast<const Part::GeomArcOfCircle*>((*it));
else if (geo->is<Part::GeomArcOfCircle>()) {
auto* arc = static_cast<const Part::GeomArcOfCircle*>(geo);
Base::Vector3d center = arc->getCenter();
double radius = arc->getRadius();
@@ -873,8 +884,8 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
}
}
}
else if ((*it)->is<Part::GeomArcOfEllipse>()) {
const Part::GeomArcOfEllipse* aoe = static_cast<const Part::GeomArcOfEllipse*>((*it));
else if (geo->is<Part::GeomArcOfEllipse>()) {
auto* aoe = static_cast<const Part::GeomArcOfEllipse*>(geo);
Base::Vector3d center = aoe->getCenter();
@@ -934,7 +945,7 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint>& suggested
// Suggest vertical constraint
constr.Type = Tangent;
constr.GeoId = tangId;
constr.PosId = Sketcher::PointPos::none;
constr.PosId = PointPos::none;
suggestedConstraints.push_back(constr);
}