diff --git a/toonz/sources/tnztools/toonzvectorbrushtool.cpp b/toonz/sources/tnztools/toonzvectorbrushtool.cpp index 2f46d02..13e42ba 100644 --- a/toonz/sources/tnztools/toonzvectorbrushtool.cpp +++ b/toonz/sources/tnztools/toonzvectorbrushtool.cpp @@ -914,10 +914,6 @@ void ToonzVectorBrushTool::leftButtonUp(const TPointD &pos, addTrackPoint(TThickPoint(m_lastSnapPoint, m_currThickness), getPixelSize() * getPixelSize()); } - m_strokeIndex1 = -1; - m_strokeIndex2 = -1; - m_w1 = -1; - m_w2 = -2; m_foundFirstSnap = false; m_foundLastSnap = false; @@ -1373,142 +1369,108 @@ void ToonzVectorBrushTool::mouseMove(const TPointD &pos, const TMouseEvent &e) { void ToonzVectorBrushTool::checkStrokeSnapping(bool beforeMousePress, bool invertCheck) { - if (Preferences::instance()->getVectorSnappingTarget() == 1) return; - - TVectorImageP vi(getImage(false)); - bool checkSnap = m_snap.getValue(); - if (invertCheck) checkSnap = !checkSnap; + if (Preferences::instance()->getVectorSnappingTarget() == 1) + return; // 0 - strokes, 1 - guides, 2 - all + m_dragDraw = true; - if (vi && checkSnap) { - double minDistance2 = m_minDistance2; - if (beforeMousePress) - m_strokeIndex1 = -1; - else - m_strokeIndex2 = -1; - int i, strokeNumber = vi->getStrokeCount(); - TStroke *stroke; - double distance2, outW; - bool snapFound = false; - TThickPoint point1; - - for (i = 0; i < strokeNumber; i++) { - stroke = vi->getStroke(i); - if (stroke->getNearestW(m_mousePos, outW, distance2) && - distance2 < minDistance2) { - minDistance2 = distance2; - beforeMousePress ? m_strokeIndex1 = i : m_strokeIndex2 = i; - if (areAlmostEqual(outW, 0.0, 1e-3)) - beforeMousePress ? m_w1 = 0.0 : m_w2 = 0.0; - else if (areAlmostEqual(outW, 1.0, 1e-3)) - beforeMousePress ? m_w1 = 1.0 : m_w2 = 1.0; - else - beforeMousePress ? m_w1 = outW : m_w2 = outW; - - beforeMousePress ? point1 = stroke->getPoint(m_w1) - : point1 = stroke->getPoint(m_w2); - snapFound = true; - } - } - // compare to first point of current stroke - if (beforeMousePress && snapFound) { - m_firstSnapPoint = TPointD(point1.x, point1.y); + + if (invertCheck == m_snap.getValue()) + return; + + TVectorImageP vi(getImage(false)); + if (!vi) + return; + + TPointD point; + bool found = false; + double minDistance2 = m_minDistance2; + int count = vi->getStrokeCount(); + for(int i = 0; i < count; ++i) { + double w, d2; + TStroke *stroke = vi->getStroke(i); + if (!stroke->getNearestW(m_mousePos, w, d2) || d2 >= minDistance2) + continue; + minDistance2 = d2; + w = w > 0.001 ? (w < 0.999 ? w : 1.0) : 0.0; + point = stroke->getPoint(w); + found = true; + } + + if (beforeMousePress) { + if (found) { + m_firstSnapPoint = point; m_foundFirstSnap = true; - } else if (!beforeMousePress) { - if (!snapFound) { - TPointD tempPoint = m_track.getFirstPoint(); - double distanceFromStart = tdistance2(m_mousePos, tempPoint); - - if (distanceFromStart < m_minDistance2) { - point1 = tempPoint; - distance2 = distanceFromStart; - snapFound = true; - m_snapSelf = true; - } - } - if (snapFound) { - m_lastSnapPoint = TPointD(point1.x, point1.y); - m_foundLastSnap = true; - if (distance2 < 2.0) m_dragDraw = false; - } } + return; + } + + if (!found) { + // compare to first point of current stroke + TPointD p = m_track.getFirstPoint(); + double d2 = tdistance2(m_mousePos, p); + if (!(d2 < m_minDistance2)) + return; + point = p; + minDistance2 = d2; + m_snapSelf = true; } + + m_lastSnapPoint = point; + m_foundLastSnap = true; + if (minDistance2 < 2.0) + m_dragDraw = false; } //------------------------------------------------------------------------------------------------------------- void ToonzVectorBrushTool::checkGuideSnapping(bool beforeMousePress, bool invertCheck) { - if (Preferences::instance()->getVectorSnappingTarget() == 0) return; - bool foundSnap; - TPointD snapPoint; - beforeMousePress ? foundSnap = m_foundFirstSnap : foundSnap = m_foundLastSnap; - beforeMousePress ? snapPoint = m_firstSnapPoint : snapPoint = m_lastSnapPoint; - - bool checkSnap = m_snap.getValue(); - if (invertCheck) checkSnap = !checkSnap; - - if (checkSnap) { - // check guide snapping - int vGuideCount = 0, hGuideCount = 0; - double guideDistance = sqrt(m_minDistance2); - TToolViewer *viewer = getViewer(); - if (viewer) { - vGuideCount = viewer->getVGuideCount(); - hGuideCount = viewer->getHGuideCount(); - } - double distanceToVGuide = -1.0, distanceToHGuide = -1.0; - double vGuide, hGuide; - bool useGuides = false; - if (vGuideCount) { - for (int j = 0; j < vGuideCount; j++) { - double guide = viewer->getVGuide(j); - double tempDistance = std::abs(guide - m_mousePos.y); - if (tempDistance < guideDistance && - (distanceToVGuide < 0 || tempDistance < distanceToVGuide)) { - distanceToVGuide = tempDistance; - vGuide = guide; - useGuides = true; - } - } - } - if (hGuideCount) { - for (int j = 0; j < hGuideCount; j++) { - double guide = viewer->getHGuide(j); - double tempDistance = std::abs(guide - m_mousePos.x); - if (tempDistance < guideDistance && - (distanceToHGuide < 0 || tempDistance < distanceToHGuide)) { - distanceToHGuide = tempDistance; - hGuide = guide; - useGuides = true; - } - } - } - if (useGuides && foundSnap) { - double currYDistance = std::abs(snapPoint.y - m_mousePos.y); - double currXDistance = std::abs(snapPoint.x - m_mousePos.x); - double hypotenuse = - sqrt(pow(currYDistance, 2.0) + pow(currXDistance, 2.0)); - if ((distanceToVGuide >= 0 && distanceToVGuide < hypotenuse) || - (distanceToHGuide >= 0 && distanceToHGuide < hypotenuse)) { - useGuides = true; - m_snapSelf = false; - } else - useGuides = false; + if (Preferences::instance()->getVectorSnappingTarget() == 0) + return; // 0 - strokes, 1 - guides, 2 - all + if (invertCheck == m_snap.getValue()) + return; + TToolViewer *viewer = getViewer(); + if (!viewer) + return; + + // choose snaping fields to work + bool &m_foundSnap = beforeMousePress ? m_foundFirstSnap : m_foundLastSnap; + TPointD &m_snapPoint = beforeMousePress ? m_firstSnapPoint : m_lastSnapPoint; + + // init min distance, with using snapPoint found by checkStrokeSnapping + double minDistance2 = m_minDistance2; + if (m_foundSnap) { + double d2 = tdistance2(m_snapPoint, m_mousePos); + if (d2 < minDistance2) minDistance2 = d2; + } + + // find nearest vertical guide + int cnt = viewer->getVGuideCount(); + for(int i = 0; i < cnt; ++i) { + double guide = viewer->getVGuide(i); + double d2 = guide - m_mousePos.y; + d2 *= d2; // we work with square of the distance + if (d2 < minDistance2) { + m_foundSnap = true; + m_snapPoint.x = m_mousePos.x; + m_snapPoint.y = guide; + m_snapSelf = false; + minDistance2 = d2; } - if (useGuides) { - assert(distanceToHGuide >= 0 || distanceToVGuide >= 0); - if (distanceToHGuide < 0 || - (distanceToVGuide <= distanceToHGuide && distanceToVGuide >= 0)) { - snapPoint.y = vGuide; - snapPoint.x = m_mousePos.x; + } - } else { - snapPoint.y = m_mousePos.y; - snapPoint.x = hGuide; - } - beforeMousePress ? m_foundFirstSnap = true : m_foundLastSnap = true; - beforeMousePress ? m_firstSnapPoint = snapPoint - : m_lastSnapPoint = snapPoint; + // find nearest horizontal guide + cnt = viewer->getHGuideCount(); + for(int i = 0; i < cnt; ++i) { + double guide = viewer->getHGuide(i); + double d2 = guide - m_mousePos.x; + d2 *= d2; // we work with square of the distance + if (d2 < minDistance2) { + m_foundSnap = true; + m_snapPoint.x = guide; + m_snapPoint.y = m_mousePos.y; + m_snapSelf = false; + minDistance2 = d2; } } } diff --git a/toonz/sources/tnztools/toonzvectorbrushtool.h b/toonz/sources/tnztools/toonzvectorbrushtool.h index 5ded2d6..8e32b57 100644 --- a/toonz/sources/tnztools/toonzvectorbrushtool.h +++ b/toonz/sources/tnztools/toonzvectorbrushtool.h @@ -171,9 +171,9 @@ protected: double m_minThick, m_maxThick; // for snapping and framerange - int m_strokeIndex1, m_strokeIndex2, m_col, m_firstFrame, m_veryFirstFrame, + int m_col, m_firstFrame, m_veryFirstFrame, m_veryFirstCol, m_targetType; - double m_w1, m_w2, m_pixelSize, m_currThickness, m_minDistance2; + double m_pixelSize, m_currThickness, m_minDistance2; bool m_foundFirstSnap = false, m_foundLastSnap = false, m_dragDraw = true, m_altPressed = false, m_snapSelf = false; TRectD m_modifiedRegion;