Improve radius/diameter dims for ellipse,spline

This commit is contained in:
wandererfan
2019-05-06 20:02:21 -04:00
committed by WandererFan
parent 42c2a4d6ac
commit af0271691c
7 changed files with 147 additions and 24 deletions

View File

@@ -92,6 +92,7 @@ DrawView::~DrawView()
App::DocumentObjectExecReturn *DrawView::execute(void)
{
// Base::Console().Message("DV::execute() - %s\n", getNameInDocument());
handleXYLock();
requestPaint();
return App::DocumentObject::execute();
@@ -429,6 +430,7 @@ bool DrawView::keepUpdated(void)
void DrawView::requestPaint(void)
{
// Base::Console().Message("DV::requestPaint() - %s\n", getNameInDocument());
signalGuiPaint(this);
}

View File

@@ -238,6 +238,7 @@ App::DocumentObjectExecReturn *DrawViewDimension::execute(void)
//now we can check if Reference2ds have valid targets.
if (!checkReferences2D()) {
Base::Console().Warning("%s has invalid 2D References\n", getNameInDocument());
return App::DocumentObject::StdReturn;
}
@@ -282,6 +283,37 @@ App::DocumentObjectExecReturn *DrawViewDimension::execute(void)
pts.onCurve.first = pts.center + Base::Vector3d(1,0,0) * circle->radius; //arbitrary point on edge
pts.onCurve.second = pts.center + Base::Vector3d(-1,0,0) * circle->radius; //arbitrary point on edge
}
} else if ((base && base->geomType == TechDrawGeometry::GeomType::ELLIPSE) ||
(base && base->geomType == TechDrawGeometry::GeomType::ARCOFELLIPSE)) {
TechDrawGeometry::Ellipse* ellipse = static_cast<TechDrawGeometry::Ellipse*> (base);
if (ellipse->closed()) {
double r1 = ellipse->minor;
double r2 = ellipse->major;
double rAvg = (r1 + r2) / 2.0;
pts.center = Base::Vector3d(ellipse->center.x,
ellipse->center.y,
0.0);
pts.radius = rAvg;
pts.isArc = false;
pts.onCurve.first = pts.center + Base::Vector3d(1,0,0) * rAvg; //arbitrary point on edge
pts.onCurve.second = pts.center + Base::Vector3d(-1,0,0) * rAvg; //arbitrary point on edge
} else {
TechDrawGeometry::AOE* aoe = static_cast<TechDrawGeometry::AOE*> (base);
double r1 = aoe->minor;
double r2 = aoe->major;
double rAvg = (r1 + r2) / 2.0;
pts.isArc = true;
pts.center = Base::Vector3d(aoe->center.x,
aoe->center.y,
0.0);
pts.radius = rAvg;
pts.arcEnds.first = Base::Vector3d(aoe->startPnt.x,aoe->startPnt.y,0.0);
pts.arcEnds.second = Base::Vector3d(aoe->endPnt.x,aoe->endPnt.y,0.0);
pts.midArc = Base::Vector3d(aoe->midPnt.x,aoe->midPnt.y,0.0);
pts.arcCW = aoe->cw;
pts.onCurve.first = Base::Vector3d(aoe->midPnt.x,aoe->midPnt.y,0.0);
pts.onCurve.second = pts.center + Base::Vector3d(-1,0,0) * rAvg; //arbitrary point on edge
}
} else if (base && base->geomType == TechDrawGeometry::GeomType::BSPLINE) {
TechDrawGeometry::BSpline* spline = static_cast<TechDrawGeometry::BSpline*> (base);
if (spline->isCircle()) {
@@ -303,7 +335,7 @@ App::DocumentObjectExecReturn *DrawViewDimension::execute(void)
pts.onCurve.second = pts.center + Base::Vector3d(-1,0,0) * rad; //arbitrary point on edge
}
} else {
//fubar - can't have non-circular spline as target of Diameter dimension
//fubar - can't have non-circular spline as target of Radius dimension
Base::Console().Error("Dimension %s refers to invalid BSpline\n",getNameInDocument());
return App::DocumentObject::StdReturn;
}
@@ -338,6 +370,37 @@ App::DocumentObjectExecReturn *DrawViewDimension::execute(void)
pts.onCurve.first = pts.center + Base::Vector3d(1,0,0) * circle->radius; //arbitrary point on edge
pts.onCurve.second = pts.center + Base::Vector3d(-1,0,0) * circle->radius; //arbitrary point on edge
}
} else if ( (base && base->geomType == TechDrawGeometry::GeomType::ELLIPSE) ||
(base && base->geomType == TechDrawGeometry::GeomType::ARCOFELLIPSE) ) {
TechDrawGeometry::Ellipse* ellipse = static_cast<TechDrawGeometry::Ellipse*> (base);
if (ellipse->closed()) {
double r1 = ellipse->minor;
double r2 = ellipse->major;
double rAvg = (r1 + r2) / 2.0;
pts.center = Base::Vector3d(ellipse->center.x,
ellipse->center.y,
0.0);
pts.radius = rAvg;
pts.isArc = false;
pts.onCurve.first = pts.center + Base::Vector3d(1,0,0) * rAvg; //arbitrary point on edge
pts.onCurve.second = pts.center + Base::Vector3d(-1,0,0) * rAvg; //arbitrary point on edge
} else {
TechDrawGeometry::AOE* aoe = static_cast<TechDrawGeometry::AOE*> (base);
double r1 = aoe->minor;
double r2 = aoe->major;
double rAvg = (r1 + r2) / 2.0;
pts.isArc = true;
pts.center = Base::Vector3d(aoe->center.x,
aoe->center.y,
0.0);
pts.radius = rAvg;
pts.arcEnds.first = Base::Vector3d(aoe->startPnt.x,aoe->startPnt.y,0.0);
pts.arcEnds.second = Base::Vector3d(aoe->endPnt.x,aoe->endPnt.y,0.0);
pts.midArc = Base::Vector3d(aoe->midPnt.x,aoe->midPnt.y,0.0);
pts.arcCW = aoe->cw;
pts.onCurve.first = Base::Vector3d(aoe->midPnt.x,aoe->midPnt.y,0.0);
pts.onCurve.second = pts.center + Base::Vector3d(-1,0,0) * rAvg; //arbitrary point on edge
}
} else if (base && base->geomType == TechDrawGeometry::GeomType::BSPLINE) {
TechDrawGeometry::BSpline* spline = static_cast<TechDrawGeometry::BSpline*> (base);
if (spline->isCircle()) {
@@ -360,7 +423,7 @@ App::DocumentObjectExecReturn *DrawViewDimension::execute(void)
}
} else {
//fubar - can't have non-circular spline as target of Diameter dimension
Base::Console().Error("Dimension %s refers to invalid BSpline\n",getNameInDocument());
Base::Console().Error("%s: can not make a Circle from this BSpline edge\n",getNameInDocument());
return App::DocumentObject::StdReturn;
}
} else {
@@ -442,7 +505,6 @@ App::DocumentObjectExecReturn *DrawViewDimension::execute(void)
}
//TODO: if MeasureType = Projected and the Projected shape changes, the Dimension may become invalid (see tilted Cube example)
return DrawView::execute();
}
@@ -627,7 +689,6 @@ double DrawViewDimension::getDimValue()
} else if(Type.isValue("Radius")){
arcPoints pts = m_arcPoints;
result = pts.radius / getViewPart()->getScale(); //Projected BaseGeom is scaled for drawing
} else if(Type.isValue("Diameter")){
arcPoints pts = m_arcPoints;

View File

@@ -197,6 +197,22 @@ std::string BaseGeom::dump()
return ss.str();
}
bool BaseGeom::closed(void)
{
//return occEdge.Closed(); //based on a flag in occ. may not be correct!
bool result = false;
Base::Vector3d start(getStartPoint().x,
getStartPoint().y,
0.0);
Base::Vector3d end(getEndPoint().x,
getEndPoint().y,
0.0);
if (start.IsEqual(end, 0.00001)) {
result = true;
}
return result;
}
//! Convert 1 OCC edge into 1 BaseGeom (static factory method)
BaseGeom* BaseGeom::baseFactory(TopoDS_Edge edge)
@@ -252,7 +268,7 @@ BaseGeom* BaseGeom::baseFactory(TopoDS_Edge edge)
delete bspline;
bspline = nullptr;
} else {
TopoDS_Edge circEdge = bspline->isCircle2(isArc);
TopoDS_Edge circEdge = bspline->asCircle(isArc);
if (!circEdge.IsNull()) {
if (isArc) {
aoc = new AOC(circEdge);
@@ -699,8 +715,8 @@ void BSpline::getCircleParms(bool& isCircle, double& radius, Base::Vector3d& cen
}
}
// can this BSpline be a circle?
TopoDS_Edge BSpline::isCircle2(bool& arc)
// make a circular edge from BSpline
TopoDS_Edge BSpline::asCircle(bool& arc)
{
TopoDS_Edge result;
BRepAdaptor_Curve c(occEdge);
@@ -743,7 +759,7 @@ TopoDS_Edge BSpline::isCircle2(bool& arc)
projm.Perform(pm);
}
catch(const StdFail_NotDone &e) {
Base::Console().Log("Geometry::isCircle2 - init: %s\n",e.GetMessageString());
Base::Console().Log("Geometry::asCircle - init: %s\n",e.GetMessageString());
return result;
}
if ( (proj1.NbPoints() == 0) ||
@@ -760,7 +776,7 @@ TopoDS_Edge BSpline::isCircle2(bool& arc)
pcm = projm.NearestPoint();
}
catch(const StdFail_NotDone &e) {
Base::Console().Log("Geometry::isCircle2 - nearPoint: %s\n",e.GetMessageString());
Base::Console().Log("Geometry::asCircle - nearPoint: %s\n",e.GetMessageString());
return result;
}

View File

@@ -81,6 +81,7 @@ class TechDrawExport BaseGeom
Base::Vector2d nearPoint(Base::Vector2d p);
Base::Vector2d nearPoint(const BaseGeom* p);
static BaseGeom* baseFactory(TopoDS_Edge edge);
bool closed(void);
std::string dump();
};
@@ -192,7 +193,7 @@ class TechDrawExport BSpline: public BaseGeom
bool isLine(void);
bool isCircle(void);
TopoDS_Edge isCircle2(bool& isArc);
TopoDS_Edge asCircle(bool& isArc);
void getCircleParms(bool& isCircle, double& radius, Base::Vector3d& center, bool& isArc);
bool intersectsArc(Base::Vector3d p1,Base::Vector3d p2);
std::vector<BezierSegment> segments;

View File

@@ -283,12 +283,33 @@ void CmdTechDrawNewRadiusDimension::activated(int iMsg)
if (edgeType == isCircle) {
objs.push_back(objFeat);
subs.push_back(SubNames[0]);
} else if (edgeType == isEllipse) {
QMessageBox::StandardButton result =
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Ellipse Curve Warning"),
QObject::tr("Selected edge is an Ellipse. Radius will be approximate. Continue?"),
QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
if (result == QMessageBox::Ok) {
objs.push_back(objFeat);
subs.push_back(SubNames[0]);
} else {
return;
}
} else if (edgeType == isBSplineCircle) {
QMessageBox::StandardButton result =
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Selection Warning"),
QObject::tr("Selected edge is a BSpline. Radius will be approximate."),
QMessageBox::Ok | QMessageBox::Cancel,
QMessageBox::Cancel);
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("BSpline Curve Warning"),
QObject::tr("Selected edge is a BSpline. Radius will be approximate. Continue?"),
QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
if (result == QMessageBox::Ok) {
objs.push_back(objFeat);
subs.push_back(SubNames[0]);
} else {
return;
}
} else if (edgeType == isBSpline) {
QMessageBox::StandardButton result =
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("BSpline Curve Warning"),
QObject::tr("Selected edge is a BSpline. Radius will be approximate. Continue?"),
QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
if (result == QMessageBox::Ok) {
objs.push_back(objFeat);
subs.push_back(SubNames[0]);
@@ -317,6 +338,7 @@ void CmdTechDrawNewRadiusDimension::activated(int iMsg)
doCommand(Doc,"App.activeDocument().%s.addView(App.activeDocument().%s)",PageName.c_str(),FeatName.c_str());
commitCommand();
dim->recomputeFeature();
//Horrible hack to force Tree update
@@ -383,12 +405,33 @@ void CmdTechDrawNewDiameterDimension::activated(int iMsg)
if (edgeType == isCircle) {
objs.push_back(objFeat);
subs.push_back(SubNames[0]);
} else if (edgeType == isEllipse) {
QMessageBox::StandardButton result =
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Ellipse Curve Warning"),
QObject::tr("Selected edge is an Ellipse. Diameter will be approximate. Continue?"),
QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
if (result == QMessageBox::Ok) {
objs.push_back(objFeat);
subs.push_back(SubNames[0]);
} else {
return;
}
} else if (edgeType == isBSplineCircle) {
QMessageBox::StandardButton result =
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Selection Warning"),
QObject::tr("Selected edge is a BSpline. Diameter will be approximate."),
QMessageBox::Ok | QMessageBox::Cancel,
QMessageBox::Cancel);
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("BSpline Curve Warning"),
QObject::tr("Selected edge is a BSpline. Diameter will be approximate. Continue?"),
QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
if (result == QMessageBox::Ok) {
objs.push_back(objFeat);
subs.push_back(SubNames[0]);
} else {
return;
}
} else if (edgeType == isBSpline) {
QMessageBox::StandardButton result =
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("BSpline Curve Warning"),
QObject::tr("Selected edge is a BSpline. Diameter will be approximate. Continue?"),
QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
if (result == QMessageBox::Ok) {
objs.push_back(objFeat);
subs.push_back(SubNames[0]);

View File

@@ -449,7 +449,6 @@ QString QGIViewDimension::getLabelText(void)
QString second = datumLabel->getTolText()->toPlainText();
result = first + second;
return result;
}
void QGIViewDimension::datumLabelDragged(bool ctrl)
@@ -1104,7 +1103,6 @@ void QGIViewDimension::draw()
} else if(strcmp(dimType, "Radius") == 0) {
// preferred terminology: Dimension Text, Dimension Line(s), Extension Lines, Arrowheads
// radius gets 1 dimension line from the dimension text to a point on the curve
Base::Vector3d pointOnCurve,curveCenter;
double radius;
arcPoints pts = dim->getArcPoints();
@@ -1371,7 +1369,6 @@ void QGIViewDimension::draw()
Base::Vector3d labelNorm(-labelVec.y, labelVec.x, 0.);
double lAngle = atan2(labelNorm.y, labelNorm.x);
//<<<<<<<<<<<
if (lAngle < 0.0) {
lAngle = 2 * M_PI + lAngle; //map to +ve lAngle
}
@@ -1385,7 +1382,6 @@ void QGIViewDimension::draw()
(lAngle <= 1.5*M_PI - angleFiddle)) { // < 260CW -> Q3
lAngle -= M_PI; // flip CCW
}
//<<<<<<<<<
// //if label is more/less vertical, make it vertical
@@ -1424,7 +1420,6 @@ void QGIViewDimension::draw()
} else {
Base::Console().Log("INFO - QGIVD::draw - no parent to update\n");
}
}
void QGIViewDimension::drawBorder(void)

