Horizon overlay and some vanishing point customization (#253)
This commit is contained in:
parent
dff5b5fdcb
commit
bd19747b0d
5 changed files with 166 additions and 25 deletions
|
@ -55,6 +55,13 @@ extern TEnv::IntVar ShowFieldGuide;
|
||||||
extern TEnv::IntVar GuideOpacity;
|
extern TEnv::IntVar GuideOpacity;
|
||||||
extern TEnv::IntVar HorizontalOffset;
|
extern TEnv::IntVar HorizontalOffset;
|
||||||
extern TEnv::IntVar VerticalOffset;
|
extern TEnv::IntVar VerticalOffset;
|
||||||
|
extern TEnv::IntVar ShowHorizon;
|
||||||
|
extern TEnv::IntVar HorizonAngle;
|
||||||
|
extern TEnv::IntVar HorizonStep;
|
||||||
|
extern TEnv::IntVar HorizonOffset;
|
||||||
|
extern TEnv::IntVar ShowVanishingPointRays;
|
||||||
|
extern TEnv::IntVar VanishingPointRayAngles;
|
||||||
|
extern TEnv::IntVar VanishingPointRayOpacity;
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// TPanel
|
// TPanel
|
||||||
|
@ -453,6 +460,52 @@ TPanelTitleBarButtonForGrids::TPanelTitleBarButtonForGrids(
|
||||||
emit updateViewer();
|
emit updateViewer();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
QGroupBox* vanishingCheckbox = new QGroupBox(tr("Vanishing Point Rays"), this);
|
||||||
|
vanishingCheckbox->setCheckable(true);
|
||||||
|
vanishingCheckbox->setChecked(ShowVanishingPointRays != 0);
|
||||||
|
connect(vanishingCheckbox, &QGroupBox::toggled, [=](bool value) {
|
||||||
|
ShowVanishingPointRays = value == true ? 1 : 0;
|
||||||
|
emit updateViewer();
|
||||||
|
});
|
||||||
|
|
||||||
|
QSlider* vanishingAngleSlider = new QSlider(this);
|
||||||
|
vanishingAngleSlider->setRange(5, 90);
|
||||||
|
vanishingAngleSlider->setValue(VanishingPointRayAngles);
|
||||||
|
vanishingAngleSlider->setOrientation(Qt::Horizontal);
|
||||||
|
vanishingAngleSlider->setMinimumWidth(300);
|
||||||
|
QLabel* vanishingAngleLabel = new QLabel(this);
|
||||||
|
vanishingAngleLabel->setText(tr("Angle: ") +
|
||||||
|
QString::number(VanishingPointRayAngles));
|
||||||
|
connect(vanishingAngleSlider, &QSlider::valueChanged, [=](int value) {
|
||||||
|
VanishingPointRayAngles = value;
|
||||||
|
vanishingAngleLabel->setText(tr("Angle: ") +
|
||||||
|
QString::number(VanishingPointRayAngles));
|
||||||
|
emit updateViewer();
|
||||||
|
});
|
||||||
|
|
||||||
|
QSlider* vanishingOpacitySlider = new QSlider(this);
|
||||||
|
vanishingOpacitySlider->setRange(1, 100);
|
||||||
|
vanishingOpacitySlider->setValue(VanishingPointRayOpacity);
|
||||||
|
vanishingOpacitySlider->setOrientation(Qt::Horizontal);
|
||||||
|
QLabel* vanishingOpacityLabel = new QLabel(this);
|
||||||
|
vanishingOpacityLabel->setText(tr("Opacity: ") +
|
||||||
|
QString::number(VanishingPointRayOpacity));
|
||||||
|
connect(vanishingOpacitySlider, &QSlider::valueChanged, [=](int value) {
|
||||||
|
VanishingPointRayOpacity = value;
|
||||||
|
vanishingOpacityLabel->setText(tr("Opacity: ") +
|
||||||
|
QString::number(VanishingPointRayOpacity));
|
||||||
|
emit updateViewer();
|
||||||
|
});
|
||||||
|
|
||||||
|
QGridLayout* vanishingLayout = new QGridLayout(this);
|
||||||
|
vanishingLayout->addWidget(vanishingAngleLabel, 0, 0, Qt::AlignRight);
|
||||||
|
vanishingAngleLabel->setFixedWidth(110);
|
||||||
|
vanishingAngleLabel->setAlignment(Qt::AlignRight);
|
||||||
|
vanishingLayout->addWidget(vanishingAngleSlider, 0, 1);
|
||||||
|
vanishingLayout->addWidget(vanishingOpacityLabel, 1, 0, Qt::AlignRight);
|
||||||
|
vanishingLayout->addWidget(vanishingOpacitySlider, 1, 1);
|
||||||
|
vanishingCheckbox->setLayout(vanishingLayout);
|
||||||
|
|
||||||
QGroupBox *horizontalCheckbox = new QGroupBox(tr("Horizontal Grid"), this);
|
QGroupBox *horizontalCheckbox = new QGroupBox(tr("Horizontal Grid"), this);
|
||||||
horizontalCheckbox->setCheckable(true);
|
horizontalCheckbox->setCheckable(true);
|
||||||
horizontalCheckbox->setChecked(ShowHorizontalGrid != 0);
|
horizontalCheckbox->setChecked(ShowHorizontalGrid != 0);
|
||||||
|
@ -544,6 +597,70 @@ TPanelTitleBarButtonForGrids::TPanelTitleBarButtonForGrids(
|
||||||
verticalLayout->addWidget(verticalOffsetSlider, 1, 1);
|
verticalLayout->addWidget(verticalOffsetSlider, 1, 1);
|
||||||
verticalCheckbox->setLayout(verticalLayout);
|
verticalCheckbox->setLayout(verticalLayout);
|
||||||
|
|
||||||
|
|
||||||
|
QGroupBox* horizonCheckbox = new QGroupBox(tr("Horizon"), this);
|
||||||
|
horizonCheckbox->setCheckable(true);
|
||||||
|
horizonCheckbox->setChecked(ShowHorizon != 0);
|
||||||
|
connect(horizonCheckbox, &QGroupBox::toggled, [=](bool value) {
|
||||||
|
ShowHorizon = value == true ? 1 : 0;
|
||||||
|
emit updateViewer();
|
||||||
|
});
|
||||||
|
|
||||||
|
QSlider* horizonAngleSlider = new QSlider(this);
|
||||||
|
horizonAngleSlider->setRange(-90, 90);
|
||||||
|
horizonAngleSlider->setValue(HorizonAngle);
|
||||||
|
horizonAngleSlider->setOrientation(Qt::Horizontal);
|
||||||
|
horizonAngleSlider->setMinimumWidth(300);
|
||||||
|
QLabel* horizonAngleLabel = new QLabel(this);
|
||||||
|
horizonAngleLabel->setText(tr("Angle: ") +
|
||||||
|
QString::number(HorizonAngle));
|
||||||
|
connect(horizonAngleSlider, &QSlider::valueChanged, [=](int value) {
|
||||||
|
HorizonAngle = value;
|
||||||
|
horizonAngleLabel->setText(tr("Angle: ") +
|
||||||
|
QString::number(HorizonAngle));
|
||||||
|
emit updateViewer();
|
||||||
|
});
|
||||||
|
|
||||||
|
QSlider* horizonStepSlider = new QSlider(this);
|
||||||
|
horizonStepSlider->setRange(2, 100);
|
||||||
|
horizonStepSlider->setValue(HorizonStep);
|
||||||
|
horizonStepSlider->setOrientation(Qt::Horizontal);
|
||||||
|
QLabel* horizonStepLabel = new QLabel(this);
|
||||||
|
horizonStepLabel->setText(tr("Step: ") +
|
||||||
|
QString::number(HorizonStep));
|
||||||
|
connect(horizonStepSlider, &QSlider::valueChanged, [=](int value) {
|
||||||
|
HorizonStep = value;
|
||||||
|
horizonStepLabel->setText(tr("Step: ") +
|
||||||
|
QString::number(HorizonStep));
|
||||||
|
emit updateViewer();
|
||||||
|
});
|
||||||
|
|
||||||
|
QSlider* horizonOffsetSlider = new QSlider(this);
|
||||||
|
horizonOffsetSlider->setRange(-500, 500);
|
||||||
|
horizonOffsetSlider->setValue(HorizonOffset);
|
||||||
|
horizonOffsetSlider->setOrientation(Qt::Horizontal);
|
||||||
|
QLabel* horizonOffsetLabel = new QLabel(this);
|
||||||
|
horizonOffsetLabel->setText(tr("Offset: ") +
|
||||||
|
QString::number(HorizonOffset));
|
||||||
|
connect(horizonOffsetSlider, &QSlider::valueChanged, [=](int value) {
|
||||||
|
HorizonOffset = value;
|
||||||
|
horizonOffsetLabel->setText(tr("Offset: ") +
|
||||||
|
QString::number(HorizonOffset));
|
||||||
|
emit updateViewer();
|
||||||
|
});
|
||||||
|
|
||||||
|
QGridLayout* horizonLayout = new QGridLayout(this);
|
||||||
|
horizonLayout->addWidget(horizonAngleLabel, 0, 0, Qt::AlignRight);
|
||||||
|
horizonAngleLabel->setFixedWidth(110);
|
||||||
|
horizonAngleLabel->setAlignment(Qt::AlignRight);
|
||||||
|
horizonLayout->addWidget(horizonAngleSlider, 0, 1);
|
||||||
|
horizonLayout->addWidget(horizonStepLabel, 1, 0, Qt::AlignRight);
|
||||||
|
horizonLayout->addWidget(horizonStepSlider, 1, 1);
|
||||||
|
horizonLayout->addWidget(horizonOffsetLabel, 2, 0, Qt::AlignRight);
|
||||||
|
horizonLayout->addWidget(horizonOffsetSlider, 2, 1);
|
||||||
|
horizonCheckbox->setLayout(horizonLayout);
|
||||||
|
|
||||||
|
|
||||||
QGroupBox *isometricCheckbox = new QGroupBox(tr("Isometric Grid"), this);
|
QGroupBox *isometricCheckbox = new QGroupBox(tr("Isometric Grid"), this);
|
||||||
isometricCheckbox->setCheckable(true);
|
isometricCheckbox->setCheckable(true);
|
||||||
isometricCheckbox->setChecked(ShowIsometricGrid != 0);
|
isometricCheckbox->setChecked(ShowIsometricGrid != 0);
|
||||||
|
@ -639,10 +756,13 @@ TPanelTitleBarButtonForGrids::TPanelTitleBarButtonForGrids(
|
||||||
gridLayout->addWidget(fieldGuideCheckbox, 2, 0, 1, 2);
|
gridLayout->addWidget(fieldGuideCheckbox, 2, 0, 1, 2);
|
||||||
gridLayout->addWidget(horizontalCheckbox, 3, 0, 1, 2);
|
gridLayout->addWidget(horizontalCheckbox, 3, 0, 1, 2);
|
||||||
gridLayout->addWidget(verticalCheckbox, 4, 0, 1, 2);
|
gridLayout->addWidget(verticalCheckbox, 4, 0, 1, 2);
|
||||||
gridLayout->addWidget(isometricCheckbox, 5, 0, 1, 2);
|
|
||||||
gridLayout->addWidget(guideOpacityLabel, 6, 0);
|
|
||||||
gridLayout->addWidget(guideOpacitySlider, 6, 1);
|
|
||||||
|
|
||||||
|
gridLayout->addWidget(horizonCheckbox, 5, 0, 1, 2);
|
||||||
|
gridLayout->addWidget(isometricCheckbox, 6, 0, 1, 2);
|
||||||
|
gridLayout->addWidget(vanishingCheckbox, 7, 0, 1, 2);
|
||||||
|
|
||||||
|
gridLayout->addWidget(guideOpacityLabel, 8, 0);
|
||||||
|
gridLayout->addWidget(guideOpacitySlider, 8, 1);
|
||||||
gridWidget->setLayout(gridLayout);
|
gridWidget->setLayout(gridLayout);
|
||||||
gridsAction->setDefaultWidget(gridWidget);
|
gridsAction->setDefaultWidget(gridWidget);
|
||||||
m_menu->addAction(gridsAction);
|
m_menu->addAction(gridsAction);
|
||||||
|
|
|
@ -780,7 +780,6 @@ SceneViewer::SceneViewer(ImageUtils::FullScreenWidget *parent)
|
||||||
, m_toolDisableReason("")
|
, m_toolDisableReason("")
|
||||||
, m_editPreviewSubCamera(false)
|
, m_editPreviewSubCamera(false)
|
||||||
, m_locator(NULL)
|
, m_locator(NULL)
|
||||||
, m_showPerspectiveGrids(ShowPerspectiveGrids)
|
|
||||||
, m_isLocator(false)
|
, m_isLocator(false)
|
||||||
, m_isBusyOnTabletMove(false) {
|
, m_isBusyOnTabletMove(false) {
|
||||||
m_visualSettings.m_sceneProperties =
|
m_visualSettings.m_sceneProperties =
|
||||||
|
@ -1724,7 +1723,7 @@ void SceneViewer::drawOverlay() {
|
||||||
// draw tool gadgets
|
// draw tool gadgets
|
||||||
TTool *tool = app->getCurrentTool()->getTool();
|
TTool *tool = app->getCurrentTool()->getTool();
|
||||||
TXshSimpleLevel *sl = app->getCurrentLevel()->getSimpleLevel();
|
TXshSimpleLevel *sl = app->getCurrentLevel()->getSimpleLevel();
|
||||||
if (sl && m_showPerspectiveGrids) {
|
if (sl) {
|
||||||
std::vector<TPointD> assistantPoints =
|
std::vector<TPointD> assistantPoints =
|
||||||
sl->getProperties()->getVanishingPoints();
|
sl->getProperties()->getVanishingPoints();
|
||||||
if (assistantPoints.size() > 0) {
|
if (assistantPoints.size() > 0) {
|
||||||
|
@ -3360,11 +3359,4 @@ void SceneViewer::registerContext() {
|
||||||
TGlContext tglContext(tglGetCurrentContext());
|
TGlContext tglContext(tglGetCurrentContext());
|
||||||
TGLDisplayListsManager::instance()->attachContext(displayListId, tglContext);
|
TGLDisplayListsManager::instance()->attachContext(displayListId, tglContext);
|
||||||
l_contexts.insert(tglContext);
|
l_contexts.insert(tglContext);
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
void SceneViewer::setShowPerspectiveGrids(bool show) {
|
|
||||||
m_showPerspectiveGrids = show;
|
|
||||||
ShowPerspectiveGrids = show ? 1 : 0;
|
|
||||||
}
|
}
|
|
@ -167,7 +167,6 @@ class SceneViewer final : public GLWidgetForHighDpi,
|
||||||
TRectD m_clipRect;
|
TRectD m_clipRect;
|
||||||
|
|
||||||
bool m_isPicking;
|
bool m_isPicking;
|
||||||
bool m_showPerspectiveGrids = true;
|
|
||||||
bool m_canShowPerspectiveGrids = false;
|
bool m_canShowPerspectiveGrids = false;
|
||||||
|
|
||||||
TRaster32P m_3DSideL;
|
TRaster32P m_3DSideL;
|
||||||
|
@ -266,9 +265,6 @@ public:
|
||||||
m_vRuler = v;
|
m_vRuler = v;
|
||||||
m_hRuler = h;
|
m_hRuler = h;
|
||||||
}
|
}
|
||||||
bool getShowPerspectiveGrids() { return m_showPerspectiveGrids; }
|
|
||||||
void setShowPerspectiveGrids(bool show);
|
|
||||||
bool getCanShowPerspectiveGrids() { return m_canShowPerspectiveGrids; }
|
|
||||||
|
|
||||||
bool is3DView() const override;
|
bool is3DView() const override;
|
||||||
TDimension getViewportSize() const { return TDimension(width(), height()); }
|
TDimension getViewportSize() const { return TDimension(width(), height()); }
|
||||||
|
|
|
@ -137,13 +137,6 @@ SceneViewerContextMenu::SceneViewerContextMenu(SceneViewer *parent)
|
||||||
if (Preferences::instance()->isOnionSkinEnabled() &&
|
if (Preferences::instance()->isOnionSkinEnabled() &&
|
||||||
!parent->isPreviewEnabled())
|
!parent->isPreviewEnabled())
|
||||||
OnioniSkinMaskGUI::addOnionSkinCommand(this);
|
OnioniSkinMaskGUI::addOnionSkinCommand(this);
|
||||||
if (parent->getCanShowPerspectiveGrids()) {
|
|
||||||
action = new QAction(tr("Toggle Perspective Grid"), this);
|
|
||||||
connect(action, &QAction::triggered, [=]() {
|
|
||||||
parent->setShowPerspectiveGrids(!parent->getShowPerspectiveGrids());
|
|
||||||
});
|
|
||||||
addAction(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tool->getTargetType() & TTool::VectorImage) {
|
if (tool->getTargetType() & TTool::VectorImage) {
|
||||||
auto addOptionAction = [](const QString &label, const int data,
|
auto addOptionAction = [](const QString &label, const int data,
|
||||||
|
|
|
@ -52,6 +52,13 @@ TEnv::IntVar HorizontalOffset("HorizontalOffset", 0);
|
||||||
TEnv::IntVar VerticalOffset("VerticalOffset", 0);
|
TEnv::IntVar VerticalOffset("VerticalOffset", 0);
|
||||||
TEnv::IntVar ShowFieldGuide("ShowFieldGuide", 0);
|
TEnv::IntVar ShowFieldGuide("ShowFieldGuide", 0);
|
||||||
TEnv::IntVar GuideOpacity("GuideOpacity", 70);
|
TEnv::IntVar GuideOpacity("GuideOpacity", 70);
|
||||||
|
TEnv::IntVar ShowHorizon("ShowHorizon", 0);
|
||||||
|
TEnv::IntVar HorizonAngle("HorizonAngle", 0);
|
||||||
|
TEnv::IntVar HorizonStep("HorizonStep", 5);
|
||||||
|
TEnv::IntVar HorizonOffset("HorizonOffset", 0);
|
||||||
|
TEnv::IntVar ShowVanishingPointRays("ShowVanishingPointRays", 1);
|
||||||
|
TEnv::IntVar VanishingPointRayAngles("VanishingPointRayAngles", 10);
|
||||||
|
TEnv::IntVar VanishingPointRayOpacity("VanishingPointRayOpacity", 80);
|
||||||
|
|
||||||
/* TODO, move to include */
|
/* TODO, move to include */
|
||||||
void getSafeAreaSizeList(QList<QList<double>> &_sizeList);
|
void getSafeAreaSizeList(QList<QList<double>> &_sizeList);
|
||||||
|
@ -395,6 +402,8 @@ void ViewerDraw::drawGridAndGuides(SceneViewer *viewer, double sc, Ruler *vr,
|
||||||
|
|
||||||
void ViewerDraw::drawPerspectiveGuides(SceneViewer *viewer, double sc,
|
void ViewerDraw::drawPerspectiveGuides(SceneViewer *viewer, double sc,
|
||||||
std::vector<TPointD> assistantPoints) {
|
std::vector<TPointD> assistantPoints) {
|
||||||
|
|
||||||
|
if (ShowVanishingPointRays == 0) return;
|
||||||
int x1, x2, y1, y2;
|
int x1, x2, y1, y2;
|
||||||
viewer->rect().getCoords(&x1, &y1, &x2, &y2);
|
viewer->rect().getCoords(&x1, &y1, &x2, &y2);
|
||||||
TRect clipRect = TRect(x1, y1, x2 + 1, y2 + 1);
|
TRect clipRect = TRect(x1, y1, x2 + 1, y2 + 1);
|
||||||
|
@ -441,7 +450,7 @@ void ViewerDraw::drawPerspectiveGuides(SceneViewer *viewer, double sc,
|
||||||
TPointD p = assistantPoints.at(j);
|
TPointD p = assistantPoints.at(j);
|
||||||
if (j < 5)
|
if (j < 5)
|
||||||
glColor4d(reds.at(j), greens.at(j), blues.at(j),
|
glColor4d(reds.at(j), greens.at(j), blues.at(j),
|
||||||
(double)GuideOpacity / 100.0);
|
(double)VanishingPointRayOpacity / 100.0);
|
||||||
TPointD end;
|
TPointD end;
|
||||||
double distanceToLeft = std::abs(p.x - bounds.x0);
|
double distanceToLeft = std::abs(p.x - bounds.x0);
|
||||||
double distanceToRight = std::abs(p.x - bounds.x1);
|
double distanceToRight = std::abs(p.x - bounds.x1);
|
||||||
|
@ -451,7 +460,7 @@ void ViewerDraw::drawPerspectiveGuides(SceneViewer *viewer, double sc,
|
||||||
double yDistance = std::max(distanceToTop, distanceToBottom);
|
double yDistance = std::max(distanceToTop, distanceToBottom);
|
||||||
double totalDistance =
|
double totalDistance =
|
||||||
std::sqrt(std::pow(xDistance, 2) + std::pow(yDistance, 2));
|
std::sqrt(std::pow(xDistance, 2) + std::pow(yDistance, 2));
|
||||||
for (int i = 0; i < 360; i += 5) {
|
for (int i = 0; i < 360; i += VanishingPointRayAngles) {
|
||||||
double yLength = std::sin(i * (3.14159 / 180)) * totalDistance;
|
double yLength = std::sin(i * (3.14159 / 180)) * totalDistance;
|
||||||
double xLength = std::cos(i * (3.14159 / 180)) * totalDistance;
|
double xLength = std::cos(i * (3.14159 / 180)) * totalDistance;
|
||||||
end.x = p.x + xLength;
|
end.x = p.x + xLength;
|
||||||
|
@ -781,6 +790,37 @@ void ViewerDraw::drawGridsAndOverlays(SceneViewer *viewer, double pixelSize) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ShowHorizon) {
|
||||||
|
double theta = (double)HorizonAngle * (3.14159 / 180);
|
||||||
|
double step = HorizonStep;
|
||||||
|
double run = std::cos(theta) * step;
|
||||||
|
double rise = std::sin(theta) * step;
|
||||||
|
double slope = rise / run;
|
||||||
|
double distance = step;
|
||||||
|
{
|
||||||
|
// find the first y value
|
||||||
|
double startY = (slope * bounds.x0) + (HorizonOffset / Stage::standardDpi * Stage::inch);
|
||||||
|
double endY = (slope * bounds.x1) + (HorizonOffset / Stage::standardDpi * Stage::inch);
|
||||||
|
|
||||||
|
if (slope == 0.0) {
|
||||||
|
startY = (rect.y0 + ((rect.y1 - rect.y0) / 2)) + (HorizonOffset / Stage::standardDpi * Stage::inch);
|
||||||
|
endY = startY;
|
||||||
|
}
|
||||||
|
|
||||||
|
double i = 1.5;
|
||||||
|
while (endY > bounds.y0 || startY > bounds.y0) {
|
||||||
|
glBegin(GL_LINES);
|
||||||
|
glVertex2d(bounds.x0, startY);
|
||||||
|
glVertex2d(bounds.x1, endY);
|
||||||
|
glEnd();
|
||||||
|
endY -= distance / Stage::standardDpi * Stage::inch;
|
||||||
|
startY -= distance / Stage::standardDpi * Stage::inch;
|
||||||
|
distance += step * i;
|
||||||
|
step = step * i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ShowIsometricGrid) {
|
if (ShowIsometricGrid) {
|
||||||
double rightTheta = (double)IsometricRightAngle * (3.14159 / 180);
|
double rightTheta = (double)IsometricRightAngle * (3.14159 / 180);
|
||||||
double rightStep = IsometricRightStep;
|
double rightStep = IsometricRightStep;
|
||||||
|
|
Loading…
Reference in a new issue