Add perspective grids to vanishing points (#185)

* Add perspective grids to vanishing points

* Limit tools
This commit is contained in:
Jeremy Bullock 2020-09-19 22:06:44 -06:00 committed by GitHub
parent 3378ef99cd
commit 28366ac752
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 407 additions and 263 deletions

View file

@ -335,6 +335,7 @@ void FullColorBrushTool::leftButtonDown(const TPointD &pos,
if (!deletedPoint) m_assistantPoints.push_back(pos);
simLevel->getProperties()->setVanishingPoints(m_assistantPoints);
level->setDirtyFlag(true);
invalidate();
return;
}
if (e.isAltPressed() && e.isShiftPressed() && !e.isCtrlPressed()) {
@ -503,53 +504,48 @@ void FullColorBrushTool::leftButtonDrag(const TPointD &pos,
invalidateRect += (brushRect);
double denominator = m_lastPoint.x - m_firstPoint.x;
if (denominator == 0) denominator == 0.001;
double slope = ((m_lastPoint.y - m_firstPoint.y) / denominator);
double slope = ((m_lastPoint.y - m_firstPoint.y) / denominator);
double radAngle = std::atan(abs(slope));
double angle = radAngle * (180 / 3.14159);
double angle = radAngle * (180 / 3.14159);
if (abs(angle) >= 82.5)
m_lastPoint.x = m_firstPoint.x;
else if (abs(angle) < 7.5)
m_lastPoint.y = m_firstPoint.y;
else {
double xDistance = m_lastPoint.x - m_firstPoint.x;
double yDistance = m_lastPoint.y - m_firstPoint.y;
double xDistance = m_lastPoint.x - m_firstPoint.x;
double yDistance = m_lastPoint.y - m_firstPoint.y;
double totalDistance = std::sqrt(std::pow(xDistance, 2) + std::pow(yDistance, 2));
double xLength = 0.0;
double yLength = 0.0;
if (angle >= 7.5 && angle < 22.5) {
yLength = std::sin(15 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(15 * (3.14159 / 180)) * totalDistance;
}
else if (angle >= 22.5 && angle < 37.5) {
yLength = std::sin(30 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(30 * (3.14159 / 180)) * totalDistance;
}
else if (angle >= 37.5 && angle < 52.5) {
yLength = std::sin(45 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(45 * (3.14159 / 180)) * totalDistance;
}
else if (angle >= 52.5 && angle < 67.5) {
yLength = std::sin(60 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(60 * (3.14159 / 180)) * totalDistance;
}
else if (angle >= 67.5 && angle < 82.5) {
yLength = std::sin(75 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(75 * (3.14159 / 180)) * totalDistance;
}
double totalDistance =
std::sqrt(std::pow(xDistance, 2) + std::pow(yDistance, 2));
double xLength = 0.0;
double yLength = 0.0;
if (angle >= 7.5 && angle < 22.5) {
yLength = std::sin(15 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(15 * (3.14159 / 180)) * totalDistance;
} else if (angle >= 22.5 && angle < 37.5) {
yLength = std::sin(30 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(30 * (3.14159 / 180)) * totalDistance;
} else if (angle >= 37.5 && angle < 52.5) {
yLength = std::sin(45 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(45 * (3.14159 / 180)) * totalDistance;
} else if (angle >= 52.5 && angle < 67.5) {
yLength = std::sin(60 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(60 * (3.14159 / 180)) * totalDistance;
} else if (angle >= 67.5 && angle < 82.5) {
yLength = std::sin(75 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(75 * (3.14159 / 180)) * totalDistance;
}
if (yDistance == abs(yDistance)) {
m_lastPoint.y = m_firstPoint.y + yLength;
}
else {
m_lastPoint.y = m_firstPoint.y - yLength;
}
if (xDistance == abs(xDistance)) {
m_lastPoint.x = m_firstPoint.x + xLength;
}
else {
m_lastPoint.x = m_firstPoint.x - xLength;
}
if (yDistance == abs(yDistance)) {
m_lastPoint.y = m_firstPoint.y + yLength;
} else {
m_lastPoint.y = m_firstPoint.y - yLength;
}
if (xDistance == abs(xDistance)) {
m_lastPoint.x = m_firstPoint.x + xLength;
} else {
m_lastPoint.x = m_firstPoint.x - xLength;
}
}
}

View file

@ -1270,6 +1270,7 @@ void ToonzRasterBrushTool::leftButtonDown(const TPointD &pos,
if (!deletedPoint) m_assistantPoints.push_back(pos);
simLevel->getProperties()->setVanishingPoints(m_assistantPoints);
level->setDirtyFlag(true);
invalidate();
return;
}
if (e.isAltPressed() && e.isShiftPressed() && !e.isCtrlPressed()) {
@ -1537,56 +1538,49 @@ void ToonzRasterBrushTool::leftButtonDrag(const TPointD &pos,
double denominator = m_lastPoint.x - m_firstPoint.x;
if (denominator == 0) denominator == 0.001;
double slope = ((m_lastPoint.y - m_firstPoint.y) / denominator);
double slope = ((m_lastPoint.y - m_firstPoint.y) / denominator);
double radAngle = std::atan(abs(slope));
double angle = radAngle * (180 / 3.14159);
double angle = radAngle * (180 / 3.14159);
if (abs(angle) >= 82.5) {
// make it vertical
m_lastPoint.x = m_firstPoint.x;
}
else if (abs(angle) < 7.5) {
// make it horizontal
m_lastPoint.y = m_firstPoint.y;
}
else {
// make it vertical
m_lastPoint.x = m_firstPoint.x;
} else if (abs(angle) < 7.5) {
// make it horizontal
m_lastPoint.y = m_firstPoint.y;
} else {
double xDistance = m_lastPoint.x - m_firstPoint.x;
double yDistance = m_lastPoint.y - m_firstPoint.y;
double totalDistance = std::sqrt(std::pow(xDistance, 2) + std::pow(yDistance, 2));
double totalDistance =
std::sqrt(std::pow(xDistance, 2) + std::pow(yDistance, 2));
double xLength = 0.0;
double yLength = 0.0;
if (angle >= 7.5 && angle < 22.5) {
yLength = std::sin(15 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(15 * (3.14159 / 180)) * totalDistance;
}
else if (angle >= 22.5 && angle < 37.5) {
yLength = std::sin(30 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(30 * (3.14159 / 180)) * totalDistance;
}
else if (angle >= 37.5 && angle < 52.5) {
yLength = std::sin(45 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(45 * (3.14159 / 180)) * totalDistance;
}
else if (angle >= 52.5 && angle < 67.5) {
yLength = std::sin(60 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(60 * (3.14159 / 180)) * totalDistance;
}
else if (angle >= 67.5 && angle < 82.5) {
yLength = std::sin(75 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(75 * (3.14159 / 180)) * totalDistance;
yLength = std::sin(15 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(15 * (3.14159 / 180)) * totalDistance;
} else if (angle >= 22.5 && angle < 37.5) {
yLength = std::sin(30 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(30 * (3.14159 / 180)) * totalDistance;
} else if (angle >= 37.5 && angle < 52.5) {
yLength = std::sin(45 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(45 * (3.14159 / 180)) * totalDistance;
} else if (angle >= 52.5 && angle < 67.5) {
yLength = std::sin(60 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(60 * (3.14159 / 180)) * totalDistance;
} else if (angle >= 67.5 && angle < 82.5) {
yLength = std::sin(75 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(75 * (3.14159 / 180)) * totalDistance;
}
if (yDistance == abs(yDistance)) {
m_lastPoint.y = m_firstPoint.y + yLength;
}
else {
m_lastPoint.y = m_firstPoint.y - yLength;
m_lastPoint.y = m_firstPoint.y + yLength;
} else {
m_lastPoint.y = m_firstPoint.y - yLength;
}
if (xDistance == abs(xDistance)) {
m_lastPoint.x = m_firstPoint.x + xLength;
}
else {
m_lastPoint.x = m_firstPoint.x - xLength;
m_lastPoint.x = m_firstPoint.x + xLength;
} else {
m_lastPoint.x = m_firstPoint.x - xLength;
}
}
}

View file

@ -750,6 +750,7 @@ void ToonzVectorBrushTool::leftButtonDown(const TPointD &pos,
if (!deletedPoint) m_assistantPoints.push_back(pos);
simLevel->getProperties()->setVanishingPoints(m_assistantPoints);
level->setDirtyFlag(true);
invalidate();
return;
}
@ -789,150 +790,150 @@ void ToonzVectorBrushTool::leftButtonDrag(const TPointD &pos,
return;
}
if ((e.isCtrlPressed() && e.isAltPressed() && !e.isShiftPressed()) || m_addingAssistant) {
if ((e.isCtrlPressed() && e.isAltPressed() && !e.isShiftPressed()) ||
m_addingAssistant) {
return;
}
TRectD invalidateRect;
m_lastPoint = pos;
m_lastPoint = pos;
bool nonShiftStraight = false;
if (e.isAltPressed() && !e.isCtrlPressed() && !e.isShiftPressed()) {
invalidateRect = TRectD(m_firstPoint, m_lastPoint).enlarge(2);
nonShiftStraight = true;
double distance = (m_brushPos.x) * 0.5;
TRectD brushRect =
TRectD(TPointD(m_brushPos.x - distance, m_brushPos.y - distance),
TPointD(m_brushPos.x + distance, m_brushPos.y + distance));
invalidateRect += (brushRect);
if (e.isAltPressed() && !e.isCtrlPressed() && !e.isShiftPressed()) {
invalidateRect = TRectD(m_firstPoint, m_lastPoint).enlarge(2);
nonShiftStraight = true;
double distance = (m_brushPos.x) * 0.5;
TRectD brushRect =
TRectD(TPointD(m_brushPos.x - distance, m_brushPos.y - distance),
TPointD(m_brushPos.x + distance, m_brushPos.y + distance));
invalidateRect += (brushRect);
// let's get info about our current location
double denominator = m_lastPoint.x - m_firstPoint.x;
double numerator = m_lastPoint.y - m_firstPoint.y;
if (areAlmostEqual(denominator, 0.0, 0.0001)) {
denominator = denominator < 0 ? -0.0001 : 0.0001;
// let's get info about our current location
double denominator = m_lastPoint.x - m_firstPoint.x;
double numerator = m_lastPoint.y - m_firstPoint.y;
if (areAlmostEqual(denominator, 0.0, 0.0001)) {
denominator = denominator < 0 ? -0.0001 : 0.0001;
}
if (areAlmostEqual(numerator, 0.0, 0.0001)) {
numerator = numerator < 0 ? -0.0001 : 0.0001;
}
double slope = (numerator / denominator);
double angle = std::atan(slope) * (180 / 3.14159);
// now let's get the angle of each of the assistant points
std::vector<double> anglesToAssistants;
for (auto point : m_assistantPoints) {
double newDenominator = point.x - m_firstPoint.x;
double newNumerator = point.y - m_firstPoint.y;
if (areAlmostEqual(newDenominator, 0.0, 0.0001)) {
newDenominator = newDenominator < 0 ? -0.0001 : 0.0001;
}
if (areAlmostEqual(numerator, 0.0, 0.0001)) {
numerator = numerator < 0 ? -0.0001 : 0.0001;
}
double slope = (numerator / denominator);
double angle = std::atan(slope) * (180 / 3.14159);
// now let's get the angle of each of the assistant points
std::vector<double> anglesToAssistants;
for (auto point : m_assistantPoints) {
double newDenominator = point.x - m_firstPoint.x;
double newNumerator = point.y - m_firstPoint.y;
if (areAlmostEqual(newDenominator, 0.0, 0.0001)) {
newDenominator = newDenominator < 0 ? -0.0001 : 0.0001;
}
if (areAlmostEqual(newNumerator, 0.0, 0.0001)) {
newNumerator = newNumerator < 0 ? -0.0001 : 0.0001;
}
double newSlope = (newNumerator / newDenominator);
double newAngle = std::atan(newSlope) * (180 / 3.14159);
anglesToAssistants.push_back(newAngle);
if (areAlmostEqual(newNumerator, 0.0, 0.0001)) {
newNumerator = newNumerator < 0 ? -0.0001 : 0.0001;
}
// figure out which angle is closer
TPointD pointToUse = TPointD(0.0, 0.0);
double difference = 360;
double newSlope = (newNumerator / newDenominator);
double newAngle = std::atan(newSlope) * (180 / 3.14159);
anglesToAssistants.push_back(newAngle);
}
for (int i = 0; i < anglesToAssistants.size(); i++) {
double newDifference = abs(angle - anglesToAssistants.at(i));
if (newDifference < difference || (180 - newDifference) < difference) {
difference = std::min(newDifference, (180 - newDifference));
pointToUse = m_assistantPoints.at(i);
}
}
// figure out which angle is closer
TPointD pointToUse = TPointD(0.0, 0.0);
double difference = 360;
double distanceFirstToLast =
std::sqrt(std::pow((m_lastPoint.x - m_firstPoint.x), 2) +
std::pow((m_lastPoint.y - m_firstPoint.y), 2));
double distanceLastToAssistant =
std::sqrt(std::pow((pointToUse.x - m_lastPoint.x), 2) +
std::pow((pointToUse.y - m_lastPoint.y), 2));
double distanceFirstToAssistant =
std::sqrt(std::pow((pointToUse.x - m_firstPoint.x), 2) +
std::pow((pointToUse.y - m_firstPoint.y), 2));
if (distanceFirstToAssistant == 0.0) distanceFirstToAssistant = 0.001;
double ratio = distanceFirstToLast / distanceFirstToAssistant;
double newX;
double newY;
// flip the direction if the last point is farther than the first point
if (distanceFirstToAssistant < distanceLastToAssistant &&
distanceFirstToLast < distanceLastToAssistant) {
newX = ((1 + ratio) * m_firstPoint.x) - (ratio * pointToUse.x);
newY = ((1 + ratio) * m_firstPoint.y) - (ratio * pointToUse.y);
} else {
newX = ((1 - ratio) * m_firstPoint.x) + (ratio * pointToUse.x);
newY = ((1 - ratio) * m_firstPoint.y) + (ratio * pointToUse.y);
}
m_lastPoint = TPointD(newX, newY);
invalidateRect += TRectD(m_firstPoint, m_lastPoint).enlarge(2);
} else if (e.isCtrlPressed() && !e.isAltPressed() && !e.isShiftPressed()) {
invalidateRect = TRectD(m_firstPoint, m_lastPoint).enlarge(2);
nonShiftStraight = true;
double distance = (m_brushPos.x) * 0.5;
TRectD brushRect =
TRectD(TPointD(m_brushPos.x - distance, m_brushPos.y - distance),
TPointD(m_brushPos.x + distance, m_brushPos.y + distance));
invalidateRect += (brushRect);
double denominator = m_lastPoint.x - m_firstPoint.x;
if (denominator == 0) denominator == 0.001;
double slope = ((m_lastPoint.y - m_firstPoint.y) / denominator);
double radAngle = std::atan(abs(slope));
double angle = radAngle * (180 / 3.14159);
if (abs(angle) >= 82.5) {
// make it vertical
m_lastPoint.x = m_firstPoint.x;
} else if (abs(angle) < 7.5) {
// make it horizontal
m_lastPoint.y = m_firstPoint.y;
} else {
double xDistance = m_lastPoint.x - m_firstPoint.x;
double yDistance = m_lastPoint.y - m_firstPoint.y;
double totalDistance =
std::sqrt(std::pow(xDistance, 2) + std::pow(yDistance, 2));
double xLength = 0.0;
double yLength = 0.0;
if (angle >= 7.5 && angle < 22.5) {
yLength = std::sin(15 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(15 * (3.14159 / 180)) * totalDistance;
} else if (angle >= 22.5 && angle < 37.5) {
yLength = std::sin(30 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(30 * (3.14159 / 180)) * totalDistance;
} else if (angle >= 37.5 && angle < 52.5) {
yLength = std::sin(45 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(45 * (3.14159 / 180)) * totalDistance;
} else if (angle >= 52.5 && angle < 67.5) {
yLength = std::sin(60 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(60 * (3.14159 / 180)) * totalDistance;
} else if (angle >= 67.5 && angle < 82.5) {
yLength = std::sin(75 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(75 * (3.14159 / 180)) * totalDistance;
}
if (yDistance == abs(yDistance)) {
m_lastPoint.y = m_firstPoint.y + yLength;
} else {
m_lastPoint.y = m_firstPoint.y - yLength;
}
if (xDistance == abs(xDistance)) {
m_lastPoint.x = m_firstPoint.x + xLength;
} else {
m_lastPoint.x = m_firstPoint.x - xLength;
}
for (int i = 0; i < anglesToAssistants.size(); i++) {
double newDifference = abs(angle - anglesToAssistants.at(i));
if (newDifference < difference || (180 - newDifference) < difference) {
difference = std::min(newDifference, (180 - newDifference));
pointToUse = m_assistantPoints.at(i);
}
}
double distanceFirstToLast =
std::sqrt(std::pow((m_lastPoint.x - m_firstPoint.x), 2) +
std::pow((m_lastPoint.y - m_firstPoint.y), 2));
double distanceLastToAssistant =
std::sqrt(std::pow((pointToUse.x - m_lastPoint.x), 2) +
std::pow((pointToUse.y - m_lastPoint.y), 2));
double distanceFirstToAssistant =
std::sqrt(std::pow((pointToUse.x - m_firstPoint.x), 2) +
std::pow((pointToUse.y - m_firstPoint.y), 2));
if (distanceFirstToAssistant == 0.0) distanceFirstToAssistant = 0.001;
double ratio = distanceFirstToLast / distanceFirstToAssistant;
double newX;
double newY;
// flip the direction if the last point is farther than the first point
if (distanceFirstToAssistant < distanceLastToAssistant &&
distanceFirstToLast < distanceLastToAssistant) {
newX = ((1 + ratio) * m_firstPoint.x) - (ratio * pointToUse.x);
newY = ((1 + ratio) * m_firstPoint.y) - (ratio * pointToUse.y);
} else {
newX = ((1 - ratio) * m_firstPoint.x) + (ratio * pointToUse.x);
newY = ((1 - ratio) * m_firstPoint.y) + (ratio * pointToUse.y);
}
m_lastPoint = TPointD(newX, newY);
invalidateRect += TRectD(m_firstPoint, m_lastPoint).enlarge(2);
} else if (e.isCtrlPressed() && !e.isAltPressed() && !e.isShiftPressed()) {
invalidateRect = TRectD(m_firstPoint, m_lastPoint).enlarge(2);
nonShiftStraight = true;
double distance = (m_brushPos.x) * 0.5;
TRectD brushRect =
TRectD(TPointD(m_brushPos.x - distance, m_brushPos.y - distance),
TPointD(m_brushPos.x + distance, m_brushPos.y + distance));
invalidateRect += (brushRect);
double denominator = m_lastPoint.x - m_firstPoint.x;
if (denominator == 0) denominator == 0.001;
double slope = ((m_lastPoint.y - m_firstPoint.y) / denominator);
double radAngle = std::atan(abs(slope));
double angle = radAngle * (180 / 3.14159);
if (abs(angle) >= 82.5) {
// make it vertical
m_lastPoint.x = m_firstPoint.x;
} else if (abs(angle) < 7.5) {
// make it horizontal
m_lastPoint.y = m_firstPoint.y;
} else {
double xDistance = m_lastPoint.x - m_firstPoint.x;
double yDistance = m_lastPoint.y - m_firstPoint.y;
double totalDistance =
std::sqrt(std::pow(xDistance, 2) + std::pow(yDistance, 2));
double xLength = 0.0;
double yLength = 0.0;
if (angle >= 7.5 && angle < 22.5) {
yLength = std::sin(15 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(15 * (3.14159 / 180)) * totalDistance;
} else if (angle >= 22.5 && angle < 37.5) {
yLength = std::sin(30 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(30 * (3.14159 / 180)) * totalDistance;
} else if (angle >= 37.5 && angle < 52.5) {
yLength = std::sin(45 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(45 * (3.14159 / 180)) * totalDistance;
} else if (angle >= 52.5 && angle < 67.5) {
yLength = std::sin(60 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(60 * (3.14159 / 180)) * totalDistance;
} else if (angle >= 67.5 && angle < 82.5) {
yLength = std::sin(75 * (3.14159 / 180)) * totalDistance;
xLength = std::cos(75 * (3.14159 / 180)) * totalDistance;
}
if (yDistance == abs(yDistance)) {
m_lastPoint.y = m_firstPoint.y + yLength;
} else {
m_lastPoint.y = m_firstPoint.y - yLength;
}
if (xDistance == abs(xDistance)) {
m_lastPoint.x = m_firstPoint.x + xLength;
} else {
m_lastPoint.x = m_firstPoint.x - xLength;
}
}
}
m_lastDragPos = pos;
m_lastDragEvent = e;
@ -962,19 +963,19 @@ void ToonzVectorBrushTool::leftButtonDrag(const TPointD &pos,
m_toggleSnap = !e.isAltPressed() && e.isCtrlPressed() && e.isShiftPressed();
if (!nonShiftStraight) {
checkStrokeSnapping(false, m_toggleSnap);
checkGuideSnapping(false, m_toggleSnap);
m_brushPos = m_lastSnapPoint;
}
else {
m_brushPos = m_lastPoint;
checkStrokeSnapping(false, m_toggleSnap);
checkGuideSnapping(false, m_toggleSnap);
m_brushPos = m_lastSnapPoint;
} else {
m_brushPos = m_lastPoint;
}
if (m_foundLastSnap)
invalidateRect +=
TRectD(m_lastSnapPoint - snapThick, m_lastSnapPoint + snapThick);
if ((e.isShiftPressed() && !e.isCtrlPressed() && !e.isAltPressed()) || nonShiftStraight) {
if ((e.isShiftPressed() && !e.isCtrlPressed() && !e.isAltPressed()) ||
nonShiftStraight) {
m_smoothStroke.clearPoints();
m_track.add(TThickPoint(m_brushPos, thickness),
getPixelSize() * getPixelSize());
@ -1014,21 +1015,24 @@ void ToonzVectorBrushTool::leftButtonUp(const TPointD &pos,
return;
}
if ((e.isAltPressed() && e.isCtrlPressed() && !e.isShiftPressed()) || m_addingAssistant) {
if ((e.isAltPressed() && e.isCtrlPressed() && !e.isShiftPressed()) ||
m_addingAssistant) {
m_addingAssistant = false;
return;
}
bool nonShiftStraight = false;
if ((e.isAltPressed() && !e.isCtrlPressed() && !e.isShiftPressed()) || (!e.isAltPressed() && e.isCtrlPressed() && !e.isShiftPressed())) {
nonShiftStraight = true;
if ((e.isAltPressed() && !e.isCtrlPressed() && !e.isShiftPressed()) ||
(!e.isAltPressed() && e.isCtrlPressed() && !e.isShiftPressed())) {
nonShiftStraight = true;
}
if (m_isPath) {
double error = 20.0 * getPixelSize();
TStroke *stroke;
if ((e.isShiftPressed() && !e.isCtrlPressed() && !e.isAltPressed()) || nonShiftStraight) {
if ((e.isShiftPressed() && !e.isCtrlPressed() && !e.isAltPressed()) ||
nonShiftStraight) {
m_track.removeMiddlePoints();
stroke = m_track.makeStroke(0);
} else {
@ -1096,7 +1100,8 @@ void ToonzVectorBrushTool::leftButtonUp(const TPointD &pos,
error *= getPixelSize();
TStroke *stroke;
if ((e.isShiftPressed() && !e.isCtrlPressed() && !e.isAltPressed()) || nonShiftStraight) {
if ((e.isShiftPressed() && !e.isCtrlPressed() && !e.isAltPressed()) ||
nonShiftStraight) {
m_track.removeMiddlePoints();
stroke = m_track.makeStroke(0);
} else {
@ -1215,7 +1220,7 @@ void ToonzVectorBrushTool::leftButtonUp(const TPointD &pos,
}
assert(stroke);
m_track.clear();
m_toggleSnap = false;
m_toggleSnap = false;
m_addingAssistant = false;
}

View file

@ -72,6 +72,7 @@
#include "trasterimage.h"
#include "tstroke.h"
#include "ttoonzimage.h"
#include "tenv.h"
// Qt includes
#include <QMenu>
@ -88,6 +89,8 @@
#include "sceneviewer.h"
TEnv::IntVar ShowPerspectiveGrids("ShowPerspectiveGrids", 1);
void drawSpline(const TAffine &viewMatrix, const TRect &clipRect, bool camera3d,
double pixelSize);
@ -777,6 +780,7 @@ SceneViewer::SceneViewer(ImageUtils::FullScreenWidget *parent)
, m_toolDisableReason("")
, m_editPreviewSubCamera(false)
, m_locator(NULL)
, m_showPerspectiveGrids(ShowPerspectiveGrids)
, m_isLocator(false)
, m_isBusyOnTabletMove(false) {
m_visualSettings.m_sceneProperties =
@ -1709,6 +1713,23 @@ void SceneViewer::drawOverlay() {
// draw tool gadgets
TTool *tool = app->getCurrentTool()->getTool();
TXshSimpleLevel *sl = app->getCurrentLevel()->getSimpleLevel();
if (sl && m_showPerspectiveGrids) {
std::vector<TPointD> assistantPoints =
sl->getProperties()->getVanishingPoints();
if (assistantPoints.size() > 0) {
if (tool->getToolType() & TTool::LevelTool &&
!app->getCurrentObject()->isSpline() &&
(tool->getName() == "T_Brush" || tool->getName() == "T_Geometric")) {
glPushMatrix();
tglMultMatrix(getViewMatrix() * tool->getMatrix());
glScaled(m_dpiScale.x, m_dpiScale.y, 1);
ViewerDraw::drawPerspectiveGuides(
this, (m_draw3DMode) ? m_zoomScale3D : m_viewAff[m_viewMode].det(),
assistantPoints);
glPopMatrix();
}
}
}
// Call tool->draw() even if the level is read only (i.e. to show hooks)
if (tool && (tool->isEnabled() || (sl && sl->isReadOnly()))) {
// tool->setViewer(this); // Moved at
@ -2156,7 +2177,7 @@ double SceneViewer::projectToZ(const TPointD &delta) {
GLint viewport[4];
double modelview[16], projection[16];
glGetIntegerv(GL_VIEWPORT, viewport);
for (int i = 0; i < 16; i++)
for (int i = 0; i < 16; i++)
projection[i] = (double)m_projectionMatrix.constData()[i];
glGetDoublev(GL_MODELVIEW_MATRIX, modelview);
@ -2318,9 +2339,8 @@ void SceneViewer::zoomQt(bool forward, bool reset) {
if (reset || ((m_zoomScale3D < 500 || !forward) &&
(m_zoomScale3D > 0.01 || forward))) {
double oldZoomScale = m_zoomScale3D;
m_zoomScale3D =
reset ? 1
: ImageUtils::getQuantizedZoomFactor(m_zoomScale3D, forward);
m_zoomScale3D = reset ? 1 : ImageUtils::getQuantizedZoomFactor(
m_zoomScale3D, forward);
m_pan3D = -(m_zoomScale3D / oldZoomScale) * -m_pan3D;
}
@ -2341,18 +2361,17 @@ void SceneViewer::zoomQt(bool forward, bool reset) {
int i;
for (i = 0; i < 2; i++) {
TAffine &viewAff = m_viewAff[i];
TAffine &viewAff = m_viewAff[i];
if (m_isFlippedX) viewAff = viewAff * TScale(-1, 1);
if (m_isFlippedX) viewAff = viewAff * TScale(1, -1);
double scale2 = std::abs(viewAff.det());
double scale2 = std::abs(viewAff.det());
if (m_isFlippedX) viewAff = viewAff * TScale(-1, 1);
if (m_isFlippedX) viewAff = viewAff * TScale(1, -1);
if (reset || ((scale2 < 100000 || !forward) &&
(scale2 > 0.001 * 0.05 || forward))) {
double oldZoomScale = sqrt(scale2) * dpiFactor;
double zoomScale =
reset ? 1
: ImageUtils::getQuantizedZoomFactor(oldZoomScale, forward);
double zoomScale = reset ? 1 : ImageUtils::getQuantizedZoomFactor(
oldZoomScale, forward);
// threshold value -0.001 is intended to absorb the error of calculation
if ((oldZoomScale - zoomScaleFittingWithScreen) *
@ -2655,9 +2674,9 @@ void SceneViewer::fitToCamera() {
TPointD P11 = cameraAff * cameraRect.getP11();
TPointD p0 = TPointD(std::min({P00.x, P01.x, P10.x, P11.x}),
std::min({P00.y, P01.y, P10.y, P11.y}));
TPointD p1 = TPointD(std::max({P00.x, P01.x, P10.x, P11.x}),
TPointD p1 = TPointD(std::max({P00.x, P01.x, P10.x, P11.x}),
std::max({P00.y, P01.y, P10.y, P11.y}));
cameraRect = TRectD(p0.x, p0.y, p1.x, p1.y);
cameraRect = TRectD(p0.x, p0.y, p1.x, p1.y);
// Pan
if (!is3DView()) {
@ -2700,9 +2719,9 @@ void SceneViewer::fitToCameraOutline() {
TPointD P11 = cameraAff * cameraRect.getP11();
TPointD p0 = TPointD(std::min({P00.x, P01.x, P10.x, P11.x}),
std::min({P00.y, P01.y, P10.y, P11.y}));
TPointD p1 = TPointD(std::max({P00.x, P01.x, P10.x, P11.x}),
TPointD p1 = TPointD(std::max({P00.x, P01.x, P10.x, P11.x}),
std::max({P00.y, P01.y, P10.y, P11.y}));
cameraRect = TRectD(p0.x, p0.y, p1.x, p1.y);
cameraRect = TRectD(p0.x, p0.y, p1.x, p1.y);
// Pan
if (!is3DView()) {
@ -2752,8 +2771,8 @@ void SceneViewer::resetZoom() {
TPointD realCenter(m_viewAff[m_viewMode].a13, m_viewAff[m_viewMode].a23);
TAffine aff =
getNormalZoomScale() * TRotation(realCenter, m_rotationAngle[m_viewMode]);
aff.a13 = realCenter.x;
aff.a23 = realCenter.y;
aff.a13 = realCenter.x;
aff.a23 = realCenter.y;
if (m_isFlippedX) aff = aff * TScale(-1, 1);
if (m_isFlippedY) aff = aff * TScale(1, -1);
setViewMatrix(aff, m_viewMode);
@ -2810,17 +2829,16 @@ void SceneViewer::setActualPixelSize() {
} else
dpi = sl->getDpi(fid);
const double inch = Stage::inch;
TAffine tempAff = getNormalZoomScale();
if (m_isFlippedX) tempAff = tempAff * TScale(-1, 1);
if (m_isFlippedY) tempAff = tempAff * TScale(1, -1);
TPointD tempScale = dpi;
const double inch = Stage::inch;
TAffine tempAff = getNormalZoomScale();
if (m_isFlippedX) tempAff = tempAff * TScale(-1, 1);
if (m_isFlippedY) tempAff = tempAff * TScale(1, -1);
TPointD tempScale = dpi;
if (m_isFlippedX) tempScale.x = -tempScale.x;
if (m_isFlippedY) tempScale.y = -tempScale.y;
for (int i = 0; i < m_viewAff.size(); ++i)
setViewMatrix(dpi == TPointD(0, 0)
? tempAff
: TScale(tempScale.x / inch, tempScale.y / inch),
setViewMatrix(dpi == TPointD(0, 0) ? tempAff : TScale(tempScale.x / inch,
tempScale.y / inch),
i);
m_pos = QPoint(0, 0);
@ -3103,7 +3121,7 @@ void drawSpline(const TAffine &viewMatrix, const TRect &clipRect, bool camera3d,
TStageObject *pegbar =
objId != TStageObjectId::NoneId ? xsh->getStageObject(objId) : 0;
const TStroke *stroke = 0;
const TStroke *stroke = 0;
if (pegbar && pegbar->getSpline()) stroke = pegbar->getSpline()->getStroke();
if (!stroke) return;
@ -3332,3 +3350,10 @@ void SceneViewer::registerContext() {
TGLDisplayListsManager::instance()->attachContext(displayListId, tglContext);
l_contexts.insert(tglContext);
}
//-----------------------------------------------------------------------------
void SceneViewer::setShowPerspectiveGrids(bool show) {
m_showPerspectiveGrids = show;
ShowPerspectiveGrids = show ? 1 : 0;
}

View file

@ -167,6 +167,8 @@ class SceneViewer final : public GLWidgetForHighDpi,
TRectD m_clipRect;
bool m_isPicking;
bool m_showPerspectiveGrids = true;
bool m_canShowPerspectiveGrids = false;
TRaster32P m_3DSideL;
TRaster32P m_3DSideR;
@ -264,6 +266,9 @@ public:
m_vRuler = v;
m_hRuler = h;
}
bool getShowPerspectiveGrids() { return m_showPerspectiveGrids; }
void setShowPerspectiveGrids(bool show);
bool getCanShowPerspectiveGrids() { return m_canShowPerspectiveGrids; }
bool is3DView() const override;
TDimension getViewportSize() const { return TDimension(width(), height()); }

View file

@ -50,8 +50,9 @@ SceneViewerContextMenu::SceneViewerContextMenu(SceneViewer *parent)
/*- サブカメラの消去 -*/
if (parent->isEditPreviewSubcamera()) {
action = addAction(tr("Reset Subcamera"));
ret = ret && parent->connect(action, SIGNAL(triggered()),
SLOT(doDeleteSubCamera()));
ret =
ret &&
parent->connect(action, SIGNAL(triggered()), SLOT(doDeleteSubCamera()));
addSeparator();
}
@ -68,8 +69,9 @@ SceneViewerContextMenu::SceneViewerContextMenu(SceneViewer *parent)
action =
commandManager->createAction(V_ShowHideFullScreen, this, !isFullScreen);
addAction(action);
ret = ret && parent->connect(action, SIGNAL(triggered()), fsWidget,
SLOT(toggleFullScreen()));
ret = ret &&
parent->connect(action, SIGNAL(triggered()), fsWidget,
SLOT(toggleFullScreen()));
}
// swap compared
@ -127,13 +129,21 @@ SceneViewerContextMenu::SceneViewerContextMenu(SceneViewer *parent)
// actual pixel size
action = commandManager->createAction(V_ActualPixelSize, this);
addAction(action);
ret = ret && parent->connect(action, SIGNAL(triggered()),
SLOT(setActualPixelSize()));
ret =
ret &&
parent->connect(action, SIGNAL(triggered()), SLOT(setActualPixelSize()));
// onion skin
if (Preferences::instance()->isOnionSkinEnabled() &&
!parent->isPreviewEnabled())
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) {
auto addOptionAction = [](const QString &label, const int data,
@ -157,9 +167,9 @@ SceneViewerContextMenu::SceneViewerContextMenu(SceneViewer *parent)
guidedDrawingMenu, guidedDrawingGroup);
addOptionAction(tr("All Drawings"), 3, guidedDrawingStatus,
guidedDrawingMenu, guidedDrawingGroup);
ret =
ret && parent->connect(guidedDrawingGroup, SIGNAL(triggered(QAction *)),
this, SLOT(setGuidedDrawingType(QAction *)));
ret = ret &&
parent->connect(guidedDrawingGroup, SIGNAL(triggered(QAction *)),
this, SLOT(setGuidedDrawingType(QAction *)));
guidedDrawingMenu->addSeparator();
bool enableOption = guidedDrawingStatus == 1 || guidedDrawingStatus == 2;
@ -167,8 +177,9 @@ SceneViewerContextMenu::SceneViewerContextMenu(SceneViewer *parent)
action->setCheckable(true);
action->setChecked(Preferences::instance()->getGuidedAutoInbetween());
action->setEnabled(enableOption);
ret = ret && parent->connect(action, SIGNAL(triggered()), this,
SLOT(setGuidedAutoInbetween()));
ret = ret &&
parent->connect(action, SIGNAL(triggered()), this,
SLOT(setGuidedAutoInbetween()));
guidedDrawingMenu->addSeparator();
int guidedInterpolation = Preferences::instance()->getGuidedInterpolation();
QActionGroup *interpolationGroup = new QActionGroup(this);
@ -230,22 +241,25 @@ SceneViewerContextMenu::SceneViewerContextMenu(SceneViewer *parent)
action = addAction(tr("Save Previewed Frames"));
action->setShortcut(QKeySequence(
CommandManager::instance()->getKeyFromId(MI_SavePreviewedFrames)));
ret = ret && parent->connect(action, SIGNAL(triggered()), this,
SLOT(savePreviewedFrames()));
ret = ret &&
parent->connect(action, SIGNAL(triggered()), this,
SLOT(savePreviewedFrames()));
// regenerate preview
action = addAction(tr("Regenerate Preview"));
action->setShortcut(QKeySequence(
CommandManager::instance()->getKeyFromId(MI_RegeneratePreview)));
ret = ret && parent->connect(action, SIGNAL(triggered()),
SLOT(regeneratePreview()));
ret =
ret &&
parent->connect(action, SIGNAL(triggered()), SLOT(regeneratePreview()));
// regenerate frame preview
action = addAction(tr("Regenerate Frame Preview"));
action->setShortcut(QKeySequence(
CommandManager::instance()->getKeyFromId(MI_RegenerateFramePr)));
ret = ret && parent->connect(action, SIGNAL(triggered()),
SLOT(regeneratePreviewFrame()));
ret = ret &&
parent->connect(action, SIGNAL(triggered()),
SLOT(regeneratePreviewFrame()));
}
assert(ret);
@ -299,9 +313,9 @@ void SceneViewerContextMenu::addSelectCommand(QMenu *menu,
TXsheet *xsh = TApp::instance()->getCurrentXsheet()->getXsheet();
TStageObject *stageObject = xsh->getStageObject(id);
if (!stageObject) return;
QString text = (id.isTable()) ? tr("Table") : getName(stageObject);
QString text = (id.isTable()) ? tr("Table") : getName(stageObject);
if (menu == this) text = tr("Select %1").arg(text);
QAction *action = new QAction(text, this);
QAction *action = new QAction(text, this);
action->setData(id.getCode());
connect(action, SIGNAL(triggered()), this, SLOT(onSetCurrent()));
menu->addAction(action);

View file

@ -1811,6 +1811,15 @@ void SceneViewer::onContextMenu(const QPoint &pos, const QPoint &globalPos) {
i++)
columnIndices.push_back(i);
TXshLevelHandle *level = TApp::instance()->getCurrentLevel();
if (level) {
TXshSimpleLevel *sl = level->getSimpleLevel();
if (sl) {
int vp = sl->getProperties()->getVanishingPoints().size();
if (vp > 0) m_canShowPerspectiveGrids = true;
}
}
SceneViewerContextMenu *menu = new SceneViewerContextMenu(this);
TTool *tool = TApp::instance()->getCurrentTool()->getTool();

View file

@ -378,6 +378,100 @@ void ViewerDraw::drawGridAndGuides(SceneViewer *viewer, double sc, Ruler *vr,
//-----------------------------------------------------------------------------
void ViewerDraw::drawPerspectiveGuides(SceneViewer *viewer, double sc,
std::vector<TPointD> assistantPoints) {
int x1, x2, y1, y2;
viewer->rect().getCoords(&x1, &y1, &x2, &y2);
TRect clipRect = TRect(x1, y1, x2 + 1, y2 + 1);
GLfloat modelView[16];
glGetFloatv(GL_MODELVIEW_MATRIX, modelView);
TAffine modelViewAff(modelView[0], modelView[4], modelView[12], modelView[1],
modelView[5], modelView[13]);
TRectD cameraRect = getCameraRect();
TPointD clipCorner[] = {
modelViewAff.inv() * TPointD(clipRect.x0, clipRect.y0),
modelViewAff.inv() * TPointD(clipRect.x1, clipRect.y0),
modelViewAff.inv() * TPointD(clipRect.x1, clipRect.y1),
modelViewAff.inv() * TPointD(clipRect.x0, clipRect.y1)};
TRectD bounds;
bounds.x0 = bounds.x1 = clipCorner[0].x;
bounds.y0 = bounds.y1 = clipCorner[0].y;
int i;
for (i = 1; i < 4; i++) {
const TPointD &p = clipCorner[i];
if (p.x < bounds.x0)
bounds.x0 = p.x;
else if (p.x > bounds.x1)
bounds.x1 = p.x;
if (p.y < bounds.y0)
bounds.y0 = p.y;
else if (p.y > bounds.y1)
bounds.y1 = p.y;
}
double interval = 150; // *sc;
glEnable(GL_BLEND); // Enable blending.
glEnable(GL_LINE_SMOOTH);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
std::vector<double> reds{0.0, 0.7, 1.0, 0.0, 0.3};
std::vector<double> greens{0.0, 0.0, 0.0, 0.4, 0.3};
std::vector<double> blues{1.0, 0.7, 0.0, 0.0, 0.3};
for (int j = 0; j < assistantPoints.size(); j++) {
TPointD p = assistantPoints.at(j);
if (j < 5) glColor4d(reds.at(j), greens.at(j), blues.at(j), 0.2);
TPointD end;
bool useX = true;
for (double i = bounds.x0; i < bounds.x1; i += interval) {
end.y = bounds.y0;
end.x = i;
tglDrawSegment(p, end);
}
for (double i = bounds.x0; i < bounds.x1; i += interval) {
end.y = bounds.y1;
end.x = i;
tglDrawSegment(p, end);
}
for (double i = bounds.y0; i < bounds.y1; i += interval) {
end.y = i;
end.x = bounds.x0;
tglDrawSegment(p, end);
}
for (double i = bounds.y0; i < bounds.y1; i += interval) {
end.y = i;
end.x = bounds.x1;
tglDrawSegment(p, end);
}
// double distanceToLeft = std::abs(p.x - bounds.x0);
// double distanceToRight = std::abs(p.x - bounds.x1);
// double distanceToTop = std::abs(p.y - bounds.y1);
// double distanceToBottom = std::abs(p.y - bounds.y0);
// double xDistance = std::max(distanceToLeft, distanceToRight);
// double yDistance = std::max(distanceToTop, distanceToBottom);
// double totalDistance = std::sqrt(std::pow(xDistance, 2) +
// std::pow(yDistance, 2));
// for (int i = 0; i < 360; i += 15) {
//
// //double slope = std::tan(i * (3.14159 / 180));
// double yLength = std::sin(i * (3.14159 / 180)) * totalDistance;
// double xLength = std::cos(i * (3.14159 / 180)) * totalDistance;
// end.x = p.x + xLength;
// end.y = p.y + yLength;
// tglDrawSegment(p, end);
//}
}
glDisable(GL_LINE_SMOOTH);
glDisable(GL_BLEND);
}
//-----------------------------------------------------------------------------
void ViewerDraw::drawColorcard(UCHAR channel) {
ToonzScene *scene = TApp::instance()->getCurrentScene()->getScene();
TRectD rect = getCameraRect();

View file

@ -35,6 +35,8 @@ TRectD getCameraRect();
void drawCameraMask(SceneViewer *viewer);
void drawGridAndGuides(SceneViewer *viewer, double viewerScale, Ruler *vRuler,
Ruler *hRuler, bool gridEnabled);
void drawPerspectiveGuides(SceneViewer *viewer, double viewerScale,
std::vector<TPointD> assistantPoints);
void draw3DCamera(unsigned long flags, double zmin, double phi);
void drawCamera(unsigned long flags, double pixelSize);