| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #include "rs_grid.h" |
| |
|
| | #include "lc_graphicviewport.h" |
| | #include "lc_gridsystem.h" |
| | #include "lc_isometricgrid.h" |
| | #include "lc_orthogonalgrid.h" |
| | #include "rs_graphic.h" |
| | #include "rs_math.h" |
| | #include "rs_settings.h" |
| | #include "rs_units.h" |
| |
|
| | #ifdef EMU_C99 |
| | #include "emu_c99.h" |
| | #endif |
| |
|
| | class RS_Graphic; |
| |
|
| | namespace { |
| |
|
| | constexpr int MINIMAL_GRID_UI_STEP = 2; |
| |
|
| | |
| | const int maxGridPoints=1000000; |
| | |
| | const double minimumGridWidth=1.0e-8; |
| | } |
| |
|
| | |
| | |
| | |
| | RS_Grid::RS_Grid(LC_GraphicViewport* graphicView) |
| | :m_viewport(graphicView) |
| | { |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | RS_Vector RS_Grid::snapGrid(const RS_Vector& coord) const { |
| | return gridSystem->snapGrid(coord); |
| | } |
| |
|
| | void RS_Grid::loadSettings(){ |
| |
|
| | LC_GROUP("Appearance"); |
| | m_scaleGrid = LC_GET_BOOL("ScaleGrid", true); |
| | |
| | auto graphic = m_viewport->getGraphic(); |
| | if (graphic != nullptr) { |
| | m_isometric = graphic->isIsometricGrid(); |
| | isoViewType = graphic->getIsoView(); |
| | m_userGrid = graphic->getVariableVector("$GRIDUNIT", RS_Vector(-1.0, -1.0)); |
| | }else { |
| | m_isometric = LC_GET_ONE_BOOL("Defaults", "IsometricGrid"); |
| | isoViewType=static_cast<RS2::IsoGridViewType>(LC_GET_ONE_INT("Defaults", "IsoGridView", 0)); |
| | m_userGrid.x = LC_GET_STR("GridSpacingX", QString("-1")).toDouble(); |
| | m_userGrid.y = LC_GET_STR("GridSpacingY", QString("-1")).toDouble(); |
| | } |
| |
|
| | bool drawMetaGrid = LC_GET_BOOL("metaGridDraw", true); |
| | bool drawGrid = LC_GET_BOOL("GridDraw", true); |
| | bool simpleGridRendering = LC_GET_BOOL("GridRenderSimple", false); |
| | m_minGridSpacing = LC_GET_INT("MinGridSpacing", 10); |
| | int gridType = LC_GET_INT("GridType", 0); |
| | bool linesGrid = gridType == 1; |
| |
|
| | RS2::LineType metagridLineType; |
| | int metaGridWidthPx; |
| |
|
| | if (linesGrid){ |
| | metagridLineType = static_cast<RS2::LineType> (LC_GET_INT("metaGridLinesLineType", RS2::SolidLine)); |
| | metaGridWidthPx = LC_GET_INT("metaGridLinesLineWidth", 1); |
| | } |
| | else{ |
| | metagridLineType = static_cast<RS2::LineType> (LC_GET_INT("metaGridPointsLineType", RS2::DotLineTiny)); |
| | metaGridWidthPx = LC_GET_INT("metaGridPointsLineWidth", 1); |
| | } |
| |
|
| | int gridWidthPx = LC_GET_INT("GridLinesLineWidth", 1); |
| | RS2::LineType gridLineType = static_cast<RS2::LineType> (LC_GET_INT("GridLinesLineType", RS2::SolidLine)); |
| |
|
| | bool disableGridOnPanning = LC_GET_BOOL("GridDisableWithinPan", false); |
| | bool drawIsoVerticalForTop = LC_GET_BOOL("GridDrawIsoVerticalForTop", true); |
| |
|
| | m_metaGridEvery = LC_GET_INT("MetaGridEvery", 10); |
| | LC_GROUP_END(); |
| |
|
| | LC_GROUP("Colors"); |
| | RS_Color metaGridColor; |
| | RS_Color gridColorLines = QColor(LC_GET_STR("gridLines", RS_Settings::color_meta_grid_lines)); |
| | RS_Color gridColorPoint = QColor(LC_GET_STR("grid", RS_Settings::color_meta_grid_points)); |
| | if (linesGrid) { |
| | metaGridColor= QColor(LC_GET_STR("meta_grid_lines", RS_Settings::color_meta_grid_lines)); |
| | } |
| | else{ |
| | metaGridColor= QColor(LC_GET_STR("meta_grid", RS_Settings::color_meta_grid_points)); |
| | } |
| | LC_GROUP_END(); |
| |
|
| | auto* gridOptions = new LC_GridSystem::LC_GridOptions(); |
| | gridOptions->drawMetaGrid = drawMetaGrid; |
| | gridOptions->simpleGridRendering = simpleGridRendering; |
| | gridOptions->gridWidthPx = gridWidthPx; |
| | gridOptions->gridLineType = gridLineType; |
| | gridOptions->drawGrid = drawGrid; |
| | gridOptions->drawLines = linesGrid; |
| | gridOptions->gridColorPoint = gridColorPoint; |
| | gridOptions->gridColorLine = gridColorLines; |
| | gridOptions->metaGridLineWidthPx = metaGridWidthPx; |
| | gridOptions->metaGridLineType = metagridLineType; |
| | gridOptions->metaGridColor = metaGridColor; |
| | gridOptions->disableGridOnPanning = disableGridOnPanning; |
| | gridOptions->drawIsometricVerticalsAlways = drawIsoVerticalForTop; |
| |
|
| | delete gridSystem; |
| |
|
| | if (m_isometric){ |
| | gridSystem = new LC_IsometricGrid(gridOptions, isoViewType); |
| | } |
| | else{ |
| | gridSystem = new LC_OrthogonalGrid(gridOptions); |
| | } |
| | } |
| |
|
| | void RS_Grid::calculateSnapSettings(){ |
| | if (gridSystem->isValid() || gridSystem->isGridDisabledByPanning(m_viewport)){ |
| | return; |
| | } |
| | RS_Vector viewZero; |
| | RS_Vector viewSize; |
| | RS_Vector metaGridWidthToUse; |
| | RS_Vector gridWidthToUse; |
| | prepareGridCalculations(viewZero, viewSize,metaGridWidthToUse, gridWidthToUse); |
| | gridSystem->calculateSnapInfo(viewZero, viewSize,metaGridWidthToUse, gridWidthToUse); |
| | m_gridWidth = gridWidthToUse; |
| | } |
| |
|
| | |
| | |
| | |
| | void RS_Grid::calculateGrid() { |
| | if (gridSystem->isValid() || gridSystem->isGridDisabledByPanning(m_viewport)){ |
| | return; |
| | } |
| |
|
| | RS_Vector viewZero; |
| | RS_Vector viewSize; |
| | RS_Vector metaGridWidthToUse; |
| | RS_Vector gridWidthToUse; |
| | prepareGridCalculations(viewZero, viewSize,metaGridWidthToUse, gridWidthToUse); |
| |
|
| | gridSystem->createGrid(m_viewport, viewZero, viewSize, metaGridWidthToUse, gridWidthToUse); |
| | m_gridWidth = gridWidthToUse; |
| | } |
| |
|
| | void RS_Grid::prepareGridCalculations(RS_Vector& viewZero,RS_Vector& viewSize,RS_Vector& metaGridWidthToUse,RS_Vector& gridWidthToUse){ |
| | RS_Vector gridWidth = prepareGridWidth(); |
| |
|
| | gridWidthToUse = gridWidth; |
| | metaGridWidthToUse = m_metaGridWidth; |
| | gridWidthToUse.valid = true; |
| | metaGridWidthToUse.valid = true; |
| | |
| | |
| | |
| |
|
| | bool hasInfiniteAxis = false; |
| | bool undefinedXSize = m_userGrid.x != 0; |
| | bool undefinedYSize = m_userGrid.y != 0; |
| |
|
| | hasInfiniteAxis = undefinedYSize != undefinedXSize; |
| |
|
| | QString gridInfoStr; |
| | QString metaGridInfoStr; |
| | bool squareGrid = gridWidth.x == gridWidth.y; |
| | if (!(gridWidth.x>minimumGridWidth && gridWidth.y>minimumGridWidth)){ |
| | gridWidthToUse.valid = false; |
| | metaGridWidthToUse.valid = false; |
| | } |
| | else { |
| | double gridWidthGUIX = m_viewport->toGuiDX(gridWidth.x); |
| | double gridWidthGUIY = m_viewport->toGuiDY(gridWidth.y); |
| | if (gridWidthGUIX < m_minGridSpacing || gridWidthGUIY < m_minGridSpacing){ |
| | gridWidthToUse.valid = false; |
| | } |
| | else{ |
| | if (hasInfiniteAxis){ |
| | gridInfoStr = QString("%1").arg(undefinedXSize ? gridWidth.y : gridWidth.x); |
| | } |
| | else { |
| | gridInfoStr = squareGrid ? QString("%1").arg(gridWidth.x) : QString("%1 x %2").arg(gridWidth.x).arg(gridWidth.y); |
| | } |
| | } |
| |
|
| | double metaGridWidthGUIX = m_viewport->toGuiDX(m_metaGridWidth.x); |
| | double metaGridWidthGUIY = m_viewport->toGuiDY(m_metaGridWidth.y); |
| |
|
| | if (metaGridWidthGUIX < m_minGridSpacing || metaGridWidthGUIY < m_minGridSpacing){ |
| | metaGridWidthToUse.valid = false; |
| | } |
| | else{ |
| | if (hasInfiniteAxis){ |
| | metaGridInfoStr = QString("%1").arg(undefinedXSize ? m_metaGridWidth.y : m_metaGridWidth.x); |
| | } |
| | else { |
| | metaGridInfoStr = squareGrid ? QString("%1").arg(m_metaGridWidth.x) : QString("%1 x %2").arg(m_metaGridWidth.x).arg(m_metaGridWidth.y); |
| | } |
| | } |
| | } |
| |
|
| | |
| | |
| |
|
| | viewZero = m_viewport->toUCSFromGui(0, 0); |
| | viewSize = m_viewport->toUCSFromGui(m_viewport->getWidth(), m_viewport->getHeight()); |
| |
|
| | |
| | m_gridInfoString = ""; |
| | if (gridWidthToUse.valid){ |
| | if (metaGridWidthToUse.valid){ |
| | m_gridInfoString = QString("%1 / %2").arg(gridInfoStr).arg(metaGridInfoStr); |
| | } |
| | else{ |
| | m_gridInfoString = QString("%1").arg(gridInfoStr); |
| | } |
| | } |
| | else{ |
| | if (metaGridWidthToUse.valid){ |
| | m_gridInfoString = QString("%1").arg(metaGridInfoStr); |
| | } |
| | } |
| |
|
| | gridSystem->setGridInfiniteState(hasInfiniteAxis, undefinedXSize); |
| | } |
| |
|
| | RS_Vector RS_Grid::prepareGridWidth() { |
| |
|
| | RS_Graphic* graphic = m_viewport->getGraphic(); |
| |
|
| | RS2::Unit unit = RS2::None; |
| | RS2::LinearFormat format = RS2::Decimal; |
| | if (graphic != nullptr) { |
| | unit = graphic->getUnit(); |
| | format = graphic->getLinearFormat(); |
| | } |
| |
|
| | RS_Vector gridWidth; |
| | |
| | |
| | if (RS_Units::isMetric(unit) || unit==RS2::None || |
| | format==RS2::Decimal || format==RS2::Engineering) { |
| | |
| | gridWidth = getMetricGridWidth(m_userGrid, m_scaleGrid, m_minGridSpacing); |
| |
|
| | }else { |
| | |
| | gridWidth = getImperialGridWidth(m_userGrid, m_scaleGrid, m_minGridSpacing); |
| | } |
| | return gridWidth; |
| | } |
| |
|
| |
|
| | RS_Vector RS_Grid::getMetricGridWidth(RS_Vector const &userGrid, bool scaleGrid, int minGridSpacing) { |
| | RS_Vector gridWidth; |
| |
|
| | bool hasExplicitUserGrid = false; |
| |
|
| | if (userGrid.x > 0.0) { |
| | gridWidth.x = userGrid.x; |
| | hasExplicitUserGrid = true; |
| | } else { |
| | gridWidth.x = minimumGridWidth; |
| | } |
| |
|
| | if (userGrid.y > 0.0) { |
| | gridWidth.y = userGrid.y; |
| | hasExplicitUserGrid = true; |
| | } else { |
| | gridWidth.y = minimumGridWidth; |
| | } |
| | |
| |
|
| | if (scaleGrid){ |
| | double guiGridWithX = m_viewport->toGuiDX(gridWidth.x); |
| | double guiGridWithY = m_viewport->toGuiDY(gridWidth.y); |
| | bool gridSmallerThanMin = guiGridWithX < minGridSpacing || guiGridWithY < minGridSpacing; |
| | if (gridSmallerThanMin) { |
| | do{ |
| | gridWidth *= 10; |
| | guiGridWithX = m_viewport->toGuiDX(gridWidth.x); |
| | guiGridWithY = m_viewport->toGuiDY(gridWidth.y); |
| | } |
| | while (guiGridWithX < minGridSpacing || guiGridWithY < minGridSpacing); |
| | } |
| | else if (hasExplicitUserGrid){ |
| | |
| |
|
| | RS_Vector decreasingWidth = gridWidth; |
| | RS_Vector previousWidth = decreasingWidth; |
| | while (true) { |
| | decreasingWidth /= 10; |
| |
|
| | double guiGridWithX = m_viewport->toGuiDX(decreasingWidth.x); |
| | double guiGridWithY = m_viewport->toGuiDY(decreasingWidth.y); |
| | if (guiGridWithX < minGridSpacing || guiGridWithY < minGridSpacing){ |
| | gridWidth = previousWidth; |
| | break; |
| | } |
| | else{ |
| | previousWidth = decreasingWidth; |
| | } |
| | } |
| | } |
| | } |
| |
|
| | |
| | int metaGridStep = m_metaGridEvery; |
| | m_metaGridWidth.x = gridWidth.x * metaGridStep; |
| | m_metaGridWidth.y = gridWidth.y * metaGridStep; |
| |
|
| | |
| | return gridWidth; |
| | } |
| |
|
| | RS_Vector RS_Grid::getImperialGridWidth(RS_Vector const &userGrid, bool scaleGrid, int minGridSpacing) { |
| | RS_Vector gridWidth{}; |
| | |
| | if (userGrid.x > 0.0) { |
| | gridWidth.x = userGrid.x; |
| | } else { |
| | gridWidth.x = 1.0 / 1024.0; |
| | } |
| |
|
| | if (userGrid.y > 0.0) { |
| | gridWidth.y = userGrid.y; |
| | } else { |
| | gridWidth.y = 1.0 / 1024.0; |
| | } |
| | |
| |
|
| | RS2::Unit unit = RS2::None; |
| | RS_Graphic *graphic = m_viewport->getGraphic(); |
| |
|
| | if (graphic) { |
| | unit = graphic->getUnit(); |
| | } |
| |
|
| | if (unit == RS2::Inch) { |
| | |
| |
|
| | |
| | |
| |
|
| | double guiGridWithX = m_viewport->toGuiDX(gridWidth.x); |
| | double guiGridWithY = m_viewport->toGuiDY(gridWidth.y); |
| | bool gridSmallerThanMin = guiGridWithX < minGridSpacing || guiGridWithY < minGridSpacing; |
| | if (scaleGrid || gridSmallerThanMin) { |
| | do{ |
| | if (RS_Math::round(gridWidth.x) >= 36) { |
| | gridWidth *= 2; |
| | } else if (RS_Math::round(gridWidth.x) >= 12) { |
| | gridWidth *= 3; |
| | } else if (RS_Math::round(gridWidth.x) >= 4) { |
| | gridWidth *= 3; |
| | } else if (RS_Math::round(gridWidth.x) >= 1) { |
| | gridWidth *= 2; |
| | } else { |
| | gridWidth *= 2; |
| | } |
| | guiGridWithX = m_viewport->toGuiDX(gridWidth.x); |
| | guiGridWithY = m_viewport->toGuiDY(gridWidth.y); |
| | } |
| | while (guiGridWithX < minGridSpacing || guiGridWithY < minGridSpacing); |
| | } |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| |
|
| | |
| | m_metaGridWidth.x = 1.0; |
| |
|
| | int minGridSpacingX2 = minGridSpacing * 2; |
| | if (m_viewport->toGuiDX(m_metaGridWidth.x) < minGridSpacingX2) { |
| | |
| | m_metaGridWidth.x = 12.0; |
| |
|
| | |
| | if (m_viewport->toGuiDX(m_metaGridWidth.x) < minGridSpacingX2) { |
| | m_metaGridWidth.x = 36.0; |
| |
|
| | |
| | |
| | |
| | |
| |
|
| | |
| | if (m_viewport->toGuiDX(m_metaGridWidth.x) < minGridSpacingX2) { |
| | m_metaGridWidth.x = -1.0; |
| | } |
| |
|
| | } |
| | } |
| |
|
| | |
| |
|
| | |
| | m_metaGridWidth.y = 1.0; |
| |
|
| | if (m_viewport->toGuiDY(m_metaGridWidth.y) < minGridSpacingX2) { |
| | |
| | m_metaGridWidth.y = 12.0; |
| |
|
| | |
| | if (m_viewport->toGuiDY(m_metaGridWidth.y) < minGridSpacingX2) { |
| | m_metaGridWidth.y = 36.0; |
| |
|
| | |
| | |
| | |
| | |
| |
|
| | |
| | if (m_viewport->toGuiDY(m_metaGridWidth.y) < minGridSpacingX2) { |
| | m_metaGridWidth.y = -1.0; |
| | } |
| | } |
| | } |
| | |
| | } else { |
| | |
| | if (scaleGrid) { |
| | while (m_viewport->toGuiDX(gridWidth.x) < minGridSpacing) { |
| | gridWidth.x *= 2; |
| | } |
| | m_metaGridWidth.x = -1.0; |
| |
|
| | while (m_viewport->toGuiDY(gridWidth.y) < minGridSpacing) { |
| | gridWidth.y *= 2; |
| | } |
| | m_metaGridWidth.y = -1.0; |
| | } |
| | |
| | } |
| | |
| | |
| | return gridWidth; |
| | } |
| |
|
| |
|
| | QString RS_Grid::getInfo() const { |
| | return m_gridInfoString; |
| | } |
| |
|
| | bool RS_Grid::isIsometric() const { |
| | return m_isometric; |
| | } |
| |
|
| | void RS_Grid::setIsometric(bool b) { |
| | m_isometric = b; |
| | } |
| |
|
| | RS_Vector RS_Grid::getGridWidth() const { |
| | return m_gridWidth; |
| | } |
| |
|
| | RS_Vector RS_Grid::getMetaGridWidth() const { |
| | return m_metaGridWidth; |
| | } |
| |
|
| | RS_Vector const &RS_Grid::getCellVector() const { |
| | return gridSystem->getCellVector(); |
| | } |
| |
|
| | void RS_Grid::setIsoViewType(RS2::IsoGridViewType chType) { |
| | isoViewType = chType; |
| | } |
| |
|
| | RS2::IsoGridViewType RS_Grid::getIsoViewType() const { |
| | return isoViewType; |
| | } |
| |
|
| |
|
| | void RS_Grid::drawGrid(RS_Painter *painter) { |
| | gridSystem->draw(painter, m_viewport); |
| | } |
| |
|
| | void RS_Grid::invalidate(bool gridOn) { |
| | if (gridSystem != nullptr) { |
| | gridSystem->invalidate(); |
| | if (gridOn) { |
| | calculateGrid(); |
| | } |
| | else{ |
| | calculateSnapSettings(); |
| | } |
| | } |
| | } |
| |
|