Merge pull request #12012 from Ondsel-Development/radius_render_fix
[Sketcher] Improve rendering of arc-angle, line-angle, arc-distances and fix radius
This commit is contained in:
@@ -93,6 +93,9 @@ SoDatumLabel::SoDatumLabel()
|
||||
SO_NODE_ADD_FIELD(param2, (0.f));
|
||||
SO_NODE_ADD_FIELD(param4, (0.f));
|
||||
SO_NODE_ADD_FIELD(param5, (0.f));
|
||||
SO_NODE_ADD_FIELD(param6, (0.f));
|
||||
SO_NODE_ADD_FIELD(param7, (0.f));
|
||||
SO_NODE_ADD_FIELD(param8, (0.f));
|
||||
|
||||
useAntialiasing = true;
|
||||
|
||||
@@ -989,6 +992,43 @@ void SoDatumLabel::GLRender(SoGLRenderAction * action)
|
||||
glVertex2f(ar3[0], ar3[1]);
|
||||
glVertex2f(ar4[0], ar4[1]);
|
||||
glEnd();
|
||||
|
||||
|
||||
if (this->datumtype.getValue() == DISTANCE) {
|
||||
// Draw arc helpers if needed
|
||||
float range1 = this->param4.getValue();
|
||||
if (range1 != 0.0) {
|
||||
float startangle1 = this->param3.getValue();
|
||||
float radius1 = this->param5.getValue();
|
||||
SbVec3f center = points[2];
|
||||
int countSegments = std::max(6, abs(int(50.0 * range1 / (2 * M_PI))));
|
||||
double segment = range1 / (countSegments - 1);
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (int i = 0; i < countSegments; i++) {
|
||||
double theta = startangle1 + segment * i;
|
||||
SbVec3f v1 = center + SbVec3f(radius1 * cos(theta), radius1 * sin(theta), 0);
|
||||
glVertex2f(v1[0], v1[1]);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
float range2 = this->param7.getValue();
|
||||
if (range2 != 0.0) {
|
||||
float startangle2 = this->param6.getValue();
|
||||
float radius2 = this->param8.getValue();
|
||||
SbVec3f center = points[3];
|
||||
int countSegments = std::max(6, abs(int(50.0 * range2 / (2 * M_PI))));
|
||||
double segment = range2 / (countSegments - 1);
|
||||
|
||||
glBegin(GL_LINE_STRIP);
|
||||
for (int i = 0; i < countSegments; i++) {
|
||||
double theta = startangle2 + segment * i;
|
||||
SbVec3f v1 = center + SbVec3f(radius2 * cos(theta), radius2 * sin(theta), 0);
|
||||
glVertex2f(v1[0], v1[1]);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (this->datumtype.getValue() == RADIUS || this->datumtype.getValue() == DIAMETER) {
|
||||
// Get the Points
|
||||
|
||||
@@ -77,6 +77,9 @@ public:
|
||||
SoSFFloat param3;
|
||||
SoSFFloat param4;
|
||||
SoSFFloat param5;
|
||||
SoSFFloat param6;
|
||||
SoSFFloat param7;
|
||||
SoSFFloat param8;
|
||||
SoMFVec3f pnts;
|
||||
SoSFVec3f norm;
|
||||
SoSFImage image;
|
||||
|
||||
@@ -814,6 +814,17 @@ Restart:
|
||||
case DistanceY: {
|
||||
assert(Constr->First >= -extGeoCount && Constr->First < intGeoCount);
|
||||
|
||||
double helperStartAngle1 = 0.; // for arc helpers
|
||||
double helperStartAngle2 = 0.;
|
||||
double helperRange1 = 0.;
|
||||
double helperRange2 = 0.;
|
||||
double radius1 = 0.;
|
||||
double radius2 = 0.;
|
||||
Base::Vector3d center1(0., 0., 0.);
|
||||
Base::Vector3d center2(0., 0., 0.);
|
||||
|
||||
int numPoints = 2;
|
||||
|
||||
// pnt1 will be initialized to (0,0,0) if only one point is given
|
||||
auto pnt1 = geolistfacade.getPoint(Constr->First, Constr->FirstPos);
|
||||
|
||||
@@ -838,17 +849,15 @@ Restart:
|
||||
pnt2.ProjectToLine(pnt1 - l2p1, l2p2 - l2p1);
|
||||
pnt2 += pnt1;
|
||||
}
|
||||
else {
|
||||
if (isCircleOrArc(*geo1)) {
|
||||
// circular to line distance
|
||||
auto [radius, ct] = getRadiusCenterCircleArc(geo1);
|
||||
// project the center on the line (translated to origin)
|
||||
pnt1.ProjectToLine(ct - l2p1, l2p2 - l2p1);
|
||||
Base::Vector3d dir = pnt1;
|
||||
dir.Normalize();
|
||||
pnt1 += ct;
|
||||
pnt2 = ct + dir * radius;
|
||||
}
|
||||
else if (isCircleOrArc(*geo1)) {
|
||||
// circular to line distance
|
||||
auto [radius, ct] = getRadiusCenterCircleArc(geo1);
|
||||
// project the center on the line (translated to origin)
|
||||
pnt1.ProjectToLine(ct - l2p1, l2p2 - l2p1);
|
||||
Base::Vector3d dir = pnt1;
|
||||
dir.Normalize();
|
||||
pnt1 += ct;
|
||||
pnt2 = ct + dir * radius;
|
||||
}
|
||||
}
|
||||
else if (isCircleOrArc(*geo2)) {
|
||||
@@ -890,10 +899,8 @@ Restart:
|
||||
break;
|
||||
}
|
||||
|
||||
// NOLINTBEGIN
|
||||
SoDatumLabel* asciiText = static_cast<SoDatumLabel*>(
|
||||
sep->getChild(static_cast<int>(ConstraintNodePosition::DatumLabelIndex)));
|
||||
// NOLINTEND
|
||||
int index = static_cast<int>(ConstraintNodePosition::DatumLabelIndex);
|
||||
auto* asciiText = static_cast<SoDatumLabel*>(sep->getChild(index)); // NOLINT
|
||||
|
||||
// Get presentation string (w/o units if option is set)
|
||||
asciiText->string =
|
||||
@@ -909,13 +916,102 @@ Restart:
|
||||
asciiText->datumtype = SoDatumLabel::DISTANCEY;
|
||||
}
|
||||
|
||||
// Check if arc helpers are needed
|
||||
if (Constr->Second != GeoEnum::GeoUndef
|
||||
&& Constr->SecondPos == Sketcher::PointPos::none) {
|
||||
auto geo1 = geolistfacade.getGeometryFromGeoId(Constr->First);
|
||||
auto geo2 = geolistfacade.getGeometryFromGeoId(Constr->Second);
|
||||
|
||||
if (isArcOfCircle(*geo1)) {
|
||||
auto arc = static_cast<const Part::GeomArcOfCircle*>(geo1); // NOLINT
|
||||
radius1 = arc->getRadius();
|
||||
center1 = arc->getCenter();
|
||||
|
||||
double angle =
|
||||
toVector2d(isLineSegment(*geo2) ? pnt2 - center1 : pnt1 - center1)
|
||||
.Angle();
|
||||
double startAngle, endAngle;
|
||||
arc->getRange(startAngle, endAngle, /*emulateCCW=*/true);
|
||||
|
||||
findHelperAngles(helperStartAngle1,
|
||||
helperRange1,
|
||||
angle,
|
||||
startAngle,
|
||||
endAngle);
|
||||
|
||||
if (helperRange1 != 0.) {
|
||||
// We override to draw the full helper as it does not look good
|
||||
// otherwise We still use findHelperAngles before to find if helper
|
||||
// is needed.
|
||||
helperStartAngle1 = endAngle;
|
||||
helperRange1 = 2 * M_PI - (endAngle - startAngle);
|
||||
|
||||
numPoints++;
|
||||
}
|
||||
}
|
||||
if (isArcOfCircle(*geo2)) {
|
||||
auto arc = static_cast<const Part::GeomArcOfCircle*>(geo2); // NOLINT
|
||||
radius2 = arc->getRadius();
|
||||
center2 = arc->getCenter();
|
||||
|
||||
double angle =
|
||||
toVector2d(pnt2 - center2).Angle(); // between -pi and pi
|
||||
double startAngle, endAngle; // between 0 and 2*pi
|
||||
arc->getRange(startAngle, endAngle, /*emulateCCW=*/true);
|
||||
|
||||
findHelperAngles(helperStartAngle2,
|
||||
helperRange2,
|
||||
angle,
|
||||
startAngle,
|
||||
endAngle);
|
||||
|
||||
if (helperRange2 != 0.) {
|
||||
helperStartAngle2 = endAngle;
|
||||
helperRange2 = 2 * M_PI - (endAngle - startAngle);
|
||||
|
||||
numPoints++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Assign the Datum Points
|
||||
asciiText->pnts.setNum(2);
|
||||
asciiText->pnts.setNum(numPoints);
|
||||
SbVec3f* verts = asciiText->pnts.startEditing();
|
||||
|
||||
verts[0] = SbVec3f(pnt1.x, pnt1.y, zConstrH);
|
||||
verts[1] = SbVec3f(pnt2.x, pnt2.y, zConstrH);
|
||||
|
||||
if (numPoints > 2) {
|
||||
if (helperRange1 != 0.) {
|
||||
verts[2] = SbVec3f(center1.x, center1.y, zConstrH);
|
||||
asciiText->param3 = helperStartAngle1;
|
||||
asciiText->param4 = helperRange1;
|
||||
asciiText->param5 = radius1;
|
||||
}
|
||||
else {
|
||||
verts[2] = SbVec3f(center2.x, center2.y, zConstrH);
|
||||
asciiText->param3 = helperStartAngle2;
|
||||
asciiText->param4 = helperRange2;
|
||||
asciiText->param5 = radius2;
|
||||
}
|
||||
if (numPoints > 3) {
|
||||
verts[3] = SbVec3f(center2.x, center2.y, zConstrH);
|
||||
asciiText->param6 = helperStartAngle2;
|
||||
asciiText->param7 = helperRange2;
|
||||
asciiText->param8 = radius2;
|
||||
}
|
||||
else {
|
||||
asciiText->param6 = 0.;
|
||||
asciiText->param7 = 0.;
|
||||
asciiText->param8 = 0.;
|
||||
}
|
||||
}
|
||||
else {
|
||||
asciiText->param3 = 0.;
|
||||
asciiText->param4 = 0.;
|
||||
asciiText->param5 = 0.;
|
||||
}
|
||||
|
||||
asciiText->pnts.finishEditing();
|
||||
|
||||
// Assign the Label Distance
|
||||
@@ -1281,20 +1377,25 @@ Restart:
|
||||
const Part::Geometry* geo =
|
||||
geolistfacade.getGeometryFromGeoId(Constr->First);
|
||||
if (geo->is<Part::GeomLineSegment>()) {
|
||||
const Part::GeomLineSegment* lineSeg =
|
||||
static_cast<const Part::GeomLineSegment*>(geo);
|
||||
auto* lineSeg = static_cast<const Part::GeomLineSegment*>(geo);
|
||||
p0 = Base::convertTo<SbVec3f>(
|
||||
(lineSeg->getEndPoint() + lineSeg->getStartPoint()) / 2);
|
||||
double l1 = 2 * distance
|
||||
- (lineSeg->getEndPoint() - lineSeg->getStartPoint()).Length() / 2;
|
||||
endLineLength1 = 2 * distance;
|
||||
endLineLength2 = l1 > 0. ? l1 : 0.;
|
||||
|
||||
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);
|
||||
auto* arc = static_cast<const Part::GeomArcOfCircle*>(geo);
|
||||
p0 = Base::convertTo<SbVec3f>(arc->getCenter());
|
||||
|
||||
endLineLength1 = 2 * distance - arc->getRadius();
|
||||
endLineLength2 = endLineLength1;
|
||||
|
||||
double endangle;
|
||||
arc->getRange(startangle, endangle, /*emulateCCWXY=*/true);
|
||||
range = endangle - startangle;
|
||||
@@ -1333,51 +1434,43 @@ Restart:
|
||||
double helperStartAngle = 0.;
|
||||
double helperRange = 0.;
|
||||
|
||||
if (Constr->First != GeoEnum::GeoUndef) {
|
||||
const Part::Geometry* geo =
|
||||
geolistfacade.getGeometryFromGeoId(Constr->First);
|
||||
if (Constr->First == GeoEnum::GeoUndef) {
|
||||
break;
|
||||
}
|
||||
|
||||
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.);
|
||||
const Part::Geometry* geo = 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; // between -pi and pi
|
||||
double startAngle, endAngle; // between 0 and 2*pi
|
||||
arc->getRange(startAngle, endAngle, /*emulateCCW=*/true);
|
||||
|
||||
if (angle == 10) {
|
||||
angle = (startAngle + endAngle) / 2;
|
||||
}
|
||||
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.);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
|
||||
findHelperAngles(helperStartAngle,
|
||||
helperRange,
|
||||
angle,
|
||||
startAngle,
|
||||
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.);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
@@ -1415,54 +1508,45 @@ Restart:
|
||||
double helperStartAngle = 0.;
|
||||
double helperRange = 0.;
|
||||
|
||||
if (Constr->First != GeoEnum::GeoUndef) {
|
||||
const Part::Geometry* geo =
|
||||
geolistfacade.getGeometryFromGeoId(Constr->First);
|
||||
if (Constr->First == GeoEnum::GeoUndef) {
|
||||
break;
|
||||
}
|
||||
const Part::Geometry* geo = 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.);
|
||||
if (geo->is<Part::GeomArcOfCircle>()) {
|
||||
auto* arc = static_cast<const Part::GeomArcOfCircle*>(geo);
|
||||
double radius = arc->getRadius();
|
||||
double angle = (double)Constr->LabelPosition; // between -pi and pi
|
||||
double startAngle, endAngle; // between 0 and 2*pi
|
||||
arc->getRange(startAngle, endAngle, /*emulateCCW=*/true);
|
||||
|
||||
if (angle == 10) {
|
||||
angle = (startAngle + endAngle) / 2;
|
||||
}
|
||||
else if (geo->is<Part::GeomCircle>()) {
|
||||
auto* circle = static_cast<const Part::GeomCircle*>(geo);
|
||||
auto gf = GeometryFacade::getFacade(geo);
|
||||
|
||||
double radius;
|
||||
findHelperAngles(helperStartAngle,
|
||||
helperRange,
|
||||
angle,
|
||||
startAngle,
|
||||
endAngle);
|
||||
|
||||
radius = circle->getRadius();
|
||||
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);
|
||||
|
||||
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;
|
||||
double radius;
|
||||
|
||||
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.);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
@@ -1518,6 +1602,39 @@ Restart:
|
||||
}
|
||||
}
|
||||
|
||||
void EditModeConstraintCoinManager::findHelperAngles(double& helperStartAngle,
|
||||
double& helperRange,
|
||||
double angle,
|
||||
double startAngle,
|
||||
double endAngle)
|
||||
{
|
||||
double margin = 0.2; // about 10deg
|
||||
if (angle < 0) {
|
||||
angle = angle + 2 * M_PI;
|
||||
}
|
||||
// endAngle can be more than 2*pi as its startAngle + arcAngle
|
||||
if (endAngle > 2 * M_PI && angle < endAngle - 2 * M_PI) {
|
||||
angle = angle + 2 * M_PI;
|
||||
}
|
||||
if (!(angle > startAngle && angle < endAngle)) {
|
||||
if ((angle < startAngle && startAngle - angle < angle + 2 * M_PI - endAngle)
|
||||
|| (angle > endAngle && startAngle + 2 * M_PI - angle < angle - endAngle)) {
|
||||
if (angle > startAngle) {
|
||||
angle -= 2 * M_PI;
|
||||
}
|
||||
helperStartAngle = angle - margin;
|
||||
helperRange = startAngle - angle + margin;
|
||||
}
|
||||
else {
|
||||
if (angle < endAngle) {
|
||||
angle += 2 * M_PI;
|
||||
}
|
||||
helperStartAngle = endAngle;
|
||||
helperRange = angle - endAngle + margin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Base::Vector3d EditModeConstraintCoinManager::seekConstraintPosition(const Base::Vector3d& origPos,
|
||||
const Base::Vector3d& norm,
|
||||
const Base::Vector3d& dir,
|
||||
|
||||
@@ -250,6 +250,13 @@ private:
|
||||
|
||||
/// Essentially a version of sendConstraintIconToCoin, with a blank icon
|
||||
void clearCoinImage(SoImage* soImagePtr);
|
||||
|
||||
/// Find helper angle for radius/diameter constraint
|
||||
void findHelperAngles(double& helperStartAngle,
|
||||
double& helperAngle,
|
||||
double angle,
|
||||
double startAngle,
|
||||
double endAngle);
|
||||
//@}
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user