Sketcher: Arc to arc or circle distance constraint
This commit is contained in:
committed by
abdullahtahiriyo
parent
5ae3a5da9d
commit
838802e28d
@@ -3178,7 +3178,7 @@ int Sketch::addDistanceConstraint(int geoId, double* value, bool driving)
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
|
||||
// point to line distance constraint
|
||||
// point to line or circle distance constraint
|
||||
int Sketch::addDistanceConstraint(int geoId1,
|
||||
PointPos pos1,
|
||||
int geoId2,
|
||||
@@ -3245,23 +3245,44 @@ int Sketch::addDistanceConstraint(int geoId1, int geoId2, double* value, bool dr
|
||||
geoId1 = checkGeoId(geoId1);
|
||||
geoId2 = checkGeoId(geoId2);
|
||||
|
||||
if (Geoms[geoId1].type == Circle) {
|
||||
if (Geoms[geoId2].type == Circle) {
|
||||
GCS::Circle& c1 = Circles[Geoms[geoId1].index];
|
||||
GCS::Circle& c2 = Circles[Geoms[geoId2].index];
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintC2CDistance(c1, c2, value, tag, driving);
|
||||
return ConstraintsCounter;
|
||||
GCS::Circle *c1, *c2;
|
||||
if (Geoms[geoId2].type == Line) {
|
||||
if (Geoms[geoId1].type == Circle) {
|
||||
c1 = &Circles[Geoms[geoId1].index];
|
||||
}
|
||||
else if (Geoms[geoId2].type == Line) {
|
||||
GCS::Circle& c = Circles[Geoms[geoId1].index];
|
||||
GCS::Line& l = Lines[Geoms[geoId2].index];
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintC2LDistance(c, l, value, tag, driving);
|
||||
return ConstraintsCounter;
|
||||
else if (Geoms[geoId1].type == Arc) {
|
||||
c1 = &Arcs[Geoms[geoId1].index];
|
||||
}
|
||||
GCS::Line* l = &Lines[Geoms[geoId2].index];
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintC2LDistance(*c1, *l, value, tag, driving);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
else {
|
||||
if ((Geoms[geoId1].type == Circle) && (Geoms[geoId2].type == Circle)) {
|
||||
c1 = &Circles[Geoms[geoId1].index];
|
||||
c2 = &Circles[Geoms[geoId2].index];
|
||||
}
|
||||
else if ((Geoms[geoId1].type == Arc) && (Geoms[geoId2].type == Circle)) {
|
||||
c1 = &Arcs[Geoms[geoId1].index];
|
||||
c2 = &Circles[Geoms[geoId2].index];
|
||||
}
|
||||
else if ((Geoms[geoId1].type == Circle) && (Geoms[geoId2].type == Arc)) {
|
||||
c1 = &Circles[Geoms[geoId1].index];
|
||||
c2 = &Arcs[Geoms[geoId2].index];
|
||||
}
|
||||
else if ((Geoms[geoId1].type == Arc) && (Geoms[geoId2].type == Arc)) {
|
||||
c1 = &Arcs[Geoms[geoId1].index];
|
||||
c2 = &Arcs[Geoms[geoId2].index];
|
||||
}
|
||||
else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int tag = ++ConstraintsCounter;
|
||||
GCSsys.addConstraintC2CDistance(*c1, *c2, value, tag, driving);
|
||||
return ConstraintsCounter;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4363,54 +4363,33 @@ void CmdSketcherConstrainDistance::activated(int iMsg)
|
||||
else if (isEdge(GeoId1, PosId1) && isEdge(GeoId2, PosId2)) {
|
||||
const Part::Geometry* geom1 = Obj->getGeometry(GeoId1);
|
||||
const Part::Geometry* geom2 = Obj->getGeometry(GeoId2);
|
||||
|
||||
if (isCircle(*geom1) && isCircle(*geom2)) {// circle to circle distance
|
||||
double radius1 = 0.0, radius2 = 0.0;
|
||||
Base::Vector3d center1, center2;
|
||||
if (isArcOfCircle(*geom1)) {
|
||||
auto arcSeg1 = static_cast<const Part::GeomArcOfCircle*>(geom1);
|
||||
radius1 = arcSeg1->getRadius();
|
||||
center1 = arcSeg1->getCenter();
|
||||
}
|
||||
if (isArcOfCircle(*geom2))) {
|
||||
auto arcSeg2 = static_cast<const Part::GeomArcOfCircle*>(geom2);
|
||||
radius2 = arcSeg2->getRadius();
|
||||
center2 = arcSeg2->getCenter();
|
||||
}
|
||||
if (isCircle(*geom1)) {
|
||||
auto circleSeg1 = static_cast<const Part::GeomCircle*>(geom1);
|
||||
double radius1 = circleSeg1->getRadius();
|
||||
Base::Vector3d center1 = circleSeg1->getCenter();
|
||||
|
||||
radius1 = circleSeg1->getRadius();
|
||||
center1 = circleSeg1->getCenter();
|
||||
}
|
||||
if (isCircle(*geom2)) {
|
||||
auto circleSeg2 = static_cast<const Part::GeomCircle*>(geom2);
|
||||
double radius2 = circleSeg2->getRadius();
|
||||
Base::Vector3d center2 = circleSeg2->getCenter();
|
||||
|
||||
double ActDist = 0.;
|
||||
|
||||
Base::Vector3d intercenter = center1 - center2;
|
||||
double intercenterdistance = intercenter.Length();
|
||||
|
||||
if (intercenterdistance >= radius1 && intercenterdistance >= radius2) {
|
||||
|
||||
ActDist = intercenterdistance - radius1 - radius2;
|
||||
}
|
||||
else {
|
||||
double bigradius = std::max(radius1, radius2);
|
||||
double smallradius = std::min(radius1, radius2);
|
||||
|
||||
ActDist = bigradius - smallradius - intercenterdistance;
|
||||
}
|
||||
|
||||
openCommand(QT_TRANSLATE_NOOP("Command", "Add circle to circle distance constraint"));
|
||||
Gui::cmdAppObjectArgs(selection[0].getObject(),
|
||||
"addConstraint(Sketcher.Constraint('Distance',%d,%d,%f))",
|
||||
GeoId1,
|
||||
GeoId2,
|
||||
ActDist);
|
||||
|
||||
if (arebothpointsorsegmentsfixed
|
||||
|| constraintCreationMode
|
||||
== Reference) {// it is a constraint on a external line, make it non-driving
|
||||
const std::vector<Sketcher::Constraint*>& ConStr = Obj->Constraints.getValues();
|
||||
|
||||
Gui::cmdAppObjectArgs(selection[0].getObject(),
|
||||
"setDriving(%d,%s)",
|
||||
ConStr.size() - 1,
|
||||
"False");
|
||||
finishDatumConstraint(this, Obj, false);
|
||||
}
|
||||
else {
|
||||
finishDatumConstraint(this, Obj, true);
|
||||
}
|
||||
|
||||
radius2 = circleSeg2->getRadius();
|
||||
center2 = circleSeg2->getCenter();
|
||||
}
|
||||
if (radius1 == 0.0 || radius2 == 0.0) {
|
||||
Gui::TranslatedNotification(
|
||||
Obj,
|
||||
QObject::tr("Wrong selection"),
|
||||
QObject::tr("Cannot add a length constraint on this selection!"));
|
||||
return;
|
||||
}
|
||||
else if ((isCircle(*geom1) && isLineSegment(*geom2))
|
||||
@@ -4458,6 +4437,45 @@ void CmdSketcherConstrainDistance::activated(int iMsg)
|
||||
|
||||
return;
|
||||
}
|
||||
double ActDist = 0.0;
|
||||
|
||||
Base::Vector3d intercenter = center1 - center2;
|
||||
double intercenterdistance = intercenter.Length();
|
||||
|
||||
if (intercenterdistance >= radius1 && intercenterdistance >= radius2) {
|
||||
|
||||
ActDist = intercenterdistance - radius1 - radius2;
|
||||
}
|
||||
else {
|
||||
double bigradius = std::max(radius1, radius2);
|
||||
double smallradius = std::min(radius1, radius2);
|
||||
|
||||
ActDist = bigradius - smallradius - intercenterdistance;
|
||||
}
|
||||
|
||||
openCommand(QT_TRANSLATE_NOOP("Command", "Add circle to circle distance constraint"));
|
||||
Gui::cmdAppObjectArgs(selection[0].getObject(),
|
||||
"addConstraint(Sketcher.Constraint('Distance',%d,%d,%f))",
|
||||
GeoId1,
|
||||
GeoId2,
|
||||
ActDist);
|
||||
|
||||
if (arebothpointsorsegmentsfixed
|
||||
|| constraintCreationMode
|
||||
== Reference) {// it is a constraint on a external line, make it non-driving
|
||||
const std::vector<Sketcher::Constraint*>& ConStr = Obj->Constraints.getValues();
|
||||
|
||||
Gui::cmdAppObjectArgs(selection[0].getObject(),
|
||||
"setDriving(%d,%s)",
|
||||
ConStr.size() - 1,
|
||||
"False");
|
||||
finishDatumConstraint(this, Obj, false);
|
||||
}
|
||||
else {
|
||||
finishDatumConstraint(this, Obj, true);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else if (isEdge(GeoId1, PosId1)) {// line length
|
||||
if (GeoId1 < 0 && GeoId1 >= Sketcher::GeoEnum::VAxis) {
|
||||
|
||||
@@ -704,8 +704,7 @@ Restart:
|
||||
}
|
||||
|
||||
if (geo1->is<Part::GeomEllipse>() || geo1->is<Part::GeomArcOfEllipse>()
|
||||
|| geo1->getTypeId()
|
||||
== Part::GeomArcOfHyperbola::getClassTypeId()) {
|
||||
|| geo1->is<Part::GeomArcOfHyperbola>()) {
|
||||
|
||||
Base::Vector3d majDir, minDir, rvec;
|
||||
majDir = Base::Vector3d(cos(angle1),
|
||||
@@ -837,43 +836,53 @@ Restart:
|
||||
else {
|
||||
const Part::Geometry* geo1 =
|
||||
geolistfacade.getGeometryFromGeoId(Constr->First);
|
||||
if (geo1->is<Part::GeomCircle>()) { // circle to line
|
||||
// distance
|
||||
const Part::GeomCircle* circleSeg =
|
||||
static_cast<const Part::GeomCircle*>(geo1);
|
||||
if (geo1->is<Part::GeomCircle>()) { // circle to line distance
|
||||
auto lineSeg = static_cast<const Part::GeomLineSegment*>(geo);
|
||||
auto circleSeg = static_cast<const Part::GeomCircle*>(geo1);
|
||||
Base::Vector3d ct = circleSeg->getCenter();
|
||||
Base::Vector3d l2p1 = lineSeg->getStartPoint();
|
||||
Base::Vector3d l2p2 = lineSeg->getEndPoint();
|
||||
double radius = circleSeg->getRadius();
|
||||
pnt1.ProjectToLine(
|
||||
ct - l2p1,
|
||||
l2p2 - l2p1); // project on the line translated to origin
|
||||
Base::Vector3d dir = pnt1;
|
||||
// project on the line translated to origin
|
||||
pnt2.ProjectToLine(ct - l2p1, l2p2 - l2p1);
|
||||
Base::Vector3d dir = pnt2;
|
||||
dir.Normalize();
|
||||
pnt1 += ct;
|
||||
pnt2 = ct + dir * radius;
|
||||
pnt1 = ct + dir * radius;
|
||||
pnt2 += ct;
|
||||
Base::Vector3d d = l2p2 - l2p1;
|
||||
double ActDist = std::abs(-ct.x * d.y + ct.y * d.x
|
||||
+ l2p1.x * l2p2.y - l2p2.x * l2p1.y)
|
||||
/ d.Length()
|
||||
- radius;
|
||||
if (ActDist < 0) {
|
||||
std::swap(pnt1, pnt2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (geo->is<Part::GeomCircle>()) {
|
||||
const Part::Geometry* geo1 =
|
||||
geolistfacade.getGeometryFromGeoId(Constr->First);
|
||||
if (geo1->is<Part::GeomCircle>()) { // circle to circle
|
||||
// distance
|
||||
const Part::GeomCircle* circleSeg1 =
|
||||
static_cast<const Part::GeomCircle*>(geo1);
|
||||
auto circleSeg2 = static_cast<const Part::GeomCircle*>(geo);
|
||||
GetCirclesMinimalDistance(circleSeg1, circleSeg2, pnt1, pnt2);
|
||||
}
|
||||
else if (Constr->FirstPos
|
||||
!= Sketcher::PointPos::none) { // point to circle distance
|
||||
auto circleSeg2 = static_cast<const Part::GeomCircle*>(geo);
|
||||
pnt1 = geolistfacade.getPoint(Constr->First, Constr->FirstPos);
|
||||
Base::Vector3d v = pnt1 - circleSeg2->getCenter();
|
||||
v = v.Normalize();
|
||||
pnt2 = circleSeg2->getCenter() + circleSeg2->getRadius() * v;
|
||||
}
|
||||
else if (geo->is<Part::GeomCircle>()) { // circle to circle distance
|
||||
|| geo->is<Part::GeomArcOfCircle>())
|
||||
{
|
||||
if (geo1->is<Part::GeomCircle>()
|
||||
|| geo1->is<Part::GeomArcOfCircle>()) {
|
||||
GetCirclesMinimalDistance(geo1, geo, pnt1, pnt2);
|
||||
}
|
||||
else if (Constr->FirstPos
|
||||
!= Sketcher::PointPos::none) { // point to circle
|
||||
// distance
|
||||
auto circleSeg2 =
|
||||
static_cast<const Part::GeomCircle*>(geo);
|
||||
pnt1 = geolistfacade.getPoint(Constr->First,
|
||||
Constr->FirstPos);
|
||||
Base::Vector3d v = pnt1 - circleSeg2->getCenter();
|
||||
v = v.Normalize();
|
||||
pnt2 =
|
||||
circleSeg2->getCenter() + circleSeg2->getRadius() * v;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (Constr->FirstPos != Sketcher::PointPos::none) {
|
||||
@@ -883,13 +892,13 @@ Restart:
|
||||
const Part::Geometry* geo =
|
||||
geolistfacade.getGeometryFromGeoId(Constr->First);
|
||||
if (geo->is<Part::GeomLineSegment>()) { // segment distance
|
||||
const Part::GeomLineSegment* lineSeg =
|
||||
static_cast<const Part::GeomLineSegment*>(geo);
|
||||
pnt1 = lineSeg->getStartPoint();
|
||||
pnt2 = lineSeg->getEndPoint();
|
||||
const Part::GeomLineSegment* lineSeg =
|
||||
static_cast<const Part::GeomLineSegment*>(geo);
|
||||
pnt1 = lineSeg->getStartPoint();
|
||||
pnt2 = lineSeg->getEndPoint();
|
||||
}
|
||||
else {
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -947,22 +956,22 @@ Restart:
|
||||
int ptGeoId;
|
||||
Sketcher::PointPos ptPosId;
|
||||
do { // dummy loop to use break =) Maybe goto?
|
||||
ptGeoId = Constr->First;
|
||||
ptPosId = Constr->FirstPos;
|
||||
if (ptPosId != Sketcher::PointPos::none) {
|
||||
break;
|
||||
}
|
||||
ptGeoId = Constr->Second;
|
||||
ptPosId = Constr->SecondPos;
|
||||
if (ptPosId != Sketcher::PointPos::none) {
|
||||
break;
|
||||
}
|
||||
ptGeoId = Constr->Third;
|
||||
ptPosId = Constr->ThirdPos;
|
||||
if (ptPosId != Sketcher::PointPos::none) {
|
||||
break;
|
||||
}
|
||||
assert(0); // no point found!
|
||||
ptGeoId = Constr->First;
|
||||
ptPosId = Constr->FirstPos;
|
||||
if (ptPosId != Sketcher::PointPos::none) {
|
||||
break;
|
||||
}
|
||||
ptGeoId = Constr->Second;
|
||||
ptPosId = Constr->SecondPos;
|
||||
if (ptPosId != Sketcher::PointPos::none) {
|
||||
break;
|
||||
}
|
||||
ptGeoId = Constr->Third;
|
||||
ptPosId = Constr->ThirdPos;
|
||||
if (ptPosId != Sketcher::PointPos::none) {
|
||||
break;
|
||||
}
|
||||
assert(0); // no point found!
|
||||
} while (false);
|
||||
|
||||
pos = geolistfacade.getPoint(ptGeoId, ptPosId);
|
||||
@@ -997,143 +1006,150 @@ Restart:
|
||||
|
||||
if (geo1->is<Part::GeomLineSegment>()
|
||||
&& geo2->is<Part::GeomLineSegment>()) {
|
||||
const Part::GeomLineSegment* lineSeg1 =
|
||||
static_cast<const Part::GeomLineSegment*>(geo1);
|
||||
const Part::GeomLineSegment* lineSeg2 =
|
||||
static_cast<const Part::GeomLineSegment*>(geo2);
|
||||
// tangency between two lines
|
||||
Base::Vector3d midpos1 =
|
||||
((lineSeg1->getEndPoint() + lineSeg1->getStartPoint()) / 2);
|
||||
Base::Vector3d midpos2 =
|
||||
((lineSeg2->getEndPoint() + lineSeg2->getStartPoint()) / 2);
|
||||
Base::Vector3d dir1 =
|
||||
(lineSeg1->getEndPoint() - lineSeg1->getStartPoint()).Normalize();
|
||||
Base::Vector3d dir2 =
|
||||
(lineSeg2->getEndPoint() - lineSeg2->getStartPoint()).Normalize();
|
||||
Base::Vector3d norm1 = Base::Vector3d(-dir1.y, dir1.x, 0.f);
|
||||
Base::Vector3d norm2 = Base::Vector3d(-dir2.y, dir2.x, 0.f);
|
||||
const Part::GeomLineSegment* lineSeg1 =
|
||||
static_cast<const Part::GeomLineSegment*>(geo1);
|
||||
const Part::GeomLineSegment* lineSeg2 =
|
||||
static_cast<const Part::GeomLineSegment*>(geo2);
|
||||
// tangency between two lines
|
||||
Base::Vector3d midpos1 =
|
||||
((lineSeg1->getEndPoint() + lineSeg1->getStartPoint()) / 2);
|
||||
Base::Vector3d midpos2 =
|
||||
((lineSeg2->getEndPoint() + lineSeg2->getStartPoint()) / 2);
|
||||
Base::Vector3d dir1 =
|
||||
(lineSeg1->getEndPoint() - lineSeg1->getStartPoint())
|
||||
.Normalize();
|
||||
Base::Vector3d dir2 =
|
||||
(lineSeg2->getEndPoint() - lineSeg2->getStartPoint())
|
||||
.Normalize();
|
||||
Base::Vector3d norm1 = Base::Vector3d(-dir1.y, dir1.x, 0.f);
|
||||
Base::Vector3d norm2 = Base::Vector3d(-dir2.y, dir2.x, 0.f);
|
||||
|
||||
Base::Vector3d relpos1 = seekConstraintPosition(
|
||||
midpos1,
|
||||
norm1,
|
||||
dir1,
|
||||
4.0,
|
||||
editModeScenegraphNodes.constrGroup->getChild(i));
|
||||
Base::Vector3d relpos2 = seekConstraintPosition(
|
||||
midpos2,
|
||||
norm2,
|
||||
dir2,
|
||||
4.0,
|
||||
editModeScenegraphNodes.constrGroup->getChild(i));
|
||||
Base::Vector3d relpos1 = seekConstraintPosition(
|
||||
midpos1,
|
||||
norm1,
|
||||
dir1,
|
||||
4.0,
|
||||
editModeScenegraphNodes.constrGroup->getChild(i));
|
||||
Base::Vector3d relpos2 = seekConstraintPosition(
|
||||
midpos2,
|
||||
norm2,
|
||||
dir2,
|
||||
4.0,
|
||||
editModeScenegraphNodes.constrGroup->getChild(i));
|
||||
|
||||
auto translation = static_cast<SoZoomTranslation*>(sep->getChild(
|
||||
static_cast<int>(ConstraintNodePosition::FirstTranslationIndex)));
|
||||
auto translation =
|
||||
static_cast<SoZoomTranslation*>(sep->getChild(static_cast<int>(
|
||||
ConstraintNodePosition::FirstTranslationIndex)));
|
||||
|
||||
translation->abPos =
|
||||
SbVec3f(midpos1.x, midpos1.y, zConstrH); // Absolute Reference
|
||||
translation->translation = SbVec3f(relpos1.x, relpos1.y, 0);
|
||||
translation->abPos =
|
||||
SbVec3f(midpos1.x, midpos1.y, zConstrH); // Absolute Reference
|
||||
translation->translation = SbVec3f(relpos1.x, relpos1.y, 0);
|
||||
|
||||
Base::Vector3d secondPos = midpos2 - midpos1;
|
||||
Base::Vector3d secondPos = midpos2 - midpos1;
|
||||
|
||||
translation = static_cast<SoZoomTranslation*>(sep->getChild(
|
||||
static_cast<int>(ConstraintNodePosition::SecondTranslationIndex)));
|
||||
translation =
|
||||
static_cast<SoZoomTranslation*>(sep->getChild(static_cast<int>(
|
||||
ConstraintNodePosition::SecondTranslationIndex)));
|
||||
|
||||
translation->abPos =
|
||||
SbVec3f(secondPos.x, secondPos.y, zConstrH); // Absolute Reference
|
||||
translation->translation =
|
||||
SbVec3f(relpos2.x - relpos1.x, relpos2.y - relpos1.y, 0);
|
||||
translation->abPos = SbVec3f(secondPos.x,
|
||||
secondPos.y,
|
||||
zConstrH); // Absolute Reference
|
||||
translation->translation =
|
||||
SbVec3f(relpos2.x - relpos1.x, relpos2.y - relpos1.y, 0);
|
||||
|
||||
break;
|
||||
break;
|
||||
}
|
||||
else if (geo2->is<Part::GeomLineSegment>()) {
|
||||
std::swap(geo1, geo2);
|
||||
std::swap(geo1, geo2);
|
||||
}
|
||||
|
||||
if (geo1->is<Part::GeomLineSegment>()) {
|
||||
const Part::GeomLineSegment* lineSeg =
|
||||
static_cast<const Part::GeomLineSegment*>(geo1);
|
||||
Base::Vector3d dir =
|
||||
(lineSeg->getEndPoint() - lineSeg->getStartPoint()).Normalize();
|
||||
Base::Vector3d norm(-dir.y, dir.x, 0);
|
||||
if (geo2->is<Part::GeomCircle>()) {
|
||||
const Part::GeomCircle* circle =
|
||||
static_cast<const Part::GeomCircle*>(geo2);
|
||||
// tangency between a line and a circle
|
||||
float length =
|
||||
(circle->getCenter() - lineSeg->getStartPoint()) * dir;
|
||||
const Part::GeomLineSegment* lineSeg =
|
||||
static_cast<const Part::GeomLineSegment*>(geo1);
|
||||
Base::Vector3d dir =
|
||||
(lineSeg->getEndPoint() - lineSeg->getStartPoint())
|
||||
.Normalize();
|
||||
Base::Vector3d norm(-dir.y, dir.x, 0);
|
||||
if (geo2->is<Part::GeomCircle>()) {
|
||||
const Part::GeomCircle* circle =
|
||||
static_cast<const Part::GeomCircle*>(geo2);
|
||||
// tangency between a line and a circle
|
||||
float length =
|
||||
(circle->getCenter() - lineSeg->getStartPoint()) * dir;
|
||||
|
||||
pos = lineSeg->getStartPoint() + dir * length;
|
||||
relPos = norm * 1; // TODO Huh?
|
||||
}
|
||||
else if (geo2->is<Part::GeomEllipse>()
|
||||
|| geo2->is<Part::GeomArcOfEllipse>()) {
|
||||
pos = lineSeg->getStartPoint() + dir * length;
|
||||
relPos = norm * 1; // TODO Huh?
|
||||
}
|
||||
else if (geo2->is<Part::GeomEllipse>()
|
||||
|| geo2->is<Part::GeomArcOfEllipse>()) {
|
||||
|
||||
Base::Vector3d center;
|
||||
if (geo2->is<Part::GeomEllipse>()) {
|
||||
const Part::GeomEllipse* ellipse =
|
||||
static_cast<const Part::GeomEllipse*>(geo2);
|
||||
center = ellipse->getCenter();
|
||||
}
|
||||
else {
|
||||
const Part::GeomArcOfEllipse* aoc =
|
||||
static_cast<const Part::GeomArcOfEllipse*>(geo2);
|
||||
center = aoc->getCenter();
|
||||
}
|
||||
Base::Vector3d center;
|
||||
if (geo2->is<Part::GeomEllipse>()) {
|
||||
const Part::GeomEllipse* ellipse =
|
||||
static_cast<const Part::GeomEllipse*>(geo2);
|
||||
center = ellipse->getCenter();
|
||||
}
|
||||
else {
|
||||
const Part::GeomArcOfEllipse* aoc =
|
||||
static_cast<const Part::GeomArcOfEllipse*>(geo2);
|
||||
center = aoc->getCenter();
|
||||
}
|
||||
|
||||
// tangency between a line and an ellipse
|
||||
float length = (center - lineSeg->getStartPoint()) * dir;
|
||||
// tangency between a line and an ellipse
|
||||
float length = (center - lineSeg->getStartPoint()) * dir;
|
||||
|
||||
pos = lineSeg->getStartPoint() + dir * length;
|
||||
relPos = norm * 1;
|
||||
}
|
||||
else if (geo2->is<Part::GeomArcOfCircle>()) {
|
||||
const Part::GeomArcOfCircle* arc =
|
||||
static_cast<const Part::GeomArcOfCircle*>(geo2);
|
||||
// tangency between a line and an arc
|
||||
float length = (arc->getCenter() - lineSeg->getStartPoint()) * dir;
|
||||
pos = lineSeg->getStartPoint() + dir * length;
|
||||
relPos = norm * 1;
|
||||
}
|
||||
else if (geo2->is<Part::GeomArcOfCircle>()) {
|
||||
const Part::GeomArcOfCircle* arc =
|
||||
static_cast<const Part::GeomArcOfCircle*>(geo2);
|
||||
// tangency between a line and an arc
|
||||
float length =
|
||||
(arc->getCenter() - lineSeg->getStartPoint()) * dir;
|
||||
|
||||
pos = lineSeg->getStartPoint() + dir * length;
|
||||
relPos = norm * 1; // TODO Huh?
|
||||
}
|
||||
pos = lineSeg->getStartPoint() + dir * length;
|
||||
relPos = norm * 1; // TODO Huh?
|
||||
}
|
||||
}
|
||||
|
||||
if (geo1->is<Part::GeomCircle>() && geo2->is<Part::GeomCircle>()) {
|
||||
const Part::GeomCircle* circle1 =
|
||||
static_cast<const Part::GeomCircle*>(geo1);
|
||||
const Part::GeomCircle* circle2 =
|
||||
static_cast<const Part::GeomCircle*>(geo2);
|
||||
// tangency between two circles
|
||||
Base::Vector3d dir =
|
||||
(circle2->getCenter() - circle1->getCenter()).Normalize();
|
||||
pos = circle1->getCenter() + dir * circle1->getRadius();
|
||||
relPos = dir * 1;
|
||||
const Part::GeomCircle* circle1 =
|
||||
static_cast<const Part::GeomCircle*>(geo1);
|
||||
const Part::GeomCircle* circle2 =
|
||||
static_cast<const Part::GeomCircle*>(geo2);
|
||||
// tangency between two circles
|
||||
Base::Vector3d dir =
|
||||
(circle2->getCenter() - circle1->getCenter()).Normalize();
|
||||
pos = circle1->getCenter() + dir * circle1->getRadius();
|
||||
relPos = dir * 1;
|
||||
}
|
||||
else if (geo2->is<Part::GeomCircle>()) {
|
||||
std::swap(geo1, geo2);
|
||||
std::swap(geo1, geo2);
|
||||
}
|
||||
|
||||
if (geo1->is<Part::GeomCircle>() && geo2->is<Part::GeomArcOfCircle>()) {
|
||||
const Part::GeomCircle* circle =
|
||||
static_cast<const Part::GeomCircle*>(geo1);
|
||||
const Part::GeomArcOfCircle* arc =
|
||||
static_cast<const Part::GeomArcOfCircle*>(geo2);
|
||||
// tangency between a circle and an arc
|
||||
Base::Vector3d dir =
|
||||
(arc->getCenter() - circle->getCenter()).Normalize();
|
||||
pos = circle->getCenter() + dir * circle->getRadius();
|
||||
relPos = dir * 1;
|
||||
const Part::GeomCircle* circle =
|
||||
static_cast<const Part::GeomCircle*>(geo1);
|
||||
const Part::GeomArcOfCircle* arc =
|
||||
static_cast<const Part::GeomArcOfCircle*>(geo2);
|
||||
// tangency between a circle and an arc
|
||||
Base::Vector3d dir =
|
||||
(arc->getCenter() - circle->getCenter()).Normalize();
|
||||
pos = circle->getCenter() + dir * circle->getRadius();
|
||||
relPos = dir * 1;
|
||||
}
|
||||
else if (geo1->is<Part::GeomArcOfCircle>()
|
||||
&& geo2->is<Part::GeomArcOfCircle>()) {
|
||||
const Part::GeomArcOfCircle* arc1 =
|
||||
static_cast<const Part::GeomArcOfCircle*>(geo1);
|
||||
const Part::GeomArcOfCircle* arc2 =
|
||||
static_cast<const Part::GeomArcOfCircle*>(geo2);
|
||||
// tangency between two arcs
|
||||
Base::Vector3d dir =
|
||||
(arc2->getCenter() - arc1->getCenter()).Normalize();
|
||||
pos = arc1->getCenter() + dir * arc1->getRadius();
|
||||
relPos = dir * 1;
|
||||
const Part::GeomArcOfCircle* arc1 =
|
||||
static_cast<const Part::GeomArcOfCircle*>(geo1);
|
||||
const Part::GeomArcOfCircle* arc2 =
|
||||
static_cast<const Part::GeomArcOfCircle*>(geo2);
|
||||
// tangency between two arcs
|
||||
Base::Vector3d dir =
|
||||
(arc2->getCenter() - arc1->getCenter()).Normalize();
|
||||
pos = arc1->getCenter() + dir * arc1->getRadius();
|
||||
relPos = dir * 1;
|
||||
}
|
||||
auto translation = static_cast<SoZoomTranslation*>(sep->getChild(
|
||||
static_cast<int>(ConstraintNodePosition::FirstTranslationIndex)));
|
||||
@@ -1185,124 +1201,127 @@ Restart:
|
||||
if (Constr->Second != GeoEnum::GeoUndef) {
|
||||
Base::Vector3d dir1, dir2;
|
||||
if (Constr->Third == GeoEnum::GeoUndef) { // angle between two lines
|
||||
const Part::Geometry* geo1 =
|
||||
geolistfacade.getGeometryFromGeoId(Constr->First);
|
||||
const Part::Geometry* geo2 =
|
||||
geolistfacade.getGeometryFromGeoId(Constr->Second);
|
||||
if (!isLineSegment(*geo1) || !isLineSegment(*geo2)) {
|
||||
break;
|
||||
}
|
||||
auto* line1 = static_cast<const Part::GeomLineSegment*>(geo1);
|
||||
auto* line2 = static_cast<const Part::GeomLineSegment*>(geo2);
|
||||
const Part::Geometry* geo1 =
|
||||
geolistfacade.getGeometryFromGeoId(Constr->First);
|
||||
const Part::Geometry* geo2 =
|
||||
geolistfacade.getGeometryFromGeoId(Constr->Second);
|
||||
if (!isLineSegment(*geo1) || !isLineSegment(*geo2)) {
|
||||
break;
|
||||
}
|
||||
auto* line1 = static_cast<const Part::GeomLineSegment*>(geo1);
|
||||
auto* line2 = static_cast<const Part::GeomLineSegment*>(geo2);
|
||||
|
||||
bool flip1 = (Constr->FirstPos == PointPos::end);
|
||||
bool flip2 = (Constr->SecondPos == PointPos::end);
|
||||
dir1 = (flip1 ? -1. : 1.)
|
||||
* (line1->getEndPoint() - line1->getStartPoint()).Normalize();
|
||||
dir2 = (flip2 ? -1. : 1.)
|
||||
* (line2->getEndPoint() - line2->getStartPoint()).Normalize();
|
||||
Base::Vector3d pnt1 =
|
||||
flip1 ? line1->getEndPoint() : line1->getStartPoint();
|
||||
Base::Vector3d pnt2 =
|
||||
flip2 ? line2->getEndPoint() : line2->getStartPoint();
|
||||
Base::Vector3d pnt12 =
|
||||
flip1 ? line1->getStartPoint() : line1->getEndPoint();
|
||||
Base::Vector3d pnt22 =
|
||||
flip2 ? line2->getStartPoint() : line2->getEndPoint();
|
||||
bool flip1 = (Constr->FirstPos == PointPos::end);
|
||||
bool flip2 = (Constr->SecondPos == PointPos::end);
|
||||
dir1 = (flip1 ? -1. : 1.)
|
||||
* (line1->getEndPoint() - line1->getStartPoint()).Normalize();
|
||||
dir2 = (flip2 ? -1. : 1.)
|
||||
* (line2->getEndPoint() - line2->getStartPoint()).Normalize();
|
||||
Base::Vector3d pnt1 =
|
||||
flip1 ? line1->getEndPoint() : line1->getStartPoint();
|
||||
Base::Vector3d pnt2 =
|
||||
flip2 ? line2->getEndPoint() : line2->getStartPoint();
|
||||
Base::Vector3d pnt12 =
|
||||
flip1 ? line1->getStartPoint() : line1->getEndPoint();
|
||||
Base::Vector3d pnt22 =
|
||||
flip2 ? line2->getStartPoint() : line2->getEndPoint();
|
||||
|
||||
// line-line intersection
|
||||
Base::Vector3d intersection;
|
||||
{
|
||||
double det = dir1.x * dir2.y - dir1.y * dir2.x;
|
||||
if ((det > 0 ? det : -det) < 1e-10) {
|
||||
// lines are coincident (or parallel) and in this case the
|
||||
// center of the point pairs with the shortest distance is used
|
||||
Base::Vector3d p1[2], p2[2];
|
||||
p1[0] = line1->getStartPoint();
|
||||
p1[1] = line1->getEndPoint();
|
||||
p2[0] = line2->getStartPoint();
|
||||
p2[1] = line2->getEndPoint();
|
||||
double length = DBL_MAX;
|
||||
for (int i = 0; i <= 1; i++) {
|
||||
for (int j = 0; j <= 1; j++) {
|
||||
double tmp = (p2[j] - p1[i]).Length();
|
||||
if (tmp < length) {
|
||||
length = tmp;
|
||||
double x = (p2[j].x + p1[i].x) / 2;
|
||||
double y = (p2[j].y + p1[i].y) / 2;
|
||||
intersection = Base::Vector3d(x, y, 0.);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
double c1 = dir1.y * pnt1.x - dir1.x * pnt1.y;
|
||||
double c2 = dir2.y * pnt2.x - dir2.x * pnt2.y;
|
||||
double x = (dir1.x * c2 - dir2.x * c1) / det;
|
||||
double y = (dir1.y * c2 - dir2.y * c1) / det;
|
||||
intersection = Base::Vector3d(x, y, 0.);
|
||||
}
|
||||
}
|
||||
p0.setValue(intersection.x, intersection.y, 0.);
|
||||
// line-line intersection
|
||||
Base::Vector3d intersection;
|
||||
{
|
||||
double det = dir1.x * dir2.y - dir1.y * dir2.x;
|
||||
if ((det > 0 ? det : -det) < 1e-10) {
|
||||
// lines are coincident (or parallel) and in this case the
|
||||
// center of the point pairs with the shortest distance is
|
||||
// used
|
||||
Base::Vector3d p1[2], p2[2];
|
||||
p1[0] = line1->getStartPoint();
|
||||
p1[1] = line1->getEndPoint();
|
||||
p2[0] = line2->getStartPoint();
|
||||
p2[1] = line2->getEndPoint();
|
||||
double length = DBL_MAX;
|
||||
for (int i = 0; i <= 1; i++) {
|
||||
for (int j = 0; j <= 1; j++) {
|
||||
double tmp = (p2[j] - p1[i]).Length();
|
||||
if (tmp < length) {
|
||||
length = tmp;
|
||||
double x = (p2[j].x + p1[i].x) / 2;
|
||||
double y = (p2[j].y + p1[i].y) / 2;
|
||||
intersection = Base::Vector3d(x, y, 0.);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
double c1 = dir1.y * pnt1.x - dir1.x * pnt1.y;
|
||||
double c2 = dir2.y * pnt2.x - dir2.x * pnt2.y;
|
||||
double x = (dir1.x * c2 - dir2.x * c1) / det;
|
||||
double y = (dir1.y * c2 - dir2.y * c1) / det;
|
||||
intersection = Base::Vector3d(x, y, 0.);
|
||||
}
|
||||
}
|
||||
p0.setValue(intersection.x, intersection.y, 0.);
|
||||
|
||||
range = Constr->getValue(); // WYSIWYG
|
||||
startangle = atan2(dir1.y, dir1.x);
|
||||
Base::Vector3d vl1 = dir1 * 2 * distance - (pnt1 - intersection);
|
||||
Base::Vector3d vl2 = dir2 * 2 * distance - (pnt2 - intersection);
|
||||
Base::Vector3d vl12 = dir1 * 2 * distance - (pnt12 - intersection);
|
||||
Base::Vector3d vl22 = dir2 * 2 * distance - (pnt22 - intersection);
|
||||
range = Constr->getValue(); // WYSIWYG
|
||||
startangle = atan2(dir1.y, dir1.x);
|
||||
Base::Vector3d vl1 = dir1 * 2 * distance - (pnt1 - intersection);
|
||||
Base::Vector3d vl2 = dir2 * 2 * distance - (pnt2 - intersection);
|
||||
Base::Vector3d vl12 = dir1 * 2 * distance - (pnt12 - intersection);
|
||||
Base::Vector3d vl22 = dir2 * 2 * distance - (pnt22 - intersection);
|
||||
|
||||
endLineLength1 = vl12.Dot(dir1) > 0 ? vl12.Length()
|
||||
: vl1.Dot(dir1) < 0 ? -vl1.Length()
|
||||
: 0.0;
|
||||
endLineLength2 = vl22.Dot(dir2) > 0 ? vl22.Length()
|
||||
: vl2.Dot(dir2) < 0 ? -vl2.Length()
|
||||
: 0.0;
|
||||
endLineLength1 = vl12.Dot(dir1) > 0 ? vl12.Length()
|
||||
: vl1.Dot(dir1) < 0 ? -vl1.Length()
|
||||
: 0.0;
|
||||
endLineLength2 = vl22.Dot(dir2) > 0 ? vl22.Length()
|
||||
: vl2.Dot(dir2) < 0 ? -vl2.Length()
|
||||
: 0.0;
|
||||
}
|
||||
else { // angle-via-point
|
||||
Base::Vector3d p =
|
||||
geolistfacade.getPoint(Constr->Third, Constr->ThirdPos);
|
||||
p0 = SbVec3f(p.x, p.y, 0);
|
||||
dir1 = getNormal(geolistfacade, Constr->First, p);
|
||||
// TODO: Check
|
||||
// dir1 = getSolvedSketch().calculateNormalAtPoint(Constr->First, p.x,
|
||||
// p.y);
|
||||
dir1.RotateZ(-M_PI / 2); // convert to vector of tangency by rotating
|
||||
dir2 = getNormal(geolistfacade, Constr->Second, p);
|
||||
// TODO: Check
|
||||
// dir2 = getSolvedSketch().calculateNormalAtPoint(Constr->Second, p.x,
|
||||
// p.y);
|
||||
dir2.RotateZ(-M_PI / 2);
|
||||
Base::Vector3d p =
|
||||
geolistfacade.getPoint(Constr->Third, Constr->ThirdPos);
|
||||
p0 = SbVec3f(p.x, p.y, 0);
|
||||
dir1 = getNormal(geolistfacade, Constr->First, p);
|
||||
// TODO: Check
|
||||
// dir1 = getSolvedSketch().calculateNormalAtPoint(Constr->First,
|
||||
// p.x, p.y);
|
||||
dir1.RotateZ(-M_PI
|
||||
/ 2); // convert to vector of tangency by rotating
|
||||
dir2 = getNormal(geolistfacade, Constr->Second, p);
|
||||
// TODO: Check
|
||||
// dir2 = getSolvedSketch().calculateNormalAtPoint(Constr->Second,
|
||||
// p.x, p.y);
|
||||
dir2.RotateZ(-M_PI / 2);
|
||||
|
||||
startangle = atan2(dir1.y, dir1.x);
|
||||
range = atan2(dir1.x * dir2.y - dir1.y * dir2.x,
|
||||
dir1.x * dir2.x + dir1.y * dir2.y);
|
||||
startangle = atan2(dir1.y, dir1.x);
|
||||
range = atan2(dir1.x * dir2.y - dir1.y * dir2.x,
|
||||
dir1.x * dir2.x + dir1.y * dir2.y);
|
||||
}
|
||||
}
|
||||
else if (Constr->First != GeoEnum::GeoUndef) {
|
||||
const Part::Geometry* geo =
|
||||
geolistfacade.getGeometryFromGeoId(Constr->First);
|
||||
if (geo->is<Part::GeomLineSegment>()) {
|
||||
const Part::GeomLineSegment* lineSeg =
|
||||
static_cast<const Part::GeomLineSegment*>(geo);
|
||||
p0 = Base::convertTo<SbVec3f>(
|
||||
(lineSeg->getEndPoint() + lineSeg->getStartPoint()) / 2);
|
||||
const Part::GeomLineSegment* lineSeg =
|
||||
static_cast<const Part::GeomLineSegment*>(geo);
|
||||
p0 = Base::convertTo<SbVec3f>(
|
||||
(lineSeg->getEndPoint() + lineSeg->getStartPoint()) / 2);
|
||||
|
||||
Base::Vector3d dir = lineSeg->getEndPoint() - lineSeg->getStartPoint();
|
||||
startangle = 0.;
|
||||
range = atan2(dir.y, dir.x);
|
||||
Base::Vector3d dir =
|
||||
lineSeg->getEndPoint() - lineSeg->getStartPoint();
|
||||
startangle = 0.;
|
||||
range = atan2(dir.y, dir.x);
|
||||
}
|
||||
else if (geo->is<Part::GeomArcOfCircle>()) {
|
||||
const Part::GeomArcOfCircle* arc =
|
||||
static_cast<const Part::GeomArcOfCircle*>(geo);
|
||||
p0 = Base::convertTo<SbVec3f>(arc->getCenter());
|
||||
const Part::GeomArcOfCircle* arc =
|
||||
static_cast<const Part::GeomArcOfCircle*>(geo);
|
||||
p0 = Base::convertTo<SbVec3f>(arc->getCenter());
|
||||
|
||||
double endangle;
|
||||
arc->getRange(startangle, endangle, /*emulateCCWXY=*/true);
|
||||
range = endangle - startangle;
|
||||
double endangle;
|
||||
arc->getRange(startangle, endangle, /*emulateCCWXY=*/true);
|
||||
range = endangle - startangle;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1340,45 +1359,49 @@ Restart:
|
||||
geolistfacade.getGeometryFromGeoId(Constr->First);
|
||||
|
||||
if (geo->is<Part::GeomArcOfCircle>()) {
|
||||
auto* arc = static_cast<const Part::GeomArcOfCircle*>(geo);
|
||||
double radius = arc->getRadius();
|
||||
double angle = (double)Constr->LabelPosition;
|
||||
double startAngle, endAngle;
|
||||
arc->getRange(startAngle, endAngle, /*emulateCCW=*/true);
|
||||
if (angle == 10) {
|
||||
angle = (startAngle + endAngle) / 2;
|
||||
}
|
||||
if (!(angle > startAngle && angle < endAngle)) {
|
||||
if (angle < startAngle
|
||||
&& startAngle - angle < angle + 2 * M_PI - endAngle) {
|
||||
helperStartAngle = angle;
|
||||
helperRange = startAngle - angle;
|
||||
}
|
||||
else {
|
||||
if (angle < endAngle) {
|
||||
angle += 2 * M_PI;
|
||||
}
|
||||
helperStartAngle = endAngle;
|
||||
helperRange = angle - endAngle;
|
||||
}
|
||||
}
|
||||
Base::Vector3d center = arc->getCenter();
|
||||
pnt1 = center - radius * Base::Vector3d(cos(angle), sin(angle), 0.);
|
||||
pnt2 = center + radius * Base::Vector3d(cos(angle), sin(angle), 0.);
|
||||
auto* arc = static_cast<const Part::GeomArcOfCircle*>(geo);
|
||||
double radius = arc->getRadius();
|
||||
double angle = (double)Constr->LabelPosition;
|
||||
double startAngle, endAngle;
|
||||
arc->getRange(startAngle, endAngle, /*emulateCCW=*/true);
|
||||
if (angle == 10) {
|
||||
angle = (startAngle + endAngle) / 2;
|
||||
}
|
||||
if (!(angle > startAngle && angle < endAngle)) {
|
||||
if (angle < startAngle
|
||||
&& startAngle - angle < angle + 2 * M_PI - endAngle) {
|
||||
helperStartAngle = angle;
|
||||
helperRange = startAngle - angle;
|
||||
}
|
||||
else {
|
||||
if (angle < endAngle) {
|
||||
angle += 2 * M_PI;
|
||||
}
|
||||
helperStartAngle = endAngle;
|
||||
helperRange = angle - endAngle;
|
||||
}
|
||||
}
|
||||
Base::Vector3d center = arc->getCenter();
|
||||
pnt1 =
|
||||
center - radius * Base::Vector3d(cos(angle), sin(angle), 0.);
|
||||
pnt2 =
|
||||
center + radius * Base::Vector3d(cos(angle), sin(angle), 0.);
|
||||
}
|
||||
else if (geo->is<Part::GeomCircle>()) {
|
||||
auto* circle = static_cast<const Part::GeomCircle*>(geo);
|
||||
double radius = circle->getRadius();
|
||||
double angle = (double)Constr->LabelPosition;
|
||||
if (angle == 10) {
|
||||
angle = 0;
|
||||
}
|
||||
Base::Vector3d center = circle->getCenter();
|
||||
pnt1 = center - radius * Base::Vector3d(cos(angle), sin(angle), 0.);
|
||||
pnt2 = center + radius * Base::Vector3d(cos(angle), sin(angle), 0.);
|
||||
auto* circle = static_cast<const Part::GeomCircle*>(geo);
|
||||
double radius = circle->getRadius();
|
||||
double angle = (double)Constr->LabelPosition;
|
||||
if (angle == 10) {
|
||||
angle = 0;
|
||||
}
|
||||
Base::Vector3d center = circle->getCenter();
|
||||
pnt1 =
|
||||
center - radius * Base::Vector3d(cos(angle), sin(angle), 0.);
|
||||
pnt2 =
|
||||
center + radius * Base::Vector3d(cos(angle), sin(angle), 0.);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1422,48 +1445,48 @@ Restart:
|
||||
geolistfacade.getGeometryFromGeoId(Constr->First);
|
||||
|
||||
if (geo->is<Part::GeomArcOfCircle>()) {
|
||||
auto* arc = static_cast<const Part::GeomArcOfCircle*>(geo);
|
||||
double radius = arc->getRadius();
|
||||
double angle = (double)Constr->LabelPosition;
|
||||
double startAngle, endAngle;
|
||||
arc->getRange(startAngle, endAngle, /*emulateCCW=*/true);
|
||||
if (angle == 10) {
|
||||
angle = (startAngle + endAngle) / 2;
|
||||
}
|
||||
if (!(angle > startAngle && angle < endAngle)) {
|
||||
if (angle < startAngle
|
||||
&& startAngle - angle < angle + 2 * M_PI - endAngle) {
|
||||
helperStartAngle = angle;
|
||||
helperRange = startAngle - angle;
|
||||
}
|
||||
else {
|
||||
if (angle < endAngle) {
|
||||
angle += 2 * M_PI;
|
||||
}
|
||||
helperStartAngle = endAngle;
|
||||
helperRange = angle - endAngle;
|
||||
}
|
||||
}
|
||||
pnt1 = arc->getCenter();
|
||||
pnt2 = pnt1 + radius * Base::Vector3d(cos(angle), sin(angle), 0.);
|
||||
auto* arc = static_cast<const Part::GeomArcOfCircle*>(geo);
|
||||
double radius = arc->getRadius();
|
||||
double angle = (double)Constr->LabelPosition;
|
||||
double startAngle, endAngle;
|
||||
arc->getRange(startAngle, endAngle, /*emulateCCW=*/true);
|
||||
if (angle == 10) {
|
||||
angle = (startAngle + endAngle) / 2;
|
||||
}
|
||||
if (!(angle > startAngle && angle < endAngle)) {
|
||||
if (angle < startAngle
|
||||
&& startAngle - angle < angle + 2 * M_PI - endAngle) {
|
||||
helperStartAngle = angle;
|
||||
helperRange = startAngle - angle;
|
||||
}
|
||||
else {
|
||||
if (angle < endAngle) {
|
||||
angle += 2 * M_PI;
|
||||
}
|
||||
helperStartAngle = endAngle;
|
||||
helperRange = angle - endAngle;
|
||||
}
|
||||
}
|
||||
pnt1 = arc->getCenter();
|
||||
pnt2 = pnt1 + radius * Base::Vector3d(cos(angle), sin(angle), 0.);
|
||||
}
|
||||
else if (geo->is<Part::GeomCircle>()) {
|
||||
auto* circle = static_cast<const Part::GeomCircle*>(geo);
|
||||
auto gf = GeometryFacade::getFacade(geo);
|
||||
auto* circle = static_cast<const Part::GeomCircle*>(geo);
|
||||
auto gf = GeometryFacade::getFacade(geo);
|
||||
|
||||
double radius;
|
||||
double radius;
|
||||
|
||||
radius = circle->getRadius();
|
||||
radius = circle->getRadius();
|
||||
|
||||
double angle = (double)Constr->LabelPosition;
|
||||
if (angle == 10) {
|
||||
angle = 0;
|
||||
}
|
||||
pnt1 = circle->getCenter();
|
||||
pnt2 = pnt1 + radius * Base::Vector3d(cos(angle), sin(angle), 0.);
|
||||
double angle = (double)Constr->LabelPosition;
|
||||
if (angle == 10) {
|
||||
angle = 0;
|
||||
}
|
||||
pnt1 = circle->getCenter();
|
||||
pnt2 = pnt1 + radius * Base::Vector3d(cos(angle), sin(angle), 0.);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -2120,18 +2143,18 @@ std::set<int> EditModeConstraintCoinManager::detectPreselectionConstr(const SoPi
|
||||
if (tail
|
||||
!= sep->getChild(
|
||||
static_cast<int>(ConstraintNodePosition::FirstIconIndex))) {
|
||||
Base::Console().Log("SecondIcon\n");
|
||||
Base::Console().Log("SecondIcon\n");
|
||||
|
||||
auto translation2 = static_cast<SoZoomTranslation*>(
|
||||
static_cast<SoSeparator*>(tailFather)
|
||||
->getChild(static_cast<int>(
|
||||
ConstraintNodePosition::SecondTranslationIndex)));
|
||||
auto translation2 = static_cast<SoZoomTranslation*>(
|
||||
static_cast<SoSeparator*>(tailFather)
|
||||
->getChild(static_cast<int>(
|
||||
ConstraintNodePosition::SecondTranslationIndex)));
|
||||
|
||||
absPos += translation2->abPos.getValue();
|
||||
absPos += translation2->abPos.getValue();
|
||||
|
||||
trans += translation2->translation.getValue();
|
||||
trans += translation2->translation.getValue();
|
||||
|
||||
scaleFactor = translation2->getScaleFactor();
|
||||
scaleFactor = translation2->getScaleFactor();
|
||||
}
|
||||
|
||||
// Only the translation is scaled because this is how SoZoomTranslation
|
||||
@@ -2158,31 +2181,32 @@ std::set<int> EditModeConstraintCoinManager::detectPreselectionConstr(const SoPi
|
||||
++b) {
|
||||
|
||||
#ifdef FC_DEBUG
|
||||
// Useful code to debug coordinates and bounding boxes that does not
|
||||
// need to be compiled in for any debug operations.
|
||||
// Useful code to debug coordinates and bounding boxes that does
|
||||
// not need to be compiled in for any debug operations.
|
||||
|
||||
/*Base::Console().Log("Abs(%f,%f),Trans(%f,%f),Coords(%d,%d),iCoords(%f,%f),icon(%d,%d),isize(%d,%d),boundingbox([%d,%d],[%d,%d])\n",
|
||||
* absPos[0],absPos[1],trans[0], trans[1], cursorPos[0], cursorPos[1],
|
||||
* iconCoords[0], iconCoords[1], iconX, iconY, iconSize[0], iconSize[1],
|
||||
* b->first.topLeft().x(),b->first.topLeft().y(),b->first.bottomRight().x(),b->first.bottomRight().y());*/
|
||||
/*Base::Console().Log("Abs(%f,%f),Trans(%f,%f),Coords(%d,%d),iCoords(%f,%f),icon(%d,%d),isize(%d,%d),boundingbox([%d,%d],[%d,%d])\n",
|
||||
* absPos[0],absPos[1],trans[0], trans[1], cursorPos[0],
|
||||
* cursorPos[1], iconCoords[0], iconCoords[1], iconX, iconY,
|
||||
* iconSize[0], iconSize[1],
|
||||
* b->first.topLeft().x(),b->first.topLeft().y(),b->first.bottomRight().x(),b->first.bottomRight().y());*/
|
||||
#endif
|
||||
|
||||
if (b->first.contains(iconX, iconY)) {
|
||||
// We've found a bounding box that contains the mouse pointer!
|
||||
for (std::set<int>::iterator k = b->second.begin();
|
||||
k != b->second.end();
|
||||
++k) {
|
||||
constrIndices.insert(*k);
|
||||
}
|
||||
}
|
||||
if (b->first.contains(iconX, iconY)) {
|
||||
// We've found a bounding box that contains the mouse pointer!
|
||||
for (std::set<int>::iterator k = b->second.begin();
|
||||
k != b->second.end();
|
||||
++k) {
|
||||
constrIndices.insert(*k);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// It's a constraint icon, not a combined one
|
||||
QStringList constrIdStrings = constrIdsStr.split(QString::fromLatin1(","));
|
||||
while (!constrIdStrings.empty()) {
|
||||
auto constraintid = constrIdStrings.takeAt(0).toInt();
|
||||
constrIndices.insert(constraintid);
|
||||
auto constraintid = constrIdStrings.takeAt(0).toInt();
|
||||
constrIndices.insert(constraintid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2412,24 +2436,24 @@ void EditModeConstraintCoinManager::combineConstraintIcons(IconQueue iconQueue)
|
||||
+ pow(i->position[1] - j->position[1], 2);
|
||||
if (distSquared <= maxDistSquared
|
||||
&& (*i).type != QString::fromLatin1("Constraint_Symmetric")) {
|
||||
// Found an icon in iconQueue that's close enough to
|
||||
// a member of thisGroup, so move it into thisGroup
|
||||
thisGroup.push_back(*i);
|
||||
i = iconQueue.erase(i);
|
||||
addedToGroup = true;
|
||||
break;
|
||||
// Found an icon in iconQueue that's close enough to
|
||||
// a member of thisGroup, so move it into thisGroup
|
||||
thisGroup.push_back(*i);
|
||||
i = iconQueue.erase(i);
|
||||
addedToGroup = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (addedToGroup) {
|
||||
if (i == iconQueue.end()) {
|
||||
// We just got the last icon out of iconQueue
|
||||
break;
|
||||
// We just got the last icon out of iconQueue
|
||||
break;
|
||||
}
|
||||
else {
|
||||
// Start looking through the iconQueue again, in case
|
||||
// we have an icon that's now close enough to thisGroup
|
||||
i = iconQueue.begin();
|
||||
// Start looking through the iconQueue again, in case
|
||||
// we have an icon that's now close enough to thisGroup
|
||||
i = iconQueue.begin();
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -410,16 +410,37 @@ double SketcherGui::GetPointAngle(const Base::Vector2d& p1, const Base::Vector2d
|
||||
|
||||
// Set the two points on circles at minimal distance
|
||||
// in concentric case set points on relative X axis
|
||||
void SketcherGui::GetCirclesMinimalDistance(const Part::GeomCircle* circle1,
|
||||
const Part::GeomCircle* circle2,
|
||||
void SketcherGui::GetCirclesMinimalDistance(const Part::Geometry* geom1,
|
||||
const Part::Geometry* geom2,
|
||||
Base::Vector3d& point1,
|
||||
Base::Vector3d& point2)
|
||||
{
|
||||
double radius1 = circle1->getRadius();
|
||||
double radius2 = circle2->getRadius();
|
||||
double radius1 = 0.0;
|
||||
double radius2 = 0.0;
|
||||
|
||||
point1 = circle1->getCenter();
|
||||
point2 = circle2->getCenter();
|
||||
if (geom1->is<Part::GeomCircle>()) {
|
||||
auto circle = static_cast<const Part::GeomCircle*>(geom1);
|
||||
radius1 = circle->getRadius();
|
||||
point1 = circle->getCenter();
|
||||
}
|
||||
else if (geom1->is<Part::GeomArcOfCircle>()) {
|
||||
auto arc = static_cast<const Part::GeomArcOfCircle*>(geom1);
|
||||
radius1 = arc->getRadius();
|
||||
point1 = arc->getCenter();
|
||||
}
|
||||
|
||||
if (geom2->is<Part::GeomCircle>()) {
|
||||
auto circle = static_cast<const Part::GeomCircle*>(geom2);
|
||||
radius2 = circle->getRadius();
|
||||
point2 = circle->getCenter();
|
||||
}
|
||||
else if (geom2->is<Part::GeomArcOfCircle>()) {
|
||||
auto arc = static_cast<const Part::GeomArcOfCircle*>(geom2);
|
||||
radius2 = arc->getRadius();
|
||||
point2 = arc->getCenter();
|
||||
}
|
||||
|
||||
assert(radius1 == 0 || radius2 == 0 /*Circles characteristics not available*/);
|
||||
|
||||
Base::Vector3d v = point2 - point1;
|
||||
double length = v.Length();
|
||||
|
||||
@@ -165,8 +165,8 @@ inline const char* constructionModeAsBooleanText()
|
||||
double GetPointAngle(const Base::Vector2d& p1, const Base::Vector2d& p2);
|
||||
|
||||
// Set the two points on circles at minimal distance
|
||||
void GetCirclesMinimalDistance(const Part::GeomCircle* circle1,
|
||||
const Part::GeomCircle* circle2,
|
||||
void GetCirclesMinimalDistance(const Part::Geometry* geom1,
|
||||
const Part::Geometry* geom2,
|
||||
Base::Vector3d& point1,
|
||||
Base::Vector3d& point2);
|
||||
|
||||
|
||||
@@ -1698,43 +1698,20 @@ void ViewProviderSketch::moveConstraint(int constNum, const Base::Vector2d& toPo
|
||||
}
|
||||
else if (Constr->Second != GeoEnum::GeoUndef) {
|
||||
p1 = getSolvedSketch().getPoint(Constr->First, Constr->FirstPos);
|
||||
const Part::Geometry* geo = GeoList::getGeometryFromGeoId(geomlist, Constr->Second);
|
||||
if (geo->is<Part::GeomLineSegment>()) {
|
||||
const Part::GeomLineSegment* lineSeg =
|
||||
static_cast<const Part::GeomLineSegment*>(geo);
|
||||
const Part::Geometry *geo = GeoList::getGeometryFromGeoId (geomlist, Constr->Second);
|
||||
const Part::Geometry *geo1 = GeoList::getGeometryFromGeoId (geomlist, Constr->First);
|
||||
if (geo->is<Part::GeomLineSegment>()) { // point to line distance
|
||||
auto *lineSeg = static_cast<const Part::GeomLineSegment *>(geo);
|
||||
Base::Vector3d l2p1 = lineSeg->getStartPoint();
|
||||
Base::Vector3d l2p2 = lineSeg->getEndPoint();
|
||||
if (Constr->FirstPos != Sketcher::PointPos::none) {// point to line distance
|
||||
// calculate the projection of p1 onto line2
|
||||
p2.ProjectToLine(p1 - l2p1, l2p2 - l2p1);
|
||||
p2 += p1;
|
||||
}
|
||||
else {
|
||||
const Part::Geometry* geo1 =
|
||||
GeoList::getGeometryFromGeoId(geomlist, Constr->First);
|
||||
const Part::GeomCircle* circleSeg = static_cast<const Part::GeomCircle*>(geo1);
|
||||
Base::Vector3d ct = circleSeg->getCenter();
|
||||
double radius = circleSeg->getRadius();
|
||||
p1.ProjectToLine(ct - l2p1,
|
||||
l2p2 - l2p1);// project on the line translated to origin
|
||||
Base::Vector3d dir = p1;
|
||||
dir.Normalize();
|
||||
p1 += ct;
|
||||
p2 = ct + dir * radius;
|
||||
}
|
||||
}
|
||||
else if (geo->is<Part::GeomCircle>()) {// circle to circle distance
|
||||
const Part::Geometry* geo1 = GeoList::getGeometryFromGeoId(geomlist, Constr->First);
|
||||
if (geo1->is<Part::GeomCircle>()) {
|
||||
const Part::GeomCircle* circleSeg1 = static_cast<const Part::GeomCircle*>(geo1);
|
||||
const Part::GeomCircle* circleSeg2 = static_cast<const Part::GeomCircle*>(geo);
|
||||
GetCirclesMinimalDistance(circleSeg1, circleSeg2, p1, p2);
|
||||
} else if (Constr->FirstPos != Sketcher::PointPos::none) { //point to circle distance
|
||||
auto circleSeg2 = static_cast<const Part::GeomCircle*>(geo);
|
||||
p1 = getSolvedSketch().getPoint(Constr->First, Constr->FirstPos);
|
||||
Base::Vector3d v = p1 - circleSeg2->getCenter();
|
||||
v = v.Normalize();
|
||||
p2 = circleSeg2->getCenter() + circleSeg2->getRadius() * v;
|
||||
// calculate the projection of p1 onto line2
|
||||
p2.ProjectToLine(p1-l2p1, l2p2-l2p1);
|
||||
p2 += p1;
|
||||
} else if (geo->is<Part::GeomCircle>() // circle to circle distance
|
||||
|| geo->is<Part::GeomArcOfCircle>()) {
|
||||
if (geo1->is<Part::GeomCircle>()
|
||||
|| geo1->is<Part::GeomArcOfCircle>()) {
|
||||
GetCirclesMinimalDistance(geo1, geo, p1, p2);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user