Skip to content

Commit

Permalink
[TD]oblique section lines
Browse files Browse the repository at this point in the history
  • Loading branch information
WandererFan committed May 10, 2020
1 parent b3290e0 commit 29c5528
Show file tree
Hide file tree
Showing 7 changed files with 230 additions and 135 deletions.
56 changes: 56 additions & 0 deletions src/Mod/TechDraw/App/DrawUtil.cpp
Expand Up @@ -284,6 +284,62 @@ bool DrawUtil::fpCompare(const double& d1, const double& d2, double tolerance)
return result;
}

//brute force intersection points of line(point, dir) with box(xRange, yRange)
std::pair<Base::Vector3d, Base::Vector3d> DrawUtil::boxIntersect2d(Base::Vector3d point,
Base::Vector3d dirIn,
double xRange,
double yRange)
{
std::pair<Base::Vector3d, Base::Vector3d> result;
Base::Vector3d p1, p2;
Base::Vector3d dir = dirIn;
dir.Normalize();
// y = mx + b
// m = (y1 - y0) / (x1 - x0)
if (DrawUtil::fpCompare(dir.x, 0.0) ) {
p1 = Base::Vector3d(0.0, - yRange / 2.0, 0.0);
p2 = Base::Vector3d(0.0, yRange / 2.0, 0.0);
} else {
double slope = dir.y / dir.x;
double left = -xRange / 2.0;
double right = xRange / 2.0;
double top = yRange / 2.0;
double bottom = -yRange / 2.0;
double yLeft = point.y - slope * (point.x - left) ;
double yRight = point.y - slope * (point.x - right);
double xTop = point.x - ( (point.y - top) / slope );
double xBottom = point.x - ( (point.y - bottom) / slope );

if ( (bottom < yLeft) &&
(top > yLeft) ) {
p1 = Base::Vector3d(left, yLeft);
} else if (yLeft <= bottom) {
p1 = Base::Vector3d(xBottom, bottom);
} else if (yLeft >= top) {
p1 = Base::Vector3d(xTop, top);
}

if ( (bottom < yRight) &&
(top > yRight) ) {
p2 = Base::Vector3d(right, yRight);
} else if (yRight <= bottom) {
p2 = Base::Vector3d(xBottom, bottom);
} else if (yRight >= top) {
p2 = Base::Vector3d(xTop, top);
}
}
result.first = p1;
result.second = p2;
Base::Vector3d dirCheck = p2 - p1;
dirCheck.Normalize();
if (!dir.IsEqual(dirCheck, 0.00001)) {
result.first = p2;
result.second = p1;
}

return result;
}

