diff --git a/src/Mod/Sketcher/App/Sketch.cpp b/src/Mod/Sketcher/App/Sketch.cpp index 9e6e440ab..cda00f64d 100644 --- a/src/Mod/Sketcher/App/Sketch.cpp +++ b/src/Mod/Sketcher/App/Sketch.cpp @@ -2308,42 +2308,26 @@ int Sketch::initMove(int geoId, PointPos pos, bool fine) // TODO: Ellipse GCS::Point ¢er = Points[Geoms[geoId].midPointId]; GCS::Point p0,p1; - if (pos == mid) { + if (pos == mid | pos == none) { MoveParameters.resize(2); // cx,cy p0.x = &MoveParameters[0]; p0.y = &MoveParameters[1]; *p0.x = *center.x; *p0.y = *center.y; GCSsys.addConstraintP2PCoincident(p0,center,-1); - } else if (pos == none) { - // TODO: Ellipse - MoveParameters.resize(4); // x,y,cx,cy - GCS::Ellipse &e = Ellipses[Geoms[geoId].index]; - p0.x = &MoveParameters[0]; - p0.y = &MoveParameters[1]; - *p0.x = *center.x; - *p0.y = *center.y + *e.radmin; - GCSsys.addConstraintPointOnEllipse(p0,e,-1); - p1.x = &MoveParameters[2]; - p1.y = &MoveParameters[3]; - *p1.x = *center.x; - *p1.y = *center.y; - int i=GCSsys.addConstraintP2PCoincident(p1,center,-1); - GCSsys.rescaleConstraint(i-1, 0.01); - GCSsys.rescaleConstraint(i, 0.01); } } else if (Geoms[geoId].type == ArcOfEllipse) { // TODO: ArcOfEllipse GCS::Point ¢er = Points[Geoms[geoId].midPointId]; GCS::Point p0,p1; - if (pos == mid) { + if (pos == mid || pos == none) { MoveParameters.resize(2); // cx,cy p0.x = &MoveParameters[0]; p0.y = &MoveParameters[1]; *p0.x = *center.x; *p0.y = *center.y; GCSsys.addConstraintP2PCoincident(p0,center,-1); - } else if (pos == start || pos == end || pos == none) { + } else if (pos == start || pos == end) { // TODO: Ellipse MoveParameters.resize(4); // x,y,cx,cy if (pos == start || pos == end) { @@ -2354,14 +2338,7 @@ int Sketch::initMove(int geoId, PointPos pos, bool fine) *p0.x = *p.x; *p0.y = *p.y; GCSsys.addConstraintP2PCoincident(p0,p,-1); - } else if (pos == none) { - GCS::ArcOfEllipse &a = ArcsOfEllipse[Geoms[geoId].index]; - p0.x = &MoveParameters[0]; - p0.y = &MoveParameters[1]; - *p0.x = *center.x; - *p0.y = *center.y + *a.radmin; - GCSsys.addConstraintPointOnArcOfEllipse(p0,a,-1); - } + } p1.x = &MoveParameters[2]; p1.y = &MoveParameters[3]; *p1.x = *center.x; diff --git a/src/Mod/Sketcher/Gui/CommandConstraints.cpp b/src/Mod/Sketcher/Gui/CommandConstraints.cpp index c7acb0fb6..05f2324c0 100644 --- a/src/Mod/Sketcher/Gui/CommandConstraints.cpp +++ b/src/Mod/Sketcher/Gui/CommandConstraints.cpp @@ -2431,7 +2431,7 @@ void CmdSketcherConstrainInternalAlignment::activated(int iMsg) for (std::vector< Sketcher::Constraint * >::const_iterator it= vals.begin(); it != vals.end(); ++it) { - if((*it)->Type == Sketcher::InternalAlignment && (*it)->First == GeoId) + if((*it)->Type == Sketcher::InternalAlignment && (*it)->Second == GeoId) { switch((*it)->AlignmentType){ case Sketcher::EllipseMajorDiameter: diff --git a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp index 5b735c2b7..0323b03e3 100644 --- a/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp +++ b/src/Mod/Sketcher/Gui/ViewProviderSketch.cpp @@ -1979,6 +1979,79 @@ void ViewProviderSketch::doBoxSelection(const SbVec2s &startPos, const SbVec2s & } } + } else if ((*it)->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId()) { + // Check if arc lies inside box selection + const Part::GeomArcOfEllipse *aoe = dynamic_cast(*it); + + pnt0 = aoe->getStartPoint(); + pnt1 = aoe->getEndPoint(); + pnt2 = aoe->getCenter(); + VertexId += 3; + + Plm.multVec(pnt0, pnt0); + Plm.multVec(pnt1, pnt1); + Plm.multVec(pnt2, pnt2); + pnt0 = proj(pnt0); + pnt1 = proj(pnt1); + pnt2 = proj(pnt2); + + bool pnt0Inside = polygon.Contains(Base::Vector2D(pnt0.x, pnt0.y)); + if (pnt0Inside) { + std::stringstream ss; + ss << "Vertex" << VertexId - 1; + Gui::Selection().addSelection(doc->getName(), sketchObject->getNameInDocument(), ss.str().c_str()); + } + + bool pnt1Inside = polygon.Contains(Base::Vector2D(pnt1.x, pnt1.y)); + if (pnt1Inside) { + std::stringstream ss; + ss << "Vertex" << VertexId; + Gui::Selection().addSelection(doc->getName(), sketchObject->getNameInDocument(), ss.str().c_str()); + } + + if (polygon.Contains(Base::Vector2D(pnt2.x, pnt2.y))) { + std::stringstream ss; + ss << "Vertex" << VertexId + 1; + Gui::Selection().addSelection(doc->getName(), sketchObject->getNameInDocument(), ss.str().c_str()); + } + + if (pnt0Inside && pnt1Inside) { + double startangle, endangle; + aoe->getRange(startangle, endangle); + if (startangle > endangle) // if arc is reversed + std::swap(startangle, endangle); + + double range = endangle-startangle; + int countSegments = std::max(2, int(12.0 * range / (2 * M_PI))); + float segment = float(range) / countSegments; + + // circumscribed polygon radius + float a = float(aoe->getMajorRadius()) / cos(segment/2); + float b = float(aoe->getMinorRadius()) / cos(segment/2); + float phi = float(aoe->getAngleXU()); + + bool bpolyInside = true; + pnt0 = aoe->getCenter(); + float angle = float(startangle) + segment/2; + for (int i = 0; i < countSegments; ++i, angle += segment) { + pnt = Base::Vector3d(pnt0.x + a * cos(angle) * cos(phi) - b * sin(angle) * sin(phi), + pnt0.y + a * cos(angle) * sin(phi) + b * sin(angle) * cos(phi), + 0.f); + Plm.multVec(pnt, pnt); + pnt = proj(pnt); + if (!polygon.Contains(Base::Vector2D(pnt.x, pnt.y))) { + bpolyInside = false; + break; + } + } + + if (bpolyInside) { + std::stringstream ss; + ss << "Edge" << GeoId + 1; + Gui::Selection().addSelection(doc->getName(), sketchObject->getNameInDocument(), ss.str().c_str()); + } + } + } else if ((*it)->getTypeId() == Part::GeomBSplineCurve::getClassTypeId()) { const Part::GeomBSplineCurve *spline = dynamic_cast(*it); std::vector poles = spline->getPoles(); @@ -3131,13 +3204,11 @@ Restart: if (geo1->getTypeId() == Part::GeomCircle::getClassTypeId()) { // TODO: ellipse const Part::GeomCircle *circle = dynamic_cast(geo1); r1a = circle->getRadius(); - r1b=r1a; angle1 = M_PI/4; midpos1 = circle->getCenter(); } else if (geo1->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) { const Part::GeomArcOfCircle *arc = dynamic_cast(geo1); r1a = arc->getRadius(); - r1b=r1a; double startangle, endangle; arc->getRange(startangle, endangle); angle1 = (startangle + endangle)/2; @@ -3164,13 +3235,11 @@ Restart: if (geo2->getTypeId() == Part::GeomCircle::getClassTypeId()) { const Part::GeomCircle *circle = dynamic_cast(geo2); r2a = circle->getRadius(); - r2b=r2a; angle2 = M_PI/4; midpos2 = circle->getCenter(); } else if (geo2->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) { const Part::GeomArcOfCircle *arc = dynamic_cast(geo2); r2a = arc->getRadius(); - r2b=r2a; double startangle, endangle; arc->getRange(startangle, endangle); angle2 = (startangle + endangle)/2; @@ -3191,26 +3260,46 @@ Restart: angle2 = aoe->getAngleXU(); angle2plus = (startangle + endangle)/2; midpos2 = aoe->getCenter(); - } - else + } else break; - Base::Vector3d majDir, minDir, rvec; - majDir = Base::Vector3d(cos(angle1),sin(angle1),0);//direction of major axis of ellipse - minDir = Base::Vector3d(-majDir.y,majDir.x,0);//direction of minor axis of ellipse - rvec = (r1a*cos(angle1plus)) * majDir + (r1b*sin(angle1plus)) * minDir; - midpos1 += rvec; - rvec.Normalize(); - norm1 = rvec; - dir1 = Base::Vector3d(-rvec.y,rvec.x,0);//DeepSOIC: I'm not sure what dir is supposed to mean. + if( geo1->getTypeId() == Part::GeomEllipse::getClassTypeId() || + geo1->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() ){ + + Base::Vector3d majDir, minDir, rvec; + majDir = Base::Vector3d(cos(angle1),sin(angle1),0);//direction of major axis of ellipse + minDir = Base::Vector3d(-majDir.y,majDir.x,0);//direction of minor axis of ellipse + rvec = (r1a*cos(angle1plus)) * majDir + (r1b*sin(angle1plus)) * minDir; + midpos1 += rvec; + rvec.Normalize(); + norm1 = rvec; + dir1 = Base::Vector3d(-rvec.y,rvec.x,0);//DeepSOIC: I'm not sure what dir is supposed to mean. + } + else { + norm1 = Base::Vector3d(cos(angle1),sin(angle1),0); + dir1 = Base::Vector3d(-norm1.y,norm1.x,0); + midpos1 += r1a*norm1; + } + - majDir = Base::Vector3d(cos(angle2),sin(angle2),0);//direction of major axis of ellipse - minDir = Base::Vector3d(-majDir.y,majDir.x,0);//direction of minor axis of ellipse - rvec = (r2a*cos(angle2plus)) * majDir + (r2b*sin(angle2plus)) * minDir; - midpos2 += rvec; - rvec.Normalize(); - norm2 = rvec; - dir2 = Base::Vector3d(-rvec.y,rvec.x,0); + if( geo2->getTypeId() == Part::GeomEllipse::getClassTypeId() || + geo2->getTypeId() == Part::GeomArcOfEllipse::getClassTypeId() ) { + + Base::Vector3d majDir, minDir, rvec; + majDir = Base::Vector3d(cos(angle2),sin(angle2),0);//direction of major axis of ellipse + minDir = Base::Vector3d(-majDir.y,majDir.x,0);//direction of minor axis of ellipse + rvec = (r2a*cos(angle2plus)) * majDir + (r2b*sin(angle2plus)) * minDir; + midpos2 += rvec; + rvec.Normalize(); + norm2 = rvec; + dir2 = Base::Vector3d(-rvec.y,rvec.x,0); + } + else { + norm2 = Base::Vector3d(cos(angle2),sin(angle2),0); + dir2 = Base::Vector3d(-norm2.y,norm2.x,0); + midpos2 += r2a*norm2; + } + } else // Parallel can only apply to a GeomLineSegment break; } else {