View File

@@ -86,8 +86,10 @@ void ViewProviderDrawingView::attach(App::DocumentObject *pcFeat)
auto feature = getViewObject();
if (feature != nullptr) {
connectGuiRepaint = feature->signalGuiPaint.connect(bnd);
//TODO: would be good to start the QGIV creation process here, but no guarantee we actually have
// MDIVP or QGVP yet.
} else {
Base::Console().Log("VPDV::attach has no Feature!\n");
Base::Console().Warning("VPDV::attach has no Feature!\n");
}
}
@@ -240,6 +242,7 @@ MDIViewPage* ViewProviderDrawingView::getMDIViewPage() const
void ViewProviderDrawingView::onGuiRepaint(const TechDraw::DrawView* dv)
{
// Base::Console().Message("VPDV::onGuiRepaint(%s)\n", dv->getNameInDocument());
if (dv == getViewObject()) {
if (!dv->isRemoving() &&
!dv->isRestoring()) {
@@ -247,6 +250,8 @@ void ViewProviderDrawingView::onGuiRepaint(const TechDraw::DrawView* dv)
if (qgiv) {
qgiv->updateView(true);
} else { //we are not part of the Gui page yet. ask page to add us.
//TODO: this bit causes trouble. Should move QGIV creation to attach?
// is MDIVP/QGVP available at attach time?
MDIViewPage* page = getMDIViewPage();
if (page != nullptr) {
page->addView(dv);