Base::Vector3d DrawUtil::vertex2Vector(const TopoDS_Vertex& v)
{
gp_Pnt gp = BRep_Tool::Pnt(v);
Expand Down
4 changes: 4 additions & 0 deletions src/Mod/TechDraw/App/DrawUtil.h
Expand Up @@ -79,6 +79,10 @@ class TechDrawExport DrawUtil {
static bool isFirstVert(TopoDS_Edge e, TopoDS_Vertex v, double tolerance = VERTEXTOLERANCE);
static bool isLastVert(TopoDS_Edge e, TopoDS_Vertex v, double tolerance = VERTEXTOLERANCE);
static bool fpCompare(const double& d1, const double& d2, double tolerance = FLT_EPSILON);
static std::pair<Base::Vector3d, Base::Vector3d> boxIntersect2d(Base::Vector3d point,
Base::Vector3d dir,
double xRange,
double yRange) ;
static Base::Vector3d vertex2Vector(const TopoDS_Vertex& v);
static std::string formatVector(const Base::Vector3d& v);
static std::string formatVector(const gp_Dir& v);
Expand Down
32 changes: 32 additions & 0 deletions src/Mod/TechDraw/App/DrawViewSection.cpp
Expand Up @@ -677,6 +677,38 @@ TopoDS_Face DrawViewSection::projectFace(const TopoDS_Shape &face,
return projectedFace;
}


//calculate the ends of the section line in BaseView's coords
std::pair<Base::Vector3d, Base::Vector3d> DrawViewSection::sectionLineEnds(void)
{
std::pair<Base::Vector3d, Base::Vector3d> result;

auto sNorm = SectionNormal.getValue();
double angle = M_PI / 2.0;
auto axis = getBaseDVP()->Direction.getValue();
Base::Vector3d stdOrg(0.0, 0.0, 0.0);
Base::Vector3d sLineDir = DrawUtil::vecRotate(sNorm, angle, axis, stdOrg);
sLineDir.Normalize();
Base::Vector3d sLineDir2 = - axis.Cross(sNorm);
sLineDir2.Normalize();
Base::Vector3d sLineOnBase = getBaseDVP()->projectPoint(sLineDir2);
sLineOnBase.Normalize();

auto sOrigin = SectionOrigin.getValue();
Base::Vector3d adjSectionOrg = sOrigin - getBaseDVP()->getOriginalCentroid();
Base::Vector3d sOrgOnBase = getBaseDVP()->projectPoint(adjSectionOrg);
sOrgOnBase /= getScale();

auto bbx = getBaseDVP()->getBoundingBox();
double xRange = bbx.MaxX - bbx.MinX;
xRange /= getScale();
double yRange = bbx.MaxY - bbx.MinY;
yRange /= getScale();
result = DrawUtil::boxIntersect2d(sOrgOnBase, sLineOnBase, xRange, yRange);

return result;
}

//this should really be in BoundBox.h
//!check if point is in box or on boundary of box
//!compare to isInBox which doesn't allow on boundary
Expand Down
2 changes: 2 additions & 0 deletions src/Mod/TechDraw/App/DrawViewSection.h
Expand Up @@ -119,6 +119,8 @@ class TechDrawExport DrawViewSection : public DrawViewPart
static const char* SectionDirEnums[];
static const char* CutSurfaceEnums[];

std::pair<Base::Vector3d, Base::Vector3d> sectionLineEnds(void);

protected:
TopoDS_Compound sectionFaces;
std::vector<TopoDS_Wire> sectionFaceWires;
Expand Down
158 changes: 103 additions & 55 deletions src/Mod/TechDraw/Gui/QGISectionLine.cpp
Expand Up @@ -75,6 +75,13 @@ QGISectionLine::QGISectionLine()
void QGISectionLine::draw()
{
prepareGeometryChange();
int format = getPrefSectionStandard();
if (format == ANSISTANDARD) { //"ASME"/"ANSI"
extensionEndsTrad();
} else {
extensionEndsISO();
}

makeLine();
makeArrows();
makeSymbols();
Expand All @@ -84,37 +91,15 @@ void QGISectionLine::draw()
void QGISectionLine::makeLine()
{
QPainterPath pp;
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 = getPrefSectionStandard();
if (format == ANSISTANDARD) { //"ASME"/"ANSI"
//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 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(m_end);
pp.lineTo(m_start); //sectionLine
pp.moveTo(m_beginExt1);
pp.lineTo(m_endExt1);

pp.moveTo(m_beginExt2);
pp.lineTo(m_endExt2);

pp.moveTo(m_start);
pp.lineTo(m_end);
m_line->setPath(pp);
}

Expand Down Expand Up @@ -165,8 +150,14 @@ void QGISectionLine::makeArrowsTrad()

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()));

double oblique = 1.0;
if ( !DrawUtil::fpCompare((m_arrowDir.x + m_arrowDir.y), 1.0) ) {
oblique = 1.25;
}
double offsetLength = (m_extLen * oblique) + Rez::guiX(QGIArrow::getPrefArrowSize());
QPointF offsetVec = offsetLength * offsetDir;

posArrow1 = m_start + offsetVec;
posArrow2 = m_end + offsetVec;

Expand Down Expand Up @@ -195,58 +186,114 @@ void QGISectionLine::makeSymbols()

void QGISectionLine::makeSymbolsTrad()
{
QPointF extLineStart,extLineEnd;
QPointF offset(m_arrowDir.x,-m_arrowDir.y);
offset = 1.5 * m_extLen * offset;
extLineStart = m_start + offset;
extLineEnd = m_end + offset;
prepareGeometryChange();
m_symFont.setPixelSize(QGIView::calculateFontPixelSize(m_symSize));
m_symbol1->setFont(m_symFont);
m_symbol1->setPlainText(QString::fromUtf8(m_symbol));
m_symbol2->setFont(m_symFont);
m_symbol2->setPlainText(QString::fromUtf8(m_symbol));

QRectF symRect = m_symbol1->boundingRect();
double symWidth = symRect.width();
double symHeight = symRect.height();
double symbolFudge = 1.0;
double symbolFudge = 0.75;
double angle = atan2f(m_arrowDir.y,m_arrowDir.x);
if (angle < 0.0) {
angle = 2 * M_PI + angle;
}
Base::Vector3d adjustVector(cos(angle) * symWidth, sin(angle) * symHeight, 0.0);
adjustVector = (DrawUtil::invertY(adjustVector) / 2.0) * symbolFudge;
adjustVector = DrawUtil::invertY(adjustVector) * symbolFudge;
QPointF qAdjust(adjustVector.x, adjustVector.y);

extLineStart += qAdjust;
m_symbol1->centerAt(extLineStart);
QPointF posSymbol1 = m_arrow1->pos() + qAdjust;
m_symbol1->centerAt(posSymbol1);

m_symbol2->setFont(m_symFont);
m_symbol2->setPlainText(QString::fromUtf8(m_symbol));
extLineEnd += qAdjust;
m_symbol2->centerAt(extLineEnd);
QPointF posSymbol2 = m_arrow2->pos() + qAdjust;
m_symbol2->centerAt(posSymbol2);
}

void QGISectionLine::makeSymbolsISO()
{
QPointF symPosStart, symPosEnd;
QPointF dist = (m_start - m_end);
double lenDist = sqrt(dist.x()*dist.x() + dist.y()*dist.y());
QPointF distDir = dist / lenDist;

QPointF offset = m_extLen * distDir;
symPosStart = m_start + offset;
symPosEnd = m_end - offset;

prepareGeometryChange();
m_symFont.setPixelSize(QGIView::calculateFontPixelSize(m_symSize));
m_symbol1->setFont(m_symFont);
m_symbol1->setPlainText(QString::fromUtf8(m_symbol));
m_symbol1->centerAt(symPosStart);

m_symbol2->setFont(m_symFont);
m_symbol2->setPlainText(QString::fromUtf8(m_symbol));

QPointF symPosStart, symPosEnd;
//no normalize() for QPointF
QPointF dist = (m_start - m_end);
double lenDist = sqrt(dist.x()*dist.x() + dist.y()*dist.y());
QPointF offsetDir = dist / lenDist;

QRectF symRect = m_symbol1->boundingRect();
double symWidth = symRect.width();
double symHeight = symRect.height();

double symbolFudge = 0.75;
double angle = atan2f(offsetDir.y(), offsetDir.x());
if (angle < 0.0) {
angle = 2.0 * M_PI + angle;
}
Base::Vector3d adjustVector(cos(angle) * symWidth, sin(angle) * symHeight, 0.0);
adjustVector = adjustVector * symbolFudge;
QPointF qAdjust(adjustVector.x, adjustVector.y);

symPosStart = m_start + qAdjust;
symPosEnd = m_end - qAdjust;

m_symbol1->centerAt(symPosStart);
m_symbol2->centerAt(symPosEnd);
}

void QGISectionLine::extensionEndsTrad()
{
QPointF offsetDir(m_arrowDir.x,-m_arrowDir.y);

//extensions for oblique section line needs to be a bit longer
double oblique = 1.0;
if ( !DrawUtil::fpCompare((m_arrowDir.x + m_arrowDir.y), 1.0) ) {
oblique = 1.25;
}

//draw from section line endpoint
QPointF offsetEnd = oblique * m_extLen * offsetDir;
m_beginExt1 = m_start;
m_endExt1 = m_start + offsetEnd;
m_beginExt2 = m_end;
m_endExt2 = m_end + offsetEnd;
}

void QGISectionLine::extensionEndsISO()
{
//lines are offset to other side of section line!
QPointF offsetDir(m_arrowDir.x,-m_arrowDir.y);
offsetDir = offsetDir * -1.0;

//extensions for oblique section line needs to be a bit longer?
//this is just esthetics
double oblique = 1.0;
if ( !DrawUtil::fpCompare((m_arrowDir.x + m_arrowDir.y), 1.0) ) {
oblique = 1.10;
}

//draw from section line endpoint less arrow length
QPointF offsetStart = offsetDir * Rez::guiX(QGIArrow::getPrefArrowSize());
QPointF offsetEnd = oblique * m_extLen * offsetDir;

m_beginExt1 = m_start + offsetStart;
m_endExt1 = m_start + offsetStart + offsetEnd;
m_beginExt2 = m_end + offsetStart;
m_endExt2 = m_end + offsetStart + offsetEnd;
}

void QGISectionLine::setEnds(Base::Vector3d l1, Base::Vector3d l2)
{
m_l1 = l1;
m_start = QPointF(l1.x, l1.y);
m_l2 = l2;
m_end = QPointF(l2.x, l2.y);
}

void QGISectionLine::setBounds(double x1,double y1,double x2,double y2)
Expand All @@ -269,6 +316,7 @@ void QGISectionLine::setDirection(double xDir,double yDir)
void QGISectionLine::setDirection(Base::Vector3d dir)
{
m_arrowDir = dir;
m_arrowDir.Normalize();
}

void QGISectionLine::setFont(QFont f, double fsize)
Expand Down
10 changes: 10 additions & 0 deletions src/Mod/TechDraw/Gui/QGISectionLine.h
Expand Up @@ -49,6 +49,7 @@ class TechDrawGuiExport QGISectionLine : public QGIDecoration

virtual void paint(QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 );

void setEnds(Base::Vector3d l1, Base::Vector3d l2);
void setBounds(double x1,double y1,double x2,double y2);
void setSymbol(char* sym);
void setDirection(double xDir,double yDir);
Expand All @@ -71,6 +72,9 @@ class TechDrawGuiExport QGISectionLine : public QGIDecoration
void makeSymbolsISO();
void setTools();
int getPrefSectionStandard();
void extensionEndsISO();
void extensionEndsTrad();


private:
char* m_symbol;
Expand All @@ -89,6 +93,12 @@ class TechDrawGuiExport QGISectionLine : public QGIDecoration
//QColor m_color;
double m_extLen;
// int m_sectionFormat; //0 = ASME, 1 = ISO
Base::Vector3d m_l1; //end of main section line
Base::Vector3d m_l2; //end of main section line
QPointF m_beginExt1; //start of extension line 1
QPointF m_endExt1; //end of extension line 1
QPointF m_beginExt2; //start of extension line 2
QPointF m_endExt2; //end of extension line 1
};

}
Expand Down

0 comments on commit 29c5528

Please sign in to comment.