| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | #include <QMouseEvent> |
| |
|
| | #include "lc_actioncontext.h" |
| | #include "lc_containertraverser.h" |
| | #include "lc_crosshair.h" |
| | #include "lc_cursoroverlayinfo.h" |
| | #include "lc_defaults.h" |
| | #include "lc_graphicviewport.h" |
| | #include "lc_linemath.h" |
| | #include "lc_overlayentitiescontainer.h" |
| | #include "rs_debug.h" |
| | #include "rs_graphic.h" |
| | #include "rs_graphicview.h" |
| | #include "rs_grid.h" |
| | #include "rs_math.h" |
| | #include "rs_pen.h" |
| | #include "rs_snapper.h" |
| | #include "rs_settings.h" |
| | #include "rs_units.h" |
| | #include "rs_vector.h" |
| |
|
| | namespace { |
| |
|
| | |
| | bool isPositive(double x){ |
| | return x > RS_TOLERANCE; |
| | } |
| |
|
| | |
| | bool isSizeValid(const RS_Vector& sizeVector) { |
| | return isPositive(sizeVector.x) || isPositive(sizeVector.x); |
| | } |
| |
|
| | |
| | double getValidSize(const RS_Vector& sizeVector){ |
| | return std::hypot(std::max(sizeVector.x, RS_TOLERANCE), std::max(sizeVector.y, RS_TOLERANCE)); |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | RS_SnapMode const & RS_SnapMode::clear(){ |
| | *this = RS_SnapMode{}; |
| |
|
| | return *this; |
| | } |
| |
|
| | bool RS_SnapMode::operator ==(RS_SnapMode const& rhs) const{ |
| | return snapIntersection == rhs.snapIntersection |
| | && snapOnEntity == rhs.snapOnEntity |
| | && snapCenter == rhs.snapCenter |
| | && snapDistance == rhs.snapDistance |
| | && snapMiddle == rhs.snapMiddle |
| | && snapEndpoint == rhs.snapEndpoint |
| | && snapGrid == rhs.snapGrid |
| | && snapFree == rhs.snapFree |
| | && restriction == rhs.restriction |
| | && snapAngle == rhs.snapAngle; |
| | } |
| |
|
| | bool RS_SnapMode::operator !=(RS_SnapMode const& rhs) const{ |
| | return ! this->operator ==(rhs); |
| | } |
| |
|
| | |
| | |
| | |
| | uint RS_SnapMode::toInt(const RS_SnapMode& s){ |
| | uint ret {0}; |
| |
|
| | if (s.snapIntersection) ret |= RS_SnapMode::SnapIntersection; |
| | if (s.snapOnEntity) ret |= RS_SnapMode::SnapOnEntity; |
| | if (s.snapCenter) ret |= RS_SnapMode::SnapCenter; |
| | if (s.snapDistance) ret |= RS_SnapMode::SnapDistance; |
| | if (s.snapMiddle) ret |= RS_SnapMode::SnapMiddle; |
| | if (s.snapEndpoint) ret |= RS_SnapMode::SnapEndpoint; |
| | if (s.snapGrid) ret |= RS_SnapMode::SnapGrid; |
| | if (s.snapFree) ret |= RS_SnapMode::SnapFree; |
| | if (s.snapAngle) ret |= RS_SnapMode::SnapAngle; |
| |
|
| | switch (s.restriction) { |
| | case RS2::RestrictHorizontal: |
| | ret |= RS_SnapMode::RestrictHorizontal; |
| | break; |
| | case RS2::RestrictVertical: |
| | ret |= RS_SnapMode::RestrictVertical; |
| | break; |
| | case RS2::RestrictOrthogonal: |
| | ret |= RS_SnapMode::RestrictOrthogonal; |
| | break; |
| | default: |
| | break; |
| | } |
| |
|
| | return ret; |
| | } |
| |
|
| | |
| | |
| | |
| | RS_SnapMode RS_SnapMode::fromInt(unsigned int ret){ |
| | RS_SnapMode s; |
| |
|
| | if (RS_SnapMode::SnapIntersection & ret) s.snapIntersection = true; |
| | if (RS_SnapMode::SnapOnEntity & ret) s.snapOnEntity = true; |
| | if (RS_SnapMode::SnapCenter & ret) s.snapCenter = true; |
| | if (RS_SnapMode::SnapDistance & ret) s.snapDistance = true; |
| | if (RS_SnapMode::SnapMiddle & ret) s.snapMiddle = true; |
| | if (RS_SnapMode::SnapEndpoint & ret) s.snapEndpoint = true; |
| | if (RS_SnapMode::SnapGrid & ret) s.snapGrid = true; |
| | if (RS_SnapMode::SnapFree & ret) s.snapFree = true; |
| | if (RS_SnapMode::SnapAngle & ret) s.snapAngle = true; |
| |
|
| | switch (RS_SnapMode::RestrictOrthogonal & ret) { |
| | case RS_SnapMode::RestrictHorizontal: |
| | s.restriction = RS2::RestrictHorizontal; |
| | break; |
| | case RS_SnapMode::RestrictVertical: |
| | s.restriction = RS2::RestrictVertical; |
| | break; |
| | case RS_SnapMode::RestrictOrthogonal: |
| | s.restriction = RS2::RestrictOrthogonal; |
| | break; |
| | default: |
| | s.restriction = RS2::RestrictNothing; |
| | break; |
| | } |
| |
|
| | return s; |
| | } |
| |
|
| | |
| | |
| | |
| | struct RS_Snapper::Indicator{ |
| | bool drawLines = false; |
| | int lines_type = 0; |
| | RS_Pen lines_pen; |
| |
|
| | bool drawShape = false; |
| | int shape_type = 0; |
| | RS_Pen shape_pen; |
| | |
| | int pointType = LC_DEFAULTS_PDMode; |
| | int pointSize = LC_DEFAULTS_PDSize; |
| | }; |
| |
|
| | |
| |
|
| | enum SnapType{ |
| | FREE = -1, |
| | GRID, |
| | ENTITY, |
| | ENDPOINT, |
| | INTERSECTION, |
| | MIDDLE, |
| | DISTANCE, |
| | CENTER, |
| | ANGLE, |
| | ANGLE_REL, |
| | ANGLE_ON_ENTITY |
| | }; |
| |
|
| | struct RS_Snapper::ImpData { |
| | RS_Vector snapCoord; |
| | RS_Vector snapSpot; |
| | int snapType = 0; |
| | double angle = 0.; |
| | int restriction = RS2::RestrictNothing; |
| | }; |
| |
|
| | |
| | |
| | |
| | RS_Snapper::RS_Snapper(LC_ActionContext *actionContext) |
| | :m_container(actionContext->getEntityContainer()) |
| | ,m_graphicView(actionContext->getGraphicView()) |
| | ,m_actionContext(actionContext) |
| | ,m_infoCursorOverlayData{std::make_unique<LC_InfoCursorData>()} |
| | ,pImpData(new ImpData), |
| | m_snapIndicator(new Indicator) |
| | { |
| | m_viewport = m_graphicView->getViewPort(); |
| | m_infoCursorOverlayPrefs = m_graphicView->getInfoCursorOverlayPreferences(); |
| | } |
| |
|
| | RS_Snapper::~RS_Snapper() = default; |
| |
|
| |
|
| | |
| | |
| | |
| | void RS_Snapper::init(){ |
| | m_snapMode = m_graphicView->getDefaultSnapMode(); |
| | m_keyEntity = nullptr; |
| | pImpData->snapSpot = RS_Vector{false}; |
| | pImpData->snapCoord = RS_Vector{false}; |
| | m_SnapDistance = 1.0; |
| | initSettings(); |
| | } |
| |
|
| | void RS_Snapper::initSettings() { |
| | initFromSettings(); |
| |
|
| | RS_Graphic* graphic = m_graphicView->getGraphic(); |
| | if (graphic != nullptr) { |
| | initFromGraphic(graphic); |
| | } |
| | } |
| |
|
| | void RS_Snapper::initFromSettings() { |
| | LC_GROUP("Appearance"); |
| | { |
| | int snapIndicatorLineWidth = static_cast<RS2::LineType>(LC_GET_INT("indicator_lines_line_width", 1)); |
| | m_snapIndicator->drawLines = LC_GET_BOOL("indicator_lines_state", true); |
| | if (m_snapIndicator->drawLines){ |
| | m_snapIndicator->lines_type = LC_GET_INT("indicator_lines_type", 0); |
| | RS2::LineType snapIndicatorLineType = static_cast<RS2::LineType>(LC_GET_INT("indicator_lines_line_type", RS2::DashLine)); |
| | QString snap_color_lines = LC_GET_ONE_STR("Colors", "snap_indicator_lines", RS_Settings::snap_indicator_lines); |
| | m_snapIndicator->lines_pen = RS_Pen(RS_Color(snap_color_lines), RS2::Width00, snapIndicatorLineType); |
| | m_snapIndicator->lines_pen.setScreenWidth(snapIndicatorLineWidth); |
| | } |
| | else { |
| | m_snapIndicator->lines_type = LC_Crosshair::NoLines; |
| | } |
| |
|
| | m_snapIndicator->drawShape = LC_GET_BOOL("indicator_shape_state", true); |
| | if (m_snapIndicator->drawShape) { |
| | m_snapIndicator->shape_type = LC_GET_INT("indicator_shape_type", 0); |
| | QString snap_color = LC_GET_ONE_STR("Colors", "snap_indicator", RS_Settings::snap_indicator); |
| | m_snapIndicator->shape_pen = RS_Pen(RS_Color(snap_color), RS2::Width00, RS2::SolidLine); |
| | m_snapIndicator->shape_pen.setScreenWidth(snapIndicatorLineWidth); |
| | } |
| | else{ |
| | m_snapIndicator->shape_type = LC_Crosshair::NoShape; |
| | } |
| |
|
| | m_ignoreSnapToGridIfNoGrid = LC_GET_BOOL("SnapGridIgnoreIfNoGrid", false); |
| |
|
| | } |
| | LC_GROUP_END(); |
| |
|
| | LC_GROUP("Snap"); |
| | { |
| | m_distanceBeforeSwitchToFreeSnap = LC_GET_INT("AdvSnapOnEntitySwitchToFreeDistance", 500) / 100.0; |
| | m_catchEntityGuiRange = LC_GET_INT("AdvSnapEntityCatchRange", 32); |
| | m_minGridCellSnapFactor = LC_GET_INT("AdvSnapGridCellSnapFactor", 25) / 100.0; |
| | } |
| | LC_GROUP_END(); |
| |
|
| | m_catchEntityGuiRange = LC_GET_ONE_INT("Snapping", "CatchEntityGuiDistance", 32); |
| | } |
| |
|
| | void RS_Snapper::initFromGraphic(RS_Graphic *graphic) { |
| | if (graphic != nullptr) { |
| | updateUnitFormat(graphic); |
| |
|
| | m_snapIndicator->pointType = graphic->getVariableInt("$PDMODE", LC_DEFAULTS_PDMode); |
| | m_snapIndicator->pointSize = graphic->getVariableInt("$PDSIZE", LC_DEFAULTS_PDSize); |
| |
|
| | m_anglesBase = graphic->getAnglesBase(); |
| | m_anglesCounterClockWise = graphic->areAnglesCounterClockWise(); |
| | } |
| | } |
| |
|
| | void RS_Snapper::finish() { |
| | m_finished = true; |
| | deleteSnapper(); |
| | deleteInfoCursor(); |
| |
|
| | } |
| |
|
| | void RS_Snapper::setSnapMode(const RS_SnapMode& snapMode) { |
| | this->m_snapMode = snapMode; |
| | m_actionContext->requestSnapDistOptions(&m_SnapDistance, snapMode.snapDistance); |
| | m_actionContext->requestSnapMiddleOptions(&m_middlePoints, snapMode.snapMiddle); |
| | } |
| |
|
| | RS_SnapMode const* RS_Snapper::getSnapMode() const{ |
| | return &(this->m_snapMode); |
| | } |
| |
|
| | RS_SnapMode* RS_Snapper::getSnapMode() { |
| | return &(this->m_snapMode); |
| | } |
| |
|
| | |
| | RS_Vector RS_Snapper::snapFree(QMouseEvent* e) { |
| | if (!e) { |
| | RS_DEBUG->print(RS_Debug::D_WARNING, |
| | "RS_Snapper::snapFree: event is nullptr"); |
| | return RS_Vector(false); |
| | } |
| | pImpData->snapSpot=toGraph(e); |
| | pImpData->snapCoord=pImpData->snapSpot; |
| | m_snapIndicator->drawLines=true; |
| | return pImpData->snapCoord; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | RS_Vector RS_Snapper::snapPoint(QMouseEvent* e){ |
| | pImpData->snapSpot = RS_Vector(false); |
| | RS_Vector t(false); |
| |
|
| | if (!e) { |
| | RS_DEBUG->print(RS_Debug::D_WARNING, |
| | "RS_Snapper::snapPoint: event is nullptr"); |
| | return pImpData->snapSpot; |
| | } |
| |
|
| | RS_Vector mouseCoord = toGraph(e); |
| | double ds2Min=RS_MAXDOUBLE*RS_MAXDOUBLE; |
| |
|
| | if (m_snapMode.snapEndpoint) { |
| | t = snapEndpoint(mouseCoord); |
| | double ds2=mouseCoord.squaredTo(t); |
| |
|
| | if (t.valid && ds2 < ds2Min){ |
| | ds2Min=ds2; |
| | pImpData->snapSpot = t; |
| | pImpData->snapType = SnapType::ENDPOINT; |
| | } |
| | } |
| | if (m_snapMode.snapCenter) { |
| | t = snapCenter(mouseCoord); |
| | double ds2=mouseCoord.squaredTo(t); |
| | if (ds2 < ds2Min){ |
| | ds2Min=ds2; |
| | pImpData->snapSpot = t; |
| | pImpData->snapType = SnapType::CENTER; |
| | } |
| | } |
| | if (m_snapMode.snapMiddle) { |
| | |
| | |
| |
|
| | m_actionContext->requestSnapMiddleOptions(&m_middlePoints, m_snapMode.snapMiddle); |
| | t = snapMiddle(mouseCoord); |
| | double ds2=mouseCoord.squaredTo(t); |
| | if (ds2 < ds2Min){ |
| | ds2Min=ds2; |
| | pImpData->snapSpot = t; |
| | pImpData->snapType = SnapType::MIDDLE; |
| | } |
| | } |
| | if (m_snapMode.snapDistance) { |
| | |
| | |
| | m_actionContext->requestSnapDistOptions(&m_SnapDistance, m_snapMode.snapDistance); |
| | t = snapDist(mouseCoord); |
| | double ds2=mouseCoord.squaredTo(t); |
| | if (ds2 < ds2Min){ |
| | ds2Min=ds2; |
| | pImpData->snapSpot = t; |
| | pImpData->snapType = SnapType::DISTANCE; |
| | } |
| | } |
| | if (m_snapMode.snapIntersection) { |
| | t = snapIntersection(mouseCoord); |
| | double ds2=mouseCoord.squaredTo(t); |
| | if (ds2 < ds2Min){ |
| | ds2Min=ds2; |
| | pImpData->snapSpot = t; |
| | pImpData->snapType = SnapType::INTERSECTION; |
| | } |
| | } |
| |
|
| | if (m_snapMode.snapOnEntity && pImpData->snapSpot.distanceTo(mouseCoord) > m_distanceBeforeSwitchToFreeSnap) { |
| | t = snapOnEntity(mouseCoord); |
| | double ds2=mouseCoord.squaredTo(t); |
| | if (ds2 < ds2Min){ |
| | ds2Min=ds2; |
| | pImpData->snapSpot = t; |
| | pImpData->snapType = SnapType::ENTITY; |
| | } |
| | } |
| |
|
| | if (isSnapToGrid()) { |
| | t = snapGrid(mouseCoord); |
| | double ds2=mouseCoord.squaredTo(t); |
| | if (ds2 < ds2Min){ |
| | |
| | pImpData->snapSpot = t; |
| | pImpData->snapType = SnapType::GRID; |
| | } |
| | } |
| |
|
| | if( !pImpData->snapSpot.valid ) { |
| | pImpData->snapSpot=mouseCoord; |
| | pImpData->snapType = SnapType::FREE; |
| | } else { |
| |
|
| | |
| | |
| | if(m_snapMode.snapFree){ |
| | |
| | if((mouseCoord - pImpData->snapSpot).magnitude() >= getSnapRange()){ |
| | pImpData->snapSpot = mouseCoord; |
| | pImpData->snapType = SnapType::FREE; |
| | } |
| | } |
| | } |
| | |
| | |
| | |
| | |
| | RS_Vector vpv, vph; |
| | if (m_snapMode.restriction != RS2::RestrictNothing) { |
| | RS_Vector rz = m_viewport->getRelativeZero(); |
| | if (m_viewport->hasUCS()) { |
| | RS_Vector ucsRZ = m_viewport->toUCS(rz); |
| | RS_Vector ucsSnap = m_viewport->toUCS(pImpData->snapSpot); |
| | vpv = m_viewport->toWorld(RS_Vector(ucsRZ.x, ucsSnap.y)); |
| | vph = m_viewport->toWorld(RS_Vector(ucsSnap.x, ucsRZ.y)); |
| | } else { |
| | vpv = RS_Vector(rz.x, pImpData->snapSpot.y); |
| | vph = RS_Vector(pImpData->snapSpot.x, rz.y); |
| | } |
| | } |
| |
|
| | switch (m_snapMode.restriction) { |
| | case RS2::RestrictOrthogonal: { |
| | pImpData->snapCoord = (mouseCoord.distanceTo(vpv) < mouseCoord.distanceTo(vph)) ? |
| | vpv : vph; |
| | pImpData->restriction = RS2::RestrictOrthogonal; |
| |
|
| | break; |
| | } |
| | case RS2::RestrictHorizontal: { |
| | pImpData->snapCoord = vph; |
| | pImpData->restriction = RS2::RestrictHorizontal; |
| | break; |
| | } |
| | case RS2::RestrictVertical: { |
| | pImpData->snapCoord = vpv; |
| | pImpData->restriction = RS2::RestrictVertical; |
| | break; |
| | } |
| | |
| | default: { |
| | pImpData->snapCoord = pImpData->snapSpot; |
| | pImpData->restriction = RS2::RestrictNothing; |
| | break; |
| | } |
| | } |
| | |
| | |
| |
|
| | snapPoint(pImpData->snapSpot, false); |
| |
|
| | return pImpData->snapCoord; |
| | } |
| |
|
| | |
| | RS_Vector RS_Snapper::snapPoint(const RS_Vector& coord, bool setSpot){ |
| | if(coord.valid){ |
| | pImpData->snapSpot=coord; |
| | if(setSpot) pImpData->snapCoord = coord; |
| | |
| | updateCoordinateWidgetByRelZero(pImpData->snapCoord); |
| | drawSnapper(); |
| | drawInfoCursor(); |
| | } |
| | return coord; |
| | } |
| |
|
| | double RS_Snapper::getSnapRange() const{ |
| | |
| | |
| | std::vector<double> distances(3, RS_MAXDOUBLE); |
| | double& minGui=distances[0]; |
| | double& minGrid=distances[1]; |
| | double& minSize=distances[2]; |
| | if (m_graphicView != nullptr) { |
| | minGui = toGraphDX(32); |
| | |
| | |
| | |
| | if (m_viewport->isGridOn() && m_snapMode.snapGrid) { |
| | RS_Grid *grid = m_viewport->getGrid(); |
| | const RS_Vector &cellVector = grid->getCellVector(); |
| | minGrid = cellVector.magnitude() * m_minGridCellSnapFactor; |
| | } |
| | } |
| | if (m_container != nullptr && isSizeValid(m_container->getSize())) { |
| | |
| | minSize = getValidSize(m_container->getSize()); |
| | } |
| | if (std::min(minGui, minGrid) < 0.99 * RS_MAXDOUBLE) |
| | return std::min(minGui, minGrid); |
| | if (minSize < 0.99 * RS_MAXDOUBLE) |
| | return minSize; |
| | |
| | |
| | return RS_TOLERANCE; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | RS_Vector RS_Snapper::snapFree(const RS_Vector& coord) { |
| | m_keyEntity = nullptr; |
| | return coord; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | RS_Vector RS_Snapper::snapEndpoint(const RS_Vector& coord) { |
| | RS_Vector vec = m_container->getNearestEndpoint(coord, nullptr); |
| | return vec; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | RS_Vector RS_Snapper::snapGrid(const RS_Vector& coord) { |
| | |
| |
|
| | |
| | |
| | |
| | return m_viewport->snapGrid(coord); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | RS_Vector RS_Snapper::snapOnEntity(const RS_Vector& coord) { |
| | RS_Vector vec{}; |
| | vec = m_container->getNearestPointOnEntity(coord, true, nullptr, &m_keyEntity); |
| | return vec; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | RS_Vector RS_Snapper::snapCenter(const RS_Vector& coord) { |
| | RS_Vector vec = m_container->getNearestCenter(coord, nullptr); |
| | return vec; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | RS_Vector RS_Snapper::snapMiddle(const RS_Vector& coord) { |
| | |
| | return m_container->getNearestMiddle(coord,static_cast<double *>(nullptr),m_middlePoints); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | RS_Vector RS_Snapper::snapDist(const RS_Vector& coord) { |
| | RS_Vector vec; |
| | |
| | vec = m_container->getNearestDist(m_SnapDistance, |
| | coord, |
| | nullptr); |
| | return vec; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | RS_Vector RS_Snapper::snapIntersection(const RS_Vector& coord) { |
| | RS_Vector vec{}; |
| | vec = m_container->getNearestIntersection(coord,nullptr); |
| | return vec; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | RS_Vector RS_Snapper::restrictOrthogonal(const RS_Vector& coord) { |
| | RS_Vector rz = m_viewport->getRelativeZero(); |
| | RS_Vector ret(coord); |
| |
|
| | RS_Vector retx = RS_Vector(rz.x, ret.y); |
| | RS_Vector rety = RS_Vector(ret.x, rz.y); |
| |
|
| | if (retx.distanceTo(ret) > rety.distanceTo(ret)) { |
| | ret = rety; |
| | } else { |
| | ret = retx; |
| | } |
| |
|
| | return ret; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | RS_Vector RS_Snapper::restrictHorizontal(const RS_Vector& coord) { |
| | |
| | |
| | |
| | |
| | |
| |
|
| | return m_viewport->restrictHorizontal(m_viewport->getRelativeZero(), coord); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | RS_Vector RS_Snapper::restrictVertical(const RS_Vector& coord) { |
| | |
| | |
| | |
| | return m_viewport->restrictVertical(m_viewport->getRelativeZero(), coord); |
| | } |
| |
|
| | RS_Vector RS_Snapper::restrictVertical(const RS_Vector &base, const RS_Vector &coord) const{ |
| | return m_viewport->restrictVertical(base, coord); |
| | } |
| |
|
| | RS_Vector RS_Snapper::restrictHorizontal(const RS_Vector &base, const RS_Vector &coord) const{ |
| | return m_viewport->restrictHorizontal(base, coord); |
| | } |
| |
|
| | RS_Vector RS_Snapper::restrictAngle(const RS_Vector &basePoint, const RS_Vector& snap, double angle){ |
| | RS_Vector possibleEndPoint; |
| | double realAngle = toWorldAngle(angle); |
| | RS_Vector infiniteTickEndPoint = basePoint.relative(10.0, realAngle); |
| | RS_Vector pointOnInfiniteTick = LC_LineMath::getNearestPointOnInfiniteLine(snap, basePoint, infiniteTickEndPoint); |
| |
|
| | possibleEndPoint = pointOnInfiniteTick; |
| | return possibleEndPoint; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | RS_Entity* RS_Snapper::catchEntity(const RS_Vector& pos, |
| | RS2::ResolveLevel level) { |
| |
|
| | RS_DEBUG->print("RS_Snapper::catchEntity"); |
| |
|
| | |
| | double dist (0.); |
| | |
| |
|
| | RS_Entity* entity = m_container->getNearestEntity(pos, &dist, level); |
| |
|
| | int idx = -1; |
| | if (entity != nullptr && entity->getParent()) { |
| | idx = entity->getParent()->findEntity(entity); |
| | } |
| |
|
| | if (entity != nullptr && dist <= getCatchDistance(getSnapRange(), m_catchEntityGuiRange)) { |
| | |
| | RS_DEBUG->print("RS_Snapper::catchEntity: found: %d", idx); |
| | return entity; |
| | } else { |
| | RS_DEBUG->print("RS_Snapper::catchEntity: not found"); |
| | return nullptr; |
| | } |
| | RS_DEBUG->print("RS_Snapper::catchEntity: OK"); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | RS_Entity* RS_Snapper::catchEntity(const RS_Vector& pos, RS2::EntityType enType, |
| | RS2::ResolveLevel level) { |
| |
|
| | RS_DEBUG->print("RS_Snapper::catchEntity"); |
| | |
| |
|
| | |
| | RS_EntityContainer ec(nullptr,false); |
| | |
| | bool isContainer{false}; |
| | switch(enType){ |
| | case RS2::EntityPolyline: |
| | case RS2::EntityContainer: |
| | case RS2::EntitySpline: |
| | isContainer=true; |
| | break; |
| | default: |
| | break; |
| | } |
| |
|
| | |
| | for(RS_Entity* en: lc::LC_ContainerTraverser{*m_container, level}.entities()){ |
| | if(!en->isVisible()) |
| | continue; |
| | if(en->rtti() != enType && isContainer){ |
| | |
| | RS_Entity* parent(en->getParent()); |
| | bool matchFound{false}; |
| | while(parent ) { |
| | |
| | if(parent->rtti() == enType) { |
| | matchFound=true; |
| | ec.addEntity(en); |
| | break; |
| | } |
| | parent=parent->getParent(); |
| | } |
| | if(!matchFound) continue; |
| | } |
| | if (en->rtti() == enType){ |
| | ec.addEntity(en); |
| | } |
| | } |
| | if (ec.count() == 0 ) return nullptr; |
| | double dist(0.); |
| |
|
| | RS_Entity* entity = ec.getNearestEntity(pos, &dist, RS2::ResolveNone); |
| |
|
| | int idx = -1; |
| | if (entity != nullptr && entity->getParent()) { |
| | idx = entity->getParent()->findEntity(entity); |
| | } |
| |
|
| | if (entity != nullptr && dist <= getCatchDistance(getSnapRange(), m_catchEntityGuiRange)) { |
| | |
| | RS_DEBUG->print("RS_Snapper::catchEntity: found: %d", idx); |
| | return entity; |
| | } else { |
| | RS_DEBUG->print("RS_Snapper::catchEntity: not found"); |
| | return nullptr; |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | RS_Entity* RS_Snapper::catchEntity(QMouseEvent* e,RS2::ResolveLevel level) { |
| | RS_Entity* entity = catchEntity(toGraph(e), level); |
| | return entity; |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | RS_Entity* RS_Snapper::catchEntity(QMouseEvent* e, RS2::EntityType enType,RS2::ResolveLevel level) { |
| | return catchEntity(toGraph(e),enType,level); |
| | } |
| |
|
| | RS_Entity* RS_Snapper::catchEntity(QMouseEvent* e, const EntityTypeList& enTypeList,RS2::ResolveLevel level) { |
| | RS_Vector coord = toGraph(e); |
| | return catchEntity(coord, enTypeList, level); |
| | } |
| |
|
| | RS_Entity* RS_Snapper::catchEntity(const RS_Vector& coord, const EntityTypeList& enTypeList, |
| | RS2::ResolveLevel level) { |
| | RS_Entity *pten = nullptr; |
| | switch (enTypeList.size()) { |
| | case 0: |
| | return catchEntity(coord, level); |
| | default: { |
| |
|
| | RS_EntityContainer ec(nullptr, false); |
| | for (auto t0: enTypeList) { |
| | RS_Entity *en = catchEntity(coord, t0, level); |
| | if (en) ec.addEntity(en); |
| | |
| | |
| | |
| | |
| | } |
| | if (ec.count() > 0){ |
| | ec.getDistanceToPoint(coord, &pten, RS2::ResolveNone); |
| | return pten; |
| | } |
| | } |
| | } |
| | return nullptr; |
| | } |
| |
|
| | void RS_Snapper::suspend() { |
| | |
| | |
| | pImpData->snapSpot = pImpData->snapCoord = RS_Vector{false}; |
| | } |
| |
|
| | void RS_Snapper::resume() { |
| | drawSnapper(); |
| | initSettings(); |
| | m_infoCursorOverlayPrefs = m_graphicView->getInfoCursorOverlayPreferences(); |
| | } |
| |
|
| | |
| | |
| | |
| | void RS_Snapper::hideSnapOptions() { |
| | m_actionContext->hideSnapOptions(); |
| | } |
| |
|
| |
|
| | |
| | |
| | |
| | void RS_Snapper::deleteSnapper(){ |
| | |
| | if (m_graphicView != nullptr && !m_graphicView->isCleanUp()) { |
| | m_viewport->clearOverlayDrawablesContainer(RS2::Snapper); |
| | m_graphicView->redraw(RS2::RedrawOverlay); |
| | } |
| | } |
| |
|
| | void RS_Snapper::deleteInfoCursor(){ |
| | |
| | if (m_graphicView != nullptr && !m_graphicView->isCleanUp()) { |
| | m_viewport->clearOverlayDrawablesContainer(RS2::InfoCursor); |
| | m_graphicView->redraw(RS2::RedrawOverlay); |
| | } |
| | } |
| |
|
| | |
| | |
| | |
| | void RS_Snapper::drawSnapper(){ |
| | LC_OverlayDrawablesContainer *snapperOverlay = m_viewport->getOverlaysDrawablesContainer(RS2::Snapper); |
| | snapperOverlay->clear(); |
| | if (!m_finished && pImpData->snapSpot.valid){ |
| | if (m_snapIndicator->drawLines || m_snapIndicator->drawShape) { |
| | auto *crosshair = new LC_Crosshair(pImpData->snapCoord, m_snapIndicator->shape_type, |
| | m_snapIndicator->lines_type, m_snapIndicator->lines_pen, m_snapIndicator->pointSize, m_snapIndicator->pointType); |
| | crosshair->setShapesPen(m_snapIndicator->shape_pen); |
| | snapperOverlay->add(crosshair); |
| | } |
| | } |
| | m_graphicView->redraw(RS2::RedrawOverlay); |
| | } |
| |
|
| |
|
| | LC_OverlayInfoCursor* RS_Snapper::obtainInfoCursor(){ |
| | auto overlayContainer = m_viewport->getOverlaysDrawablesContainer(RS2::InfoCursor); |
| | LC_OverlayInfoCursor * result = nullptr; |
| | |
| | auto entity = overlayContainer->first(); |
| | result = dynamic_cast<LC_OverlayInfoCursor *>(entity); |
| | if (result == nullptr && m_infoCursorOverlayPrefs != nullptr){ |
| | result = new LC_OverlayInfoCursor(pImpData->snapCoord, &m_infoCursorOverlayPrefs->options); |
| | overlayContainer->add(result); |
| | } |
| | return result; |
| | } |
| |
|
| | void RS_Snapper::drawInfoCursor(){ |
| | auto overlayContainer = m_viewport->getOverlaysDrawablesContainer(RS2::InfoCursor); |
| | if (m_infoCursorOverlayPrefs != nullptr && m_infoCursorOverlayPrefs->enabled) { |
| | |
| | auto entity = overlayContainer->first(); |
| | auto* infoCursor = dynamic_cast<LC_OverlayInfoCursor *>(entity); |
| | if (infoCursor == nullptr) { |
| | infoCursor = new LC_OverlayInfoCursor(pImpData->snapCoord, &m_infoCursorOverlayPrefs->options); |
| | overlayContainer->add(infoCursor); |
| | } |
| | else{ |
| | infoCursor->setOptions(&m_infoCursorOverlayPrefs->options); |
| | infoCursor->setPos(pImpData->snapCoord); |
| | } |
| | auto prefs = getInfoCursorOverlayPrefs(); |
| | if (prefs->showSnapType) { |
| | QString snapName = getSnapName(pImpData->snapType); |
| | QString restrictionName; |
| | if (pImpData->snapType == ANGLE || pImpData->snapType == ANGLE_REL || pImpData->snapType == ANGLE_ON_ENTITY) { |
| | double ucsAbsSnapAngle = pImpData->angle; |
| | double ucsBasisAngle = m_viewport->toUCSBasisAngle(ucsAbsSnapAngle, m_anglesBase, m_anglesCounterClockWise); |
| | restrictionName = RS_Units::formatAngle(ucsBasisAngle, m_angleFormat, m_anglePrecision); |
| | } else { |
| | restrictionName = getRestrictionName(pImpData->restriction); |
| | } |
| | if (!restrictionName.isEmpty()) { |
| | snapName = snapName + (prefs->multiLine ? "\n" : " ") + restrictionName; |
| | } |
| | m_infoCursorOverlayData->setZone2(snapName); |
| | } else { |
| | m_infoCursorOverlayData->setZone2(""); |
| | } |
| | infoCursor->setZonesData(m_infoCursorOverlayData.get()); |
| | } |
| | m_graphicView->redraw(RS2::RedrawOverlay); |
| | } |
| |
|
| | QString RS_Snapper::getRestrictionName(int restriction) { |
| | switch (restriction) { |
| | case RS2::RestrictVertical: |
| | return tr("Vertical"); |
| | case RS2::RestrictHorizontal: |
| | return tr("Horizontal"); |
| | case RS2::RestrictOrthogonal: |
| | return tr("Orthogonal"); |
| | default: |
| | return ""; |
| | } |
| | } |
| |
|
| | QString RS_Snapper::getSnapName(int snapType){ |
| | switch (snapType){ |
| | case GRID: |
| | return tr("Grid"); |
| | case ENTITY: |
| | return tr("Entity"); |
| | case ENDPOINT: |
| | return tr("Endpoint"); |
| | case INTERSECTION: |
| | return tr("Intersection"); |
| | case MIDDLE: |
| | return tr("Middle"); |
| | case DISTANCE: |
| | return tr("Distance"); |
| | case CENTER: |
| | return tr("Center"); |
| | case ANGLE: |
| | return tr("Angle"); |
| | case ANGLE_REL: |
| | return tr("Angle Relative"); |
| | case ANGLE_ON_ENTITY: |
| | return tr("Angle (on Entity)"); |
| | case FREE: |
| | default: |
| | return ""; |
| | } |
| | } |
| |
|
| | bool RS_Snapper::isSnapToGrid(){ |
| | bool result = m_snapMode.snapGrid; |
| | if (result) { |
| | if (m_ignoreSnapToGridIfNoGrid) { |
| | result = m_viewport->isGridOn(); |
| | } |
| | } |
| | return result; |
| | } |
| |
|
| | RS_Vector RS_Snapper::snapToRelativeAngle(double baseAngle, const RS_Vector ¤tCoord, const RS_Vector &referenceCoord, const double angularResolution){ |
| |
|
| | if(m_snapMode.restriction != RS2::RestrictNothing || isSnapToGrid()){ |
| | return currentCoord; |
| | } |
| |
|
| | double wcsAngleRaw = referenceCoord.angleTo(currentCoord); |
| | double ucsAngleRaw = toUCSAngle(wcsAngleRaw); |
| | double ucsAngleSnapped = ucsAngleRaw - std::remainder(ucsAngleRaw, angularResolution); |
| | double wcsAngleSnappedAbsolute = toWorldAngle(ucsAngleSnapped); |
| |
|
| | double wcsAngleSnapped = wcsAngleSnappedAbsolute + baseAngle; |
| |
|
| | RS_Vector res = RS_Vector::polar(referenceCoord.distanceTo(currentCoord), wcsAngleSnapped); |
| | res += referenceCoord; |
| |
|
| | if (m_snapMode.snapOnEntity) { |
| | RS_Vector t = m_container->getNearestVirtualIntersection(res, wcsAngleSnapped, nullptr); |
| | pImpData->snapSpot = t; |
| | pImpData->snapType = (t == res) ? SnapType::ANGLE_REL : SnapType::ANGLE_ON_ENTITY; |
| | pImpData->angle = ucsAngleSnapped; |
| | snapPoint(pImpData->snapSpot, true); |
| | return t; |
| | } else { |
| | pImpData->snapType = SnapType::ANGLE_REL; |
| | pImpData->angle = ucsAngleSnapped; |
| | snapPoint(res, true); |
| | return res; |
| | } |
| | } |
| |
|
| | RS_Vector RS_Snapper::snapToAngle(const RS_Vector ¤tCoord, const RS_Vector &referenceCoord, const double angularResolution) { |
| | if (m_snapMode.restriction != RS2::RestrictNothing || isSnapToGrid()) { |
| | return currentCoord; |
| | } |
| | return doSnapToAngle(currentCoord, referenceCoord, angularResolution); |
| | } |
| |
|
| | RS_Vector RS_Snapper::doSnapToAngle(const RS_Vector ¤tCoord, const RS_Vector &referenceCoord, const double angularResolution) { |
| | double wcsAngleRaw = referenceCoord.angleTo(currentCoord); |
| | double ucsAngleAbs = this->toUCSAngle(wcsAngleRaw); |
| |
|
| | double ucsAngle = ucsAngleAbs - this->m_anglesBase; |
| | double ucsAngleSnapped = ucsAngleAbs - remainder(ucsAngle, angularResolution); |
| |
|
| | |
| | double wcsAngleSnapped = this->toWorldAngle(ucsAngleSnapped); |
| |
|
| | RS_Vector res = RS_Vector::polar(referenceCoord.distanceTo(currentCoord), wcsAngleSnapped); |
| | res += referenceCoord; |
| |
|
| | if (this->m_snapMode.snapOnEntity) { |
| | RS_Vector t = this->m_container->getNearestVirtualIntersection(res, wcsAngleSnapped, nullptr); |
| | this->pImpData->snapSpot = t; |
| | this->pImpData->snapType = (t == res) ? ANGLE : ANGLE_ON_ENTITY; |
| | this->pImpData->angle = ucsAngleSnapped; |
| | this->snapPoint(this->pImpData->snapSpot, true); |
| | return t; |
| | } else { |
| | this->pImpData->snapType = ANGLE; |
| | this->pImpData->angle = ucsAngleSnapped; |
| | this->snapPoint(res, true); |
| | return res; |
| | } |
| | } |
| |
|
| | RS_Vector RS_Snapper::toGraph(const QMouseEvent* e) const{ |
| | const QPointF &pointF = e->position(); |
| | RS_Vector result = m_viewport->toWorldFromUi(pointF.x(), pointF.y()); |
| | return result; |
| | } |
| |
|
| | double RS_Snapper::toGuiDX(double wcsDX) const { |
| | return m_viewport->toGuiDX(wcsDX); |
| | } |
| |
|
| | double RS_Snapper::toGraphDX(int wcsDX) const { |
| | return m_viewport->toUcsDX(wcsDX); |
| | } |
| |
|
| | RS_Vector const &RS_Snapper::getRelativeZero() const { |
| | return m_viewport->getRelativeZero(); |
| | } |
| |
|
| | void RS_Snapper::updateCoordinateWidgetFormat(){ |
| | m_actionContext->updateCoordinateWidget(toWorld(RS_Vector(0.0,0.0)),toWorld(RS_Vector(0.0,0.0)), true); |
| | } |
| |
|
| | void RS_Snapper::updateCoordinateWidget(const RS_Vector& abs, const RS_Vector& rel, bool updateFormat){ |
| | if (m_infoCursorOverlayPrefs->enabled) { |
| | preparePositionsInfoCursorOverlay(updateFormat, abs, rel); |
| | } |
| | m_actionContext->updateCoordinateWidget(abs, rel, updateFormat); |
| | } |
| |
|
| | void RS_Snapper::updateCoordinateWidgetByRelZero(const RS_Vector& abs, bool updateFormat){ |
| | const RS_Vector &relative = abs - m_viewport->getRelativeZero(); |
| | if (m_infoCursorOverlayPrefs->enabled) { |
| | preparePositionsInfoCursorOverlay(updateFormat, abs, relative); |
| | } |
| | m_actionContext->updateCoordinateWidget(abs, relative, updateFormat); |
| | } |
| |
|
| | LC_InfoCursorOverlayPrefs* RS_Snapper::getInfoCursorOverlayPrefs() const { |
| | return m_infoCursorOverlayPrefs; |
| | } |
| |
|
| | bool RS_Snapper::isInfoCursorForModificationEnabled() const { |
| | return m_infoCursorOverlayPrefs->enabled && m_infoCursorOverlayPrefs->showEntityInfoOnModification; |
| | } |
| |
|
| | void RS_Snapper::preparePositionsInfoCursorOverlay(bool updateFormat, const RS_Vector &abs, const RS_Vector &relative) { |
| | LC_InfoCursorOverlayPrefs* prefs = getInfoCursorOverlayPrefs(); |
| |
|
| | QString coordAbs = ""; |
| | QString coordPolar = ""; |
| | if (prefs != nullptr && (prefs->showAbsolutePosition || prefs->showRelativePositionDistAngle || prefs->showRelativePositionDeltas)){ |
| | RS_Graphic* graphic = m_graphicView->getGraphic(); |
| | if (graphic != nullptr) { |
| | if (updateFormat) { |
| | updateUnitFormat(graphic); |
| | } |
| |
|
| | bool showLabels = prefs->showLabels; |
| | if (prefs->showAbsolutePosition) { |
| | RS_Vector ucs = toUCS(abs); |
| | QString absX = (showLabels ? "X: " : "") + formatLinear(ucs.x); |
| | QString absY = (showLabels ? "Y: " : "") + formatLinear(ucs.y); |
| | coordAbs = absX + (prefs->multiLine ? "\n" : showLabels ? " " : " , ") + absY; |
| | } |
| |
|
| | bool hasUCS = m_viewport->hasUCS(); |
| | if (prefs->showAbsolutePositionWCS && hasUCS){ |
| | QString absX = (showLabels ? "WX: " : "W") + formatLinear(abs.x); |
| | QString absY = (showLabels ? "WY: " : "") + formatLinear(abs.y); |
| |
|
| | QString coordAbsWCS = absX + (prefs->multiLine ? "\n" : showLabels ? " " : " , ") + absY; |
| |
|
| | if (coordAbs.isEmpty()){ |
| | coordAbs = coordAbsWCS; |
| | } |
| | else{ |
| | coordAbs = coordAbs + "\n" + coordAbsWCS; |
| | } |
| | } |
| |
|
| | RS_Vector relativeToUse; |
| | if (hasUCS){ |
| | relativeToUse = m_viewport->toUCSDelta(relative); |
| | } |
| | else{ |
| | relativeToUse = relative; |
| | } |
| |
|
| | if (prefs->showRelativePositionDistAngle) { |
| | QString lenStr = (showLabels ? tr("Dist: ") : "@ ") + formatLinear(relativeToUse.magnitude()); |
| | |
| |
|
| | double relativeAngle = relativeToUse.angle(); |
| | double ucsBasisAngle = ucsAbsToBasisAngle(relativeAngle); |
| | QString angleStr = (showLabels ? tr("Angle: ") : "< ") + formatAngleRaw(ucsBasisAngle); |
| |
|
| | coordPolar = lenStr + (prefs->multiLine ? "\n" : showLabels ? " " : " ") + angleStr; |
| | } |
| | if (prefs->showRelativePositionDeltas) { |
| | QString lenStr = (showLabels ? tr("dX: ") : "@ ") + formatLinear(relativeToUse.x); |
| | QString angleStr = (showLabels ? tr("dY: ") : "") + formatLinear(relativeToUse.y); |
| |
|
| | QString coordDeltas = lenStr + (prefs->multiLine ? "\n" : showLabels ? " " : " , ") + angleStr; |
| | if (coordPolar.isEmpty()){ |
| | coordPolar = coordDeltas; |
| | } |
| | else{ |
| | coordPolar = coordPolar + "\n" + coordDeltas; |
| | } |
| | } |
| | } |
| | } |
| |
|
| | m_infoCursorOverlayData->setZone1(coordAbs); |
| | m_infoCursorOverlayData->setZone3(coordPolar); |
| | } |
| |
|
| | void RS_Snapper::updateUnitFormat(RS_Graphic* graphic){ |
| | m_linearFormat = graphic->getLinearFormat(); |
| | m_linearPrecision = graphic->getLinearPrecision(); |
| | m_angleFormat = graphic->getAngleFormat(); |
| | m_anglePrecision = graphic->getAnglePrecision(); |
| | m_unit = graphic->getUnit(); |
| | } |
| |
|
| | void RS_Snapper::invalidateSnapSpot() { |
| | pImpData->snapSpot.valid = false; |
| | } |
| |
|
| | QString RS_Snapper::formatLinear(double value) const{ |
| | return RS_Units::formatLinear(value, m_unit, m_linearFormat, m_linearPrecision); |
| | } |
| |
|
| | QString RS_Snapper::formatWCSAngle(double wcsAngle) const{ |
| | double ucsAbsAngle; |
| | if (m_viewport->hasUCS()){ |
| | ucsAbsAngle = toUCSAngle(wcsAngle); |
| | } |
| | else{ |
| | ucsAbsAngle = wcsAngle; |
| | } |
| | double ucsBasisAngle = m_viewport->toUCSBasisAngle(ucsAbsAngle, m_anglesBase, m_anglesCounterClockWise); |
| | return RS_Units::formatAngle(ucsBasisAngle, m_angleFormat, m_anglePrecision); |
| | } |
| |
|
| | QString RS_Snapper::formatAngleRaw(double angle) const { |
| | return RS_Units::formatAngle(angle, m_angleFormat, m_anglePrecision); |
| | } |
| | |
| | QString RS_Snapper::formatVector(const RS_Vector &value) const{ |
| | double x, y; |
| | if (m_viewport->hasUCS()){ |
| | RS_Vector ucsValue = m_viewport->toUCS(value); |
| | x = ucsValue.x; |
| | y = ucsValue.y; |
| | } |
| | else { |
| | x = value.x; |
| | y = value.y; |
| | } |
| | return formatLinear(x).append(" , ").append(formatLinear(y)); |
| | } |
| |
|
| | QString RS_Snapper::formatVectorWCS(const RS_Vector &value) const { |
| | return QString("W ").append(formatLinear(value.x)).append(" , ").append(formatLinear(value.y)); |
| | } |
| |
|
| | QString RS_Snapper::formatRelative(const RS_Vector &value) const { |
| | double x, y; |
| | m_viewport->toUCSDelta(value, x, y); |
| | return QString("@ ").append(formatLinear(x)).append(" , ").append(formatLinear(y)); |
| | } |
| |
|
| | QString RS_Snapper::formatPolar(const RS_Vector &value) const { |
| | return formatLinear(value.magnitude()).append(" < ").append(formatWCSAngle(value.angle())); |
| | } |
| |
|
| | QString RS_Snapper::formatRelativePolar(const RS_Vector &wcsAngle) const { |
| | return QString("@ ").append(formatLinear(wcsAngle.magnitude())).append(" < ").append(formatWCSAngle(wcsAngle.angle())); |
| | } |
| |
|
| | void RS_Snapper::forceUpdateInfoCursor(const RS_Vector &pos) { |
| | LC_OverlayInfoCursor* infoCursor = obtainInfoCursor(); |
| | infoCursor->setPos(pos); |
| | infoCursor->setZonesData(m_infoCursorOverlayData.get()); |
| | } |
| |
|
| | double RS_Snapper::toWorldAngle(double ucsAbsAngle) const{ |
| | return m_viewport->toWorldAngle(ucsAbsAngle); |
| | } |
| |
|
| | double RS_Snapper::toWorldAngleDegrees(double ucsAbsAngleDegrees) const{ |
| | return m_viewport->toWorldAngleDegrees(ucsAbsAngleDegrees); |
| | } |
| |
|
| | double RS_Snapper::toUCSAngle(double wcsAngle) const{ |
| | return m_viewport->toUCSAngle(wcsAngle); |
| | } |
| |
|
| | double RS_Snapper::ucsAbsToBasisAngle(double ucsAbsAngle) const{ |
| | return m_viewport->toBasisUCSAngle(ucsAbsAngle); |
| | } |
| |
|
| | double RS_Snapper::ucsBasisToAbsAngle(double ucsRelAngle) const{ |
| | return m_viewport->toAbsUCSAngle(ucsRelAngle); |
| | } |
| |
|
| | double RS_Snapper::adjustRelativeAngleSignByBasis(double relativeAngle) const{ |
| | double result; |
| | if (m_anglesCounterClockWise){ |
| | result = relativeAngle; |
| | } |
| | else{ |
| | result = -relativeAngle; |
| | } |
| | return result; |
| | } |
| |
|
| | double RS_Snapper::toUCSBasisAngleDegrees(double wcsAngle) const{ |
| | double ucsAngle = m_viewport->toUCSAngle(wcsAngle); |
| | double ucsBasisAngle = m_viewport->toUCSBasisAngle(ucsAngle, m_anglesBase, m_anglesCounterClockWise); |
| | double result = RS_Math::rad2deg(ucsBasisAngle); |
| | return result; |
| | } |
| |
|
| | double RS_Snapper::toWorldAngleFromUCSBasisDegrees(double ucsBasisAngleDegrees) const{ |
| | double ucsBasisAngle = RS_Math::deg2rad(ucsBasisAngleDegrees); |
| | double ucsAngle = m_viewport->toUCSAbsAngle(ucsBasisAngle, m_anglesBase, m_anglesCounterClockWise); |
| | double wcsAngle = m_viewport->toWorldAngle(ucsAngle); |
| | return wcsAngle; |
| | } |
| |
|
| | double RS_Snapper::toWorldAngleFromUCSBasis(double ucsBasisAngle) const{ |
| | double ucsAngle = m_viewport->toUCSAbsAngle(ucsBasisAngle, m_anglesBase, m_anglesCounterClockWise); |
| | double wcsAngle = m_viewport->toWorldAngle(ucsAngle); |
| | return wcsAngle; |
| | } |
| |
|
| | double RS_Snapper::toUCSBasisAngle(double wcsAngle) const{ |
| | double ucsAngle = m_viewport->toUCSAngle(wcsAngle); |
| | double ucsBasisAngle = m_viewport->toUCSBasisAngle(ucsAngle, m_anglesBase, m_anglesCounterClockWise); |
| | return ucsBasisAngle; |
| | } |
| |
|
| | RS_Vector RS_Snapper::toWorld(const RS_Vector &ucsPos) const { |
| | return m_viewport->toWorld(ucsPos); |
| | } |
| |
|
| | RS_Vector RS_Snapper::toUCS(const RS_Vector &worldPos) const { |
| | return m_viewport->toUCS(worldPos); |
| | } |
| |
|
| | RS_Vector RS_Snapper::toWorldDelta(const RS_Vector &ucsDelta) const { |
| | return m_viewport->toWorldDelta(ucsDelta); |
| | } |
| |
|
| | RS_Vector RS_Snapper::toUCSDelta(const RS_Vector &worldDelta) const { |
| | return m_viewport->toUCSDelta(worldDelta); |
| | } |
| |
|
| | |
| | void RS_Snapper::calcRectCorners(const RS_Vector &worldCorner1, const RS_Vector &worldCorner3, RS_Vector &worldCorner2, RS_Vector &worldCorner4) const { |
| | RS_Vector ucsCorner1 = toUCS(worldCorner1); |
| | RS_Vector ucsCorner3 = toUCS(worldCorner3); |
| | RS_Vector ucsCorner2 = RS_Vector(ucsCorner1.x, ucsCorner3.y); |
| | RS_Vector ucsCorner4 = RS_Vector(ucsCorner3.x, ucsCorner1.y); |
| | worldCorner2 = toWorld(ucsCorner2); |
| | worldCorner4 = toWorld(ucsCorner4); |
| | } |
| |
|
| | bool RS_Snapper::hasNonDefaultAnglesBasis(){ |
| | return LC_LineMath::isMeaningfulAngle(m_anglesBase) || !m_anglesCounterClockWise; |
| | } |
| |
|
| | |
| | double RS_Snapper::getCatchDistance(double catchDistance, int catchEntityGuiRange){ |
| | return (m_graphicView != nullptr) ? std::min(catchDistance, toGraphDX(catchEntityGuiRange)) : catchDistance; |
| | } |
| |
|
| | |
| | void RS_Snapper::enableCoordinateInput(){ |
| | m_graphicView->enableCoordinateInput(); |
| | } |
| |
|
| | void RS_Snapper::disableCoordinateInput(){ |
| | m_graphicView->disableCoordinateInput(); |
| | }; |
| |
|
| | void RS_Snapper::redraw(RS2::RedrawMethod method) { |
| | |
| | |
| | m_graphicView->redraw(method); |
| | } |
| |
|
| | void RS_Snapper::redrawDrawing() { |
| | redraw(RS2::RedrawMethod::RedrawDrawing); |
| | } |
| |
|
| | void RS_Snapper::redrawAll() { |
| | redraw(RS2::RedrawMethod::RedrawAll); |
| | } |
| |
|