diff --git a/src/Mod/TechDraw/Gui/QGEPath.cpp b/src/Mod/TechDraw/Gui/QGEPath.cpp index 8c6ae8a5b5..0e99ed3e7d 100644 --- a/src/Mod/TechDraw/Gui/QGEPath.cpp +++ b/src/Mod/TechDraw/Gui/QGEPath.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #endif #include @@ -173,7 +174,9 @@ QGEPath::QGEPath() : m_attach(QPointF(0.0,0.0)), m_scale(1.0), m_inEdit(false), - m_parentItem(nullptr) + m_parentItem(nullptr), + m_startAdj(0.0), + m_endAdj(0.0) { setHandlesChildEvents(false); setAcceptHoverEvents(true); @@ -384,12 +387,26 @@ void QGEPath::updatePath(void) } QPainterPath result; prepareGeometryChange(); + QPointF startAdjVec(0.0,0.0); + QPointF endAdjVec(0.0,0.0); if (m_deltas.size() > 1) { - result.moveTo(m_deltas.front()); //(0,0) - for (int i = 1; i < (int)m_deltas.size(); i++) { - result.lineTo(m_deltas.at(i) * m_scale); + startAdjVec = m_deltas.at(1) - m_deltas.front(); + endAdjVec = (*(m_deltas.end() - 2))- m_deltas.back(); + //this next bit is ugly. + QVector2D startTemp(startAdjVec); + QVector2D endTemp(endAdjVec); + startTemp.normalize(); + endTemp.normalize(); + startAdjVec = startTemp.toPointF() * m_startAdj; + endAdjVec = endTemp.toPointF() * m_endAdj; + std::vector tempDeltas = m_deltas; + tempDeltas.front() += startAdjVec; + tempDeltas.back() += endAdjVec; + result.moveTo(tempDeltas.front()); + for (int i = 1; i < (int)tempDeltas.size(); i++) { + result.lineTo(tempDeltas.at(i) * m_scale); } - } + } setPath(result); } @@ -445,6 +462,16 @@ void QGEPath::drawGhost(void) m_ghost->show(); } +void QGEPath::setStartAdjust(double adj) +{ + m_startAdj = Rez::guiX(adj); +} + +void QGEPath::setEndAdjust(double adj) +{ + m_endAdj = Rez::guiX(adj); +} + QRectF QGEPath::boundingRect() const { return shape().controlPointRect(); diff --git a/src/Mod/TechDraw/Gui/QGEPath.h b/src/Mod/TechDraw/Gui/QGEPath.h index f8091fc728..1aa54da593 100644 --- a/src/Mod/TechDraw/Gui/QGEPath.h +++ b/src/Mod/TechDraw/Gui/QGEPath.h @@ -122,6 +122,8 @@ public: void dumpPoints(char* text); void dumpMarkerPos(char* text); void restoreState(void); + void setStartAdjust(double adjust); + void setEndAdjust(double adjust); public Q_SLOTS: void onDragFinished(QPointF pos, int index); @@ -153,6 +155,9 @@ protected: QGIView* m_parentItem; QGIPrimPath* m_ghost; + + double m_startAdj; + double m_endAdj; }; } diff --git a/src/Mod/TechDraw/Gui/QGIArrow.cpp b/src/Mod/TechDraw/Gui/QGIArrow.cpp index dd7ed0e792..8c56c6ede3 100644 --- a/src/Mod/TechDraw/Gui/QGIArrow.cpp +++ b/src/Mod/TechDraw/Gui/QGIArrow.cpp @@ -277,7 +277,39 @@ double QGIArrow::getPrefArrowSize() return style; } - +double QGIArrow::getOverlapAdjust(int style, double size) +{ + // adjustment required depends on arrow size and type! :( + // ex for fork and tick, adjustment sb zero. 0.25 is good for filled triangle, 0.1 for open arrow. + // open circle sb = radius + // NOTE: this may need to be adjusted to account for line thickness too. +// Base::Console().Message("QGIA::getOverlapAdjust(%d, %.3f) \n",style, size); + double result = 1.0; + switch(style) { + case 0: //filled triangle + result = 0.50 * size; + break; + case 1: //open arrow + result = 0.10 * size; + break; + case 2: //hash mark + result = 0.0; + break; + case 3: //dot + result = 0.0; + break; + case 4: //open circle + //diameter is size/2 so radius is size/4 + result = 0.25 * size; + break; + case 5: //fork + result = 0.0; + break; + default: //unknown + result = 1.0; + } + return result; +} void QGIArrow::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { diff --git a/src/Mod/TechDraw/Gui/QGIArrow.h b/src/Mod/TechDraw/Gui/QGIArrow.h index 714f288142..7c5215a1d7 100644 --- a/src/Mod/TechDraw/Gui/QGIArrow.h +++ b/src/Mod/TechDraw/Gui/QGIArrow.h @@ -57,6 +57,7 @@ public: void setDirection(Base::Vector3d v) { m_dir = v; } static int getPrefArrowStyle(); static double getPrefArrowSize(); + static double getOverlapAdjust(int style, double size); virtual void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 ); diff --git a/src/Mod/TechDraw/Gui/QGILeaderLine.cpp b/src/Mod/TechDraw/Gui/QGILeaderLine.cpp index e171939c4e..df32a37375 100644 --- a/src/Mod/TechDraw/Gui/QGILeaderLine.cpp +++ b/src/Mod/TechDraw/Gui/QGILeaderLine.cpp @@ -375,6 +375,15 @@ void QGILeaderLine::draw() m_line->setNormalColor(m_lineColor); scale = getScale(); m_line->setScale(scale); + if (leadFeat->StartSymbol.getValue() > -1) { + m_line->setStartAdjust(QGIArrow::getOverlapAdjust(leadFeat->StartSymbol.getValue(), + QGIArrow::getPrefArrowSize())); + } + if (leadFeat->EndSymbol.getValue() > -1) { + m_line->setEndAdjust(QGIArrow::getOverlapAdjust(leadFeat->EndSymbol.getValue(), + QGIArrow::getPrefArrowSize())); + } + m_line->makeDeltasFromPoints(qPoints); m_line->setPos(0,0); m_line->updatePath(); diff --git a/src/Mod/TechDraw/Gui/QGISectionLine.cpp b/src/Mod/TechDraw/Gui/QGISectionLine.cpp index 916353df84..bbd187e76e 100644 --- a/src/Mod/TechDraw/Gui/QGISectionLine.cpp +++ b/src/Mod/TechDraw/Gui/QGISectionLine.cpp @@ -78,39 +78,35 @@ void QGISectionLine::draw() void QGISectionLine::makeLine() { QPainterPath pp; - QPointF beginExtLineStart,beginExtLineEnd; //ext line start pts for measure Start side and measure End side - QPointF endExtLineStart, endExtLineEnd; - QPointF offset(m_arrowDir.x,-m_arrowDir.y); - double arrowLen2 = 2.0 * Rez::guiX(QGIArrow::getPrefArrowSize()); + QPointF beginExtLine1,beginExtLine2; //ext line start pts for measure Start side and measure End side + QPointF endExtLine1, endExtLine2; + QPointF offsetDir(m_arrowDir.x,-m_arrowDir.y); int format = getPrefSectionFormat(); if (format == 0) { //"ASME" - //draw from section line endpoint to just short of arrow tip - QPointF offsetBegin = m_extLen * offset; - beginExtLineStart = m_start; - beginExtLineEnd = m_end; - endExtLineStart = m_start + offsetBegin; - endExtLineEnd = m_end + offsetBegin; - pp.moveTo(beginExtLineStart); - pp.lineTo(endExtLineStart); - pp.moveTo(beginExtLineEnd); - pp.lineTo(endExtLineEnd); + //draw from section line endpoint + QPointF offsetBegin = m_extLen * offsetDir; + beginExtLine1 = m_start; //from + beginExtLine2 = m_end; //to + endExtLine1 = m_start + offsetBegin; + endExtLine2 = m_end + offsetBegin; + pp.moveTo(beginExtLine1); + pp.lineTo(endExtLine1); + pp.moveTo(beginExtLine2); + pp.lineTo(endExtLine2); } else { //"ISO" - //draw from extension line end to just short of section line - QPointF offsetBegin = arrowLen2 * offset; - QPointF offsetEnd = (arrowLen2 - m_extLen) * offset; - beginExtLineStart = m_start - offsetBegin; - beginExtLineEnd = m_end - offsetBegin; - endExtLineStart = m_start - offsetEnd; - endExtLineEnd = m_end - offsetEnd; - pp.moveTo(beginExtLineStart); - pp.lineTo(endExtLineStart); - pp.moveTo(beginExtLineEnd); - pp.lineTo(endExtLineEnd); + //draw from just short of section line away from section line + QPointF offsetBegin = Rez::guiX(QGIArrow::getOverlapAdjust(0,QGIArrow::getPrefArrowSize())) * offsetDir; + QPointF offsetEnd = offsetBegin + (m_extLen * offsetDir); + beginExtLine1 = m_start - offsetBegin; + beginExtLine2 = m_end - offsetBegin; + endExtLine1 = m_start - offsetEnd; + endExtLine2 = m_end - offsetEnd; + pp.moveTo(beginExtLine1); + pp.lineTo(endExtLine1); + pp.moveTo(beginExtLine2); + pp.lineTo(endExtLine2); } -// pp.moveTo(beginExtLineStart); -// pp.lineTo(m_start); //arrow line -// pp.moveTo(beginExtLineEnd); pp.moveTo(m_end); pp.lineTo(m_start); //sectionLine m_line->setPath(pp); @@ -125,6 +121,7 @@ void QGISectionLine::makeArrows() makeArrowsISO(); } } + //make Euro (ISO) Arrows void QGISectionLine::makeArrowsISO() { @@ -136,12 +133,6 @@ void QGISectionLine::makeArrowsISO() } arrowRotation = 360.0 - angle * (180.0/M_PI); //convert to Qt rotation (clockwise degrees) - QPointF extLineStart,extLineEnd; - QPointF offset(m_arrowDir.x,-m_arrowDir.y); //remember Y dir is flipped - offset = (m_extLen + (2.0 * QGIArrow::getPrefArrowSize())) * offset * -1.0; - extLineStart = m_start + offset; - extLineEnd = m_end + offset; - m_arrow1->setStyle(0); m_arrow1->setSize(QGIArrow::getPrefArrowSize()); m_arrow1->setPos(m_start); @@ -166,21 +157,22 @@ void QGISectionLine::makeArrowsTrad() } arrowRotation = 360.0 - angle * (180.0/M_PI); //convert to Qt rotation (clockwise degrees) - QPointF extLineStart,extLineEnd; - QPointF offset(m_arrowDir.x,-m_arrowDir.y); //remember Y dir is flipped - offset = (m_extLen + (2.0 * QGIArrow::getPrefArrowSize())) * offset; - extLineStart = m_start + offset; - extLineEnd = m_end + offset; + QPointF posArrow1,posArrow2; + QPointF offsetDir(m_arrowDir.x,-m_arrowDir.y); //remember Y dir is flipped + double offsetLength = m_extLen + Rez::guiX(QGIArrow::getOverlapAdjust(0,QGIArrow::getPrefArrowSize())); + QPointF offsetVec = offsetLength * offsetDir; + posArrow1 = m_start + offsetVec; + posArrow2 = m_end + offsetVec; m_arrow1->setStyle(0); m_arrow1->setSize(QGIArrow::getPrefArrowSize()); - m_arrow1->setPos(extLineStart); + m_arrow1->setPos(posArrow1); m_arrow1->draw(); m_arrow1->setRotation(arrowRotation); //rotation = 0 ==> -> horizontal, pointing right m_arrow2->setStyle(0); m_arrow2->setSize(QGIArrow::getPrefArrowSize()); - m_arrow2->setPos(extLineEnd); + m_arrow2->setPos(posArrow2); m_arrow2->draw(); m_arrow2->setRotation(arrowRotation); } diff --git a/src/Mod/TechDraw/Gui/QGISectionLine.h b/src/Mod/TechDraw/Gui/QGISectionLine.h index 2e167ca88d..a174bb3c62 100644 --- a/src/Mod/TechDraw/Gui/QGISectionLine.h +++ b/src/Mod/TechDraw/Gui/QGISectionLine.h @@ -76,8 +76,8 @@ private: QGIArrow* m_arrow2; QGCustomText* m_symbol1; QGCustomText* m_symbol2; - QPointF m_start; - QPointF m_end; + QPointF m_start; //start of section line + QPointF m_end; //end of section line Base::Vector3d m_arrowDir; std::string m_symFontName; QFont m_symFont; diff --git a/src/Mod/TechDraw/Gui/QGIView.cpp b/src/Mod/TechDraw/Gui/QGIView.cpp index f289df3cea..0163478458 100644 --- a/src/Mod/TechDraw/Gui/QGIView.cpp +++ b/src/Mod/TechDraw/Gui/QGIView.cpp @@ -681,6 +681,13 @@ double QGIView::getPrefFontSize() return hGrp->GetFloat("LabelSize", DefaultFontSizeInMM); } +double QGIView::getDimFontSize() +{ + Base::Reference hGrp = App::GetApplication().GetUserParameter(). + GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/TechDraw/Dimensions"); + return hGrp->GetFloat("FontSize", DefaultFontSizeInMM); +} + double QGIView::calculateFontPointSizeF(const QGraphicsItem *item, double sizeInMillimetres) { const QWidget *widget = MDIViewPage::getFromScene(item->scene()); diff --git a/src/Mod/TechDraw/Gui/QGIView.h b/src/Mod/TechDraw/Gui/QGIView.h index b4975eb59f..50fb0a0d96 100644 --- a/src/Mod/TechDraw/Gui/QGIView.h +++ b/src/Mod/TechDraw/Gui/QGIView.h @@ -137,6 +137,7 @@ protected: QString getPrefFont(void); double getPrefFontSize(void); + double getDimFontSize(void); double calculateFontPointSizeF(double sizeInMillimetres) const; Base::Reference getParmGroupCol(void); diff --git a/src/Mod/TechDraw/Gui/QGIViewDimension.cpp b/src/Mod/TechDraw/Gui/QGIViewDimension.cpp index 498752750b..fa5caf1ac5 100644 --- a/src/Mod/TechDraw/Gui/QGIViewDimension.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewDimension.cpp @@ -557,6 +557,7 @@ void QGIViewDimension::draw() dirDim = Base::Vector3d (0, 1, 0); normDim = Base::Vector3d (-1, 0, 0); } + Base::Vector3d adjustDir = dirDim; //adjust line lengths for arrowheads //for ortho drawing extension lines are para to normDim, perp to dirDist dirExt = normDim; //dirExt is para or anti-parallel to real extension direction @@ -674,6 +675,7 @@ void QGIViewDimension::draw() Base::Vector3d a1Dir = -dirDim; Base::Vector3d a2Dir = dirDim; if (strcmp(dimType, "DistanceY") == 0 ) { + adjustDir = -adjustDir; a1Dir = Base::Vector3d(0,1,0); a2Dir = Base::Vector3d(0,-1,0); } @@ -687,11 +689,12 @@ void QGIViewDimension::draw() double lblWidth = datumLabel->boundingRect().width(); if ((DrawUtil::isBetween(fauxCenter, dim1Tip, dim2Tip)) && (lblWidth > dimSpan) ) { + adjustDir = -adjustDir; if (strcmp(dimType, "DistanceY") == 0 ) { a1Dir = Base::Vector3d(0,-1,0); a2Dir = Base::Vector3d(0,1,0); - dim1Tail = dim1Tip; - dim2Tail = dim2Tip; + dim1Tail = dim1Tip + dirDim * tailLength; + dim2Tail = dim2Tip - dirDim * tailLength; } else { dim1Tail = dim1Tip - tailLength * dirDim; dim2Tail = dim2Tip + tailLength * dirDim; @@ -702,6 +705,7 @@ void QGIViewDimension::draw() if (!DrawUtil::isBetween(fauxCenter, dim1Tip, dim2Tip)) { //case3 - outerPlacement + adjustDir = -adjustDir; if (strcmp(dimType, "DistanceY") == 0 ) { a1Dir = Base::Vector3d(0,-1,0); a2Dir = Base::Vector3d(0,1,0); @@ -721,7 +725,7 @@ void QGIViewDimension::draw() // Extension lines QPainterPath path; - Base::Vector3d gap = startDist + dirExtActual * (margin * scaler); //space ext line a bt + Base::Vector3d gap = startDist + dirExtActual * (margin * scaler); //space ext line a bit path.moveTo(gap.x, gap.y); path.lineTo(extStartEnd.x, extStartEnd.y); @@ -730,11 +734,15 @@ void QGIViewDimension::draw() path.lineTo(extEndEnd.x, extEndEnd.y); //Dimension lines (arrow shafts) - //TODO: line tip goes just a bit too far. overlaps the arrowhead's point. - path.moveTo(dim1Tip.x, dim1Tip.y); + adjustDir.Normalize(); + double dimLineAdjust = Rez::guiX(QGIArrow::getOverlapAdjust(QGIArrow::getPrefArrowStyle(), + QGIArrow::getPrefArrowSize())); + Base::Vector3d adjustedTip = dim1Tip + adjustDir * dimLineAdjust; + path.moveTo(adjustedTip.x, adjustedTip.y); path.lineTo(dim1Tail.x, dim1Tail.y); - path.moveTo(dim2Tip.x, dim2Tip.y); + adjustedTip = dim2Tip - adjustDir * dimLineAdjust; + path.moveTo(adjustedTip.x, adjustedTip.y); path.lineTo(dim2Tail.x, dim2Tail.y); dimLines->setPath(path); @@ -749,7 +757,6 @@ void QGIViewDimension::draw() datumLabel->setRotation(-90.0 + angleOption); } - aHead1->setDirMode(true); aHead2->setDirMode(true); @@ -797,11 +804,16 @@ void QGIViewDimension::draw() dirDim = Base::Vector3d(1.0,0.0,0.0); } dirDim.Normalize(); + Base::Vector3d adjustDir = dirDim; //adjust line lengths for arrowheads Base::Vector3d fauxCenter = lblCenter; //default arrow endpoints + double dimLineAdjust = Rez::guiX(QGIArrow::getOverlapAdjust(QGIArrow::getPrefArrowStyle(), + QGIArrow::getPrefArrowSize())); arrow1Tip = curveCenter - dirDim * radius; + Base::Vector3d adjustedTip1 = arrow1Tip - adjustDir * dimLineAdjust; arrow2Tip = curveCenter + dirDim * radius; + Base::Vector3d adjustedTip2 = arrow2Tip + adjustDir * dimLineAdjust; arrow1Tail = curveCenter; arrow2Tail = curveCenter; @@ -828,25 +840,29 @@ void QGIViewDimension::draw() int posMode = NoSnap; bool isLeader = false; QPainterPath path; + if(outerPlacement) { Base::Vector3d v = (lblCenter - curveCenter); double angle = atan2(v.y, v.x); double tolerance = 15.0; //deg tolerance *= M_PI / 180; - if( (angle > -tolerance && angle < tolerance) || //angle = 0 or 180 (+/- 15) - (angle > (M_PI - tolerance) || angle < (-M_PI + tolerance)) ) { //dim line is Horizontal + if( (angle > -tolerance && angle < tolerance) || //angle = 0 or 180 (+/- 15) + (angle > (M_PI - tolerance) || angle < (-M_PI + tolerance)) ) { //dim line is Horizontal posMode = HorizontalSnap; - } else if( (angle < ( M_PI / 2. + tolerance) && angle > ( M_PI / 2. - tolerance)) || //angle = 90 or 270 (+/- 15) - (angle < (-M_PI / 2. + tolerance) && angle > (-M_PI / 2. - tolerance)) ) { //dim line is Vertical + } else if( (angle < ( M_PI / 2. + tolerance) && angle > ( M_PI / 2. - tolerance)) || //angle 90/270 + (angle < (-M_PI / 2. + tolerance) && angle > (-M_PI / 2. - tolerance)) ) { //Vertical posMode = VerticalSnap; } -// fauxCenter = Base::Vector3d(lblCenter.x,lblCenter.y + vertOffset,lblCenter.z); +//NOTE: VerticalSnap and Horizontal snap are confusing names. +// VerticalSnap => dim line is horizontal, dim text is directly above/below center +// HorizontalSnap => dim line is vertical, dim text is directly left/right of center. + if(posMode == VerticalSnap) { QRectF mappedRect = mapRectFromItem(datumLabel, datumLabel->boundingRect()); lblCenter = Base::Vector3d(mappedRect.center().x(), mappedRect.center().y(), 0.0); - if (lblCenter.y > curveCenter.y) { // + if (lblCenter.y > curveCenter.y) { fauxCenter = Base::Vector3d(lblCenter.x,lblCenter.y + vertOffset,lblCenter.z); } else { fauxCenter = Base::Vector3d(lblCenter.x,lblCenter.y + vertOffset,lblCenter.z); @@ -854,21 +870,27 @@ void QGIViewDimension::draw() gap = -gap; } - arrow1Tip.x = curveCenter.x - radius; //to left, on circle cl + arrow1Tip.x = curveCenter.x - radius; //to left, on circle cl arrow1Tip.y = fauxCenter.y; arrow1Tail.x = curveCenter.x; arrow1Tail.y = arrow1Tip.y; arrow1Dir = (arrow1Tip - arrow1Tail).Normalize(); + + adjustedTip1.x = arrow1Tip.x + dimLineAdjust; + adjustedTip1.y = arrow1Tip.y; path.moveTo(arrow1Tail.x, arrow1Tail.y); - path.lineTo(arrow1Tip.x, arrow1Tip.y); + path.lineTo(adjustedTip1.x, adjustedTip1.y); arrow2Tip.x = curveCenter.x + radius; arrow2Tip.y = fauxCenter.y; arrow2Tail.x = curveCenter.x; arrow2Tail.y = arrow2Tip.y; arrow2Dir = (arrow2Tip - arrow2Tail).Normalize(); + + adjustedTip2.x = arrow2Tip.x - dimLineAdjust; + adjustedTip2.y = arrow2Tip.y; path.moveTo(arrow2Tail.x, arrow2Tail.y); - path.lineTo(arrow2Tip.x, arrow2Tip.y); + path.lineTo(adjustedTip2.x, adjustedTip2.y); startExt1.x = curveCenter.x - radius; startExt1.y = curveCenter.y + gap; @@ -893,13 +915,13 @@ void QGIViewDimension::draw() lblCenter = Base::Vector3d(mappedRect.center().x(), mappedRect.center().y(), 0.0); if (lblCenter.x > curveCenter.x) { //label right -// fauxCenter = Base::Vector3d(lblCenter.x - horizOffset,lblCenter.y,lblCenter.z); //unidirection convention +// fauxCenter = Base::Vector3d(lblCenter.x - horizOffset,lblCenter.y,lblCenter.z); //uniform convention fauxCenter = Base::Vector3d(lblCenter.x + vertOffset,lblCenter.y,lblCenter.z); //aligned convention } else { //label left tip = -tip; gap = -gap; -// fauxCenter = Base::Vector3d(lblCenter.x + horizOffset,lblCenter.y,lblCenter.z); - fauxCenter = Base::Vector3d(lblCenter.x + vertOffset,lblCenter.y,lblCenter.z); +// fauxCenter = Base::Vector3d(lblCenter.x + horizOffset,lblCenter.y,lblCenter.z); //uniform + fauxCenter = Base::Vector3d(lblCenter.x + vertOffset,lblCenter.y,lblCenter.z); //aligned } arrow1Tip.x = fauxCenter.x; @@ -907,16 +929,22 @@ void QGIViewDimension::draw() arrow1Tail.x = arrow1Tip.x; arrow1Tail.y = curveCenter.y; arrow1Dir = (arrow1Tip - arrow1Tail).Normalize(); + + adjustedTip1.x = arrow1Tip.x; + adjustedTip1.y = arrow1Tip.y + dimLineAdjust; path.moveTo(arrow1Tail.x, arrow1Tail.y); - path.lineTo(arrow1Tip.x, arrow1Tip.y); + path.lineTo(adjustedTip1.x, adjustedTip1.y); arrow2Tip.x = fauxCenter.x; arrow2Tip.y = curveCenter.y + radius; arrow2Tail.x = arrow2Tip.x; arrow2Tail.y = curveCenter.y; arrow2Dir = (arrow2Tip - arrow2Tail).Normalize(); + + adjustedTip2.x = arrow2Tip.x; + adjustedTip2.y = arrow2Tip.y - dimLineAdjust; path.moveTo(arrow2Tail.x, arrow2Tail.y); - path.lineTo(arrow2Tip.x, arrow2Tip.y); + path.lineTo(adjustedTip2.x, adjustedTip2.y); startExt1.x = curveCenter.x + gap; startExt1.y = curveCenter.y - radius; @@ -937,7 +965,7 @@ void QGIViewDimension::draw() datumLabel->setRotation(-90.0); //aligned convention // datumLabel->setRotation(0.0); //unidirectional convention - } else { //outer placement, NoSnap + } else { //outer placement, NoSnap (leader type) QRectF mappedRect = mapRectFromItem(datumLabel, datumLabel->boundingRect()); lblCenter = Base::Vector3d(mappedRect.center().x(), mappedRect.center().y(), 0.0); isLeader = true; @@ -949,15 +977,15 @@ void QGIViewDimension::draw() kinkPoint.x += (lblCenter.x < curveCenter.x) ? margin : - margin; arrow1Tip = curveCenter + (kinkPoint - curveCenter).Normalize() * radius; - + adjustedTip1 = arrow1Tip + (kinkPoint - curveCenter).Normalize() * dimLineAdjust; path.moveTo(arrow1Tail.x, arrow1Tail.y); path.lineTo(kinkPoint.x, kinkPoint.y); + path.lineTo(adjustedTip1.x, adjustedTip1.y); - path.lineTo(arrow1Tip.x, arrow1Tip.y); arrow1Dir = (arrow1Tip - kinkPoint).Normalize(); datumLabel->setRotation(0.); } - } else { //NOT outerplacement ie dimLines are inside circle + } else { //NOT outerplacement ie dimLines are inside circle double vertOffset = getDefaultTextVerticalOffset(); Base::Vector3d dirLabel = lblCenter - curveCenter; @@ -986,17 +1014,20 @@ void QGIViewDimension::draw() dirDim = Base::Vector3d(cos(labelAngle), sin(labelAngle), 0.0); arrow1Tip = curveCenter - dirDim * radius; + adjustedTip1 = arrow1Tip + dirDim * dimLineAdjust; arrow1Tail = curveCenter; arrow1Dir = (arrow1Tip - arrow1Tail).Normalize(); + arrow2Tip = curveCenter + dirDim * radius; + adjustedTip2 = arrow2Tip - dirDim * dimLineAdjust; arrow2Tail = curveCenter; arrow2Dir = (arrow2Tip - arrow2Tail).Normalize(); path.moveTo(arrow1Tail.x, arrow1Tail.y); - path.lineTo(arrow1Tip.x, arrow1Tip.y); + path.lineTo(adjustedTip1.x, adjustedTip1.y); path.moveTo(arrow2Tail.x, arrow2Tail.y); - path.lineTo(arrow2Tip.x, arrow2Tip.y); + path.lineTo(adjustedTip2.x, adjustedTip2.y); } aHead1->setStyle(QGIArrow::getPrefArrowStyle()); @@ -1015,41 +1046,29 @@ void QGIViewDimension::draw() double kinkLength = Rez::guiX(5.0); //sb % of horizontal dist(lblCenter,curveCenter)??? QPainterPath arcPath; if (isArc) { + arrow1Tail = lblCenter; + arrow1Tail.x += horizOffset; + Base::Vector3d kinkPoint = arrow1Tail; + kinkPoint.x += (lblCenter.x < curveCenter.x) ? margin : - margin; if (lblCenter.x > curveCenter.x) { // label to right of vert c/l - fauxCenter = Base::Vector3d(lblCenter.x - horizOffset,lblCenter.y,lblCenter.z); - kinkPoint = Base::Vector3d(fauxCenter.x - kinkLength,fauxCenter.y,fauxCenter.z); + dLineStart = Base::Vector3d(lblCenter.x + horizOffset,lblCenter.y,lblCenter.z); + kinkPoint = Base::Vector3d(dLineStart.x - kinkLength,dLineStart.y,dLineStart.z); } else { tip = -tip; gap = -gap; - fauxCenter = Base::Vector3d(lblCenter.x + horizOffset,lblCenter.y,lblCenter.z); - kinkPoint = Base::Vector3d(fauxCenter.x + kinkLength,fauxCenter.y,fauxCenter.z); + dLineStart = Base::Vector3d(lblCenter.x + horizOffset,lblCenter.y,lblCenter.z); + kinkPoint = Base::Vector3d(dLineStart.x + kinkLength,dLineStart.y,dLineStart.z); } dirDim = (kinkPoint - curveCenter).Normalize(); pointOnCurve = curveCenter + (dirDim * radius); - Base::Vector3d startPt = Rez::guiX(pts.arcEnds.first); - Base::Vector3d endPt = Rez::guiX(pts.arcEnds.second); - if (!dim->leaderIntersectsArc(Rez::appX(kinkPoint),Rez::appX(pointOnCurve))) { //keep point within arc - if ((pointOnCurve - endPt).Length() < (pointOnCurve - startPt).Length()) { - if (!pts.arcCW ) { - pointOnCurve = endPt; - } else { - pointOnCurve = startPt; - } - } else { - if (!pts.arcCW) { - pointOnCurve = startPt; - } else { - pointOnCurve = endPt; - } - } - } - arcPath.moveTo(fauxCenter.x,fauxCenter.y); + pointOnCurve = Rez::guiX(pts.midArc); + adjustedTip1 = pointOnCurve + (dirDim * dimLineAdjust); + arcPath.moveTo(dLineStart.x,dLineStart.y); arcPath.lineTo(kinkPoint.x,kinkPoint.y); - arcPath.lineTo(pointOnCurve.x,pointOnCurve.y); - arrow1Dir = (pointOnCurve - kinkPoint).Normalize(); + arcPath.lineTo(adjustedTip1.x,adjustedTip1.y); + arrow1Dir = (arrow1Tip - kinkPoint).Normalize(); datumLabel->setRotation(0.); } - dimLines->setPath(path); if (isArc) { @@ -1078,7 +1097,7 @@ void QGIViewDimension::draw() aHead1->setDirection(arrow1Dir); aHead1->draw(); aHead1->show(); - aHead2->hide(); //only 1 arrowhead for NoSnap + outerplacement (ie a leader) + aHead2->hide(); //only 1 arrowhead for NoSnap + outerplacement (ie a leader) } } else { //inner placement aHead1->setPos(arrow1Tip.x, arrow1Tip.y); @@ -1093,6 +1112,7 @@ void QGIViewDimension::draw() aHead2->show(); } +// code for centerMark being attribute of Dim instead of View // if (dim->CentreLines.getValue()) { // curveCenterMark->setPos(curveCenter.x,curveCenter.y); // centerMark->show(); @@ -1128,27 +1148,34 @@ void QGIViewDimension::draw() if (fabs(dirDimLine.Length()) < (Precision::Confusion())) { dirDimLine = Base::Vector3d(-1.0,0.0,0.0); } +// Base::Vector3d adjustDir = dirDimLine; //adjust line lengths for arrowheads + double dimLineAdjust = Rez::guiX(QGIArrow::getOverlapAdjust(QGIArrow::getPrefArrowStyle(), + QGIArrow::getPrefArrowSize())); + Base::Vector3d dLineStart; + Base::Vector3d dLineEnd; //?? radius draws line from text to curve?? (diam is curve to text!) Base::Vector3d kinkPoint; margin = Rez::guiX(5.f); //space around label - double kinkLength = Rez::guiX(5.0); //sb % of horizontal dist(lblCenter,curveCenter)??? + double kinkLength = Rez::guiX(5.0); //sb % of horizontal dist(lblCenter,curveCenter)??? if (outerPlacement) { double offset = getDefaultTextHorizontalOffset(lblCenter.x > curveCenter.x); dLineStart.y = lblCenter.y; - dLineStart.x = lblCenter.x + offset; //start at right or left of label + dLineStart.x = lblCenter.x + offset; //start at right or left of label kinkLength = (lblCenter.x < curveCenter.x) ? kinkLength : -kinkLength; kinkPoint.y = dLineStart.y; kinkPoint.x = dLineStart.x + kinkLength; pointOnCurve = curveCenter + (kinkPoint - curveCenter).Normalize() * radius; + dLineEnd = pointOnCurve + (kinkPoint - curveCenter).Normalize() * dimLineAdjust; if ((kinkPoint - curveCenter).Length() < radius) { dirDimLine = (curveCenter - kinkPoint).Normalize(); } else { dirDimLine = (kinkPoint - curveCenter).Normalize(); } - } else { + } else { dLineStart = curveCenter - dirDimLine * margin; //just beyond centerpoint pointOnCurve = curveCenter - dirDimLine * radius; + dLineEnd = pointOnCurve + dirDimLine * dimLineAdjust; kinkPoint = dLineStart; //no kink } @@ -1166,6 +1193,7 @@ void QGIViewDimension::draw() } dLineStart = curveCenter + dirDimLine * margin; pointOnCurve = curveCenter + dirDimLine * radius; + dLineEnd = pointOnCurve - dirDimLine * dimLineAdjust; kinkPoint = dLineStart; if (!dim->leaderIntersectsArc(Rez::appX(dLineStart),Rez::appX(pointOnCurve))) { //keep pathological case within arc if ((pointOnCurve - endPt).Length() < (pointOnCurve - startPt).Length()) { @@ -1182,6 +1210,7 @@ void QGIViewDimension::draw() } } dLineStart = curveCenter + (pointOnCurve - curveCenter).Normalize() * margin; + dLineEnd = pointOnCurve - dirDimLine * dimLineAdjust; kinkPoint = dLineStart; } } @@ -1190,10 +1219,10 @@ void QGIViewDimension::draw() QPainterPath dLinePath; //radius dimension line path dLinePath.moveTo(dLineStart.x, dLineStart.y); dLinePath.lineTo(kinkPoint.x, kinkPoint.y); - dLinePath.lineTo(pointOnCurve.x, pointOnCurve.y); + dLinePath.lineTo(dLineEnd.x, dLineEnd.y); dimLines->setPath(dLinePath); - + //NOTE: in this case aHead1->dirMode is false and Qt rotation is used to point arrowhead aHead1->setStyle(QGIArrow::getPrefArrowStyle()); aHead1->setSize(QGIArrow::getPrefArrowSize()); aHead1->draw(); @@ -1239,6 +1268,8 @@ void QGIViewDimension::draw() ccwInner = false; } + double dimLineAdjust = Rez::guiX(QGIArrow::getOverlapAdjust(QGIArrow::getPrefArrowStyle(), + QGIArrow::getPrefArrowSize())); QRectF mappedRect = mapRectFromItem(datumLabel, datumLabel->boundingRect()); lblCenter = Base::Vector3d(mappedRect.center().x(), mappedRect.center().y(), 0.0); @@ -1249,7 +1280,9 @@ void QGIViewDimension::draw() QRectF arcRect(vertex.x - radius, vertex.y - radius, 2. * radius, 2. * radius); Base::Vector3d ar0Pos = vertex + d0 * radius; +// Base::Vector3d adjustedTip0 = ar0Pos - d0 * dimLineAdjust; Base::Vector3d ar1Pos = vertex + d1 * radius; +// Base::Vector3d adjustedTip1 = ar1Pos - d1 * dimLineAdjust; double startangle = atan2(dir0.y,dir0.x); if (startangle < 0) { @@ -1298,6 +1331,8 @@ void QGIViewDimension::draw() isOutside = false; } + //dim line (arc) calculation is very different here. + //TODO: make arc a bit shorter to not overlap arrowheads. ends +/- x degrees. path.arcMoveTo(arcRect, startangle * 180 / M_PI); double actualSweep = 0.0; m_obtuse = false; @@ -1319,10 +1354,7 @@ void QGIViewDimension::draw() dimLines->setPath(path); -// aHead1->setDirMode(true); -// aHead2->setDirMode(true); -// aHead1->setDirection(a1Dir); -// aHead2->setDirection(a2Dir); + //NOTE: arrowheads are dirMode(false) aHead1->flip(true); aHead1->setStyle(QGIArrow::getPrefArrowStyle()); aHead1->setSize(QGIArrow::getPrefArrowSize()); @@ -1540,7 +1572,8 @@ double QGIViewDimension::getDefaultTextHorizontalOffset(bool toLeft) const { double offset = datumLabel->boundingRect().width()*0.5 + TextOffsetFudge*2.0; - return toLeft ? -offset - TextOffsetFudge*5.0: offset; +// return toLeft ? -offset - TextOffsetFudge*5.0: offset; + return toLeft ? -offset : offset; } double QGIViewDimension::getDefaultTextVerticalOffset() const diff --git a/src/Mod/TechDraw/Gui/QGIViewPart.cpp b/src/Mod/TechDraw/Gui/QGIViewPart.cpp index e98a385bec..0ec0c2e420 100644 --- a/src/Mod/TechDraw/Gui/QGIViewPart.cpp +++ b/src/Mod/TechDraw/Gui/QGIViewPart.cpp @@ -441,8 +441,8 @@ void QGIViewPart::drawViewPart() } if (showEdge) { item = new QGIEdge(i); - addToGroup(item); //item is at scene(0,0), not group(0,0) - item->setPos(0.0,0.0); //now at group(0,0) + addToGroup(item); //item is at scene(0,0), not group(0,0) + item->setPos(0.0,0.0); //now at group(0,0) item->setPath(drawPainterPath(*itEdge)); item->setWidth(lineWidth); item->setZValue(ZVALUE::EDGE); @@ -691,7 +691,8 @@ void QGIViewPart::drawSectionLine(TechDraw::DrawViewSection* viewSection, bool b double sectionSpan; double sectionFudge = Rez::guiX(10.0); double xVal, yVal; - double fontSize = getPrefFontSize(); +// double fontSize = getPrefFontSize(); + double fontSize = getDimFontSize(); if (horiz) { double width = Rez::guiX(viewPart->getBoxX()); double height = Rez::guiX(viewPart->getBoxY());