refactor: Use gp_Ax2 for plane-agnostic snapping calculations and rendering
Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
+61
-90
@@ -19,6 +19,10 @@
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QVector>
|
||||
#include <QtMath>
|
||||
#include <optional>
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <ElCLib.hxx>
|
||||
|
||||
Snapping::Snapping(ViewportWidget* viewport) : m_viewport(viewport)
|
||||
{
|
||||
@@ -30,23 +34,15 @@ bool Snapping::update(const QPoint& mousePos)
|
||||
bool oldIsSnappingVertex = m_isSnappingVertex;
|
||||
|
||||
bool shouldSnap = false;
|
||||
if (m_viewport->currentPlane() != ViewportWidget::SketchPlane::NONE && m_viewport->activeTool() != static_cast<int>(ApplicationController::ToolType::None)) {
|
||||
QVector3D worldPos = m_viewport->unproject(mousePos, m_viewport->currentPlane());
|
||||
auto currentPlaneOpt = m_viewport->currentPlane();
|
||||
if (currentPlaneOpt && m_viewport->activeTool() != static_cast<int>(ApplicationController::ToolType::None)) {
|
||||
const auto& plane = currentPlaneOpt.value();
|
||||
QVector3D worldPosQ = m_viewport->unproject(mousePos, plane);
|
||||
gp_Pnt worldPos(worldPosQ.x(), worldPosQ.y(), worldPosQ.z());
|
||||
const float snapRectHalfSize = 0.0075f * -m_viewport->camera()->zoom();
|
||||
|
||||
switch (m_viewport->currentPlane()) {
|
||||
case ViewportWidget::SketchPlane::XY:
|
||||
shouldSnap = qAbs(worldPos.x()) < snapRectHalfSize && qAbs(worldPos.y()) < snapRectHalfSize;
|
||||
break;
|
||||
case ViewportWidget::SketchPlane::XZ:
|
||||
shouldSnap = qAbs(worldPos.x()) < snapRectHalfSize && qAbs(worldPos.z()) < snapRectHalfSize;
|
||||
break;
|
||||
case ViewportWidget::SketchPlane::YZ:
|
||||
shouldSnap = qAbs(worldPos.y()) < snapRectHalfSize && qAbs(worldPos.z()) < snapRectHalfSize;
|
||||
break;
|
||||
case ViewportWidget::SketchPlane::NONE:
|
||||
break;
|
||||
}
|
||||
gp_Pnt2d worldPos2d = ElCLib::To2d(worldPos, plane);
|
||||
shouldSnap = qAbs(worldPos2d.X()) < snapRectHalfSize && qAbs(worldPos2d.Y()) < snapRectHalfSize;
|
||||
}
|
||||
|
||||
m_isSnappingOrigin = shouldSnap;
|
||||
@@ -55,8 +51,11 @@ bool Snapping::update(const QPoint& mousePos)
|
||||
}
|
||||
|
||||
m_isSnappingVertex = false;
|
||||
if (!m_isSnappingOrigin && m_viewport->document() && m_viewport->currentPlane() != ViewportWidget::SketchPlane::NONE && m_viewport->activeTool() != static_cast<int>(ApplicationController::ToolType::None)) {
|
||||
QVector3D worldPos = m_viewport->unproject(mousePos, m_viewport->currentPlane());
|
||||
if (!m_isSnappingOrigin && m_viewport->document() && currentPlaneOpt && m_viewport->activeTool() != static_cast<int>(ApplicationController::ToolType::None)) {
|
||||
const auto& plane = currentPlaneOpt.value();
|
||||
QVector3D worldPosQ = m_viewport->unproject(mousePos, plane);
|
||||
gp_Pnt worldPos(worldPosQ.x(), worldPosQ.y(), worldPosQ.z());
|
||||
gp_Pnt2d worldPos2d = ElCLib::To2d(worldPos, plane);
|
||||
const float snapRectHalfSize = 0.0075f * -m_viewport->camera()->zoom();
|
||||
|
||||
for (Feature* feature : m_viewport->document()->features()) {
|
||||
@@ -66,20 +65,8 @@ bool Snapping::update(const QPoint& mousePos)
|
||||
auto line = static_cast<const SketchLine*>(obj);
|
||||
const gp_Pnt vertices[] = {line->startPoint(), line->endPoint()};
|
||||
for (const auto& vertex : vertices) {
|
||||
bool isClose = false;
|
||||
switch (m_viewport->currentPlane()) {
|
||||
case ViewportWidget::SketchPlane::XY:
|
||||
isClose = qAbs(worldPos.x() - vertex.X()) < snapRectHalfSize && qAbs(worldPos.y() - vertex.Y()) < snapRectHalfSize;
|
||||
break;
|
||||
case ViewportWidget::SketchPlane::XZ:
|
||||
isClose = qAbs(worldPos.x() - vertex.X()) < snapRectHalfSize && qAbs(worldPos.z() - vertex.Z()) < snapRectHalfSize;
|
||||
break;
|
||||
case ViewportWidget::SketchPlane::YZ:
|
||||
isClose = qAbs(worldPos.y() - vertex.Y()) < snapRectHalfSize && qAbs(worldPos.z() - vertex.Z()) < snapRectHalfSize;
|
||||
break;
|
||||
case ViewportWidget::SketchPlane::NONE:
|
||||
break;
|
||||
}
|
||||
gp_Pnt2d vertex2d = ElCLib::To2d(vertex, plane);
|
||||
bool isClose = qAbs(worldPos2d.X() - vertex2d.X()) < snapRectHalfSize && qAbs(worldPos2d.Y() - vertex2d.Y()) < snapRectHalfSize;
|
||||
|
||||
if (isClose) {
|
||||
m_isSnappingVertex = true;
|
||||
@@ -89,37 +76,23 @@ bool Snapping::update(const QPoint& mousePos)
|
||||
}
|
||||
} else if (obj->type() == SketchObject::ObjectType::Rectangle) {
|
||||
auto rect = static_cast<const SketchRectangle*>(obj);
|
||||
const auto& rectPlane = sketch->plane();
|
||||
const auto& p1 = rect->corner1();
|
||||
const auto& p3 = rect->corner2();
|
||||
gp_Pnt p2, p4;
|
||||
|
||||
if (sketch->plane() == SketchFeature::SketchPlane::XY) {
|
||||
p2.SetCoord(p3.X(), p1.Y(), p1.Z());
|
||||
p4.SetCoord(p1.X(), p3.Y(), p1.Z());
|
||||
} else if (sketch->plane() == SketchFeature::SketchPlane::XZ) {
|
||||
p2.SetCoord(p3.X(), p1.Y(), p1.Z());
|
||||
p4.SetCoord(p1.X(), p1.Y(), p3.Z());
|
||||
} else if (sketch->plane() == SketchFeature::SketchPlane::YZ) {
|
||||
p2.SetCoord(p1.X(), p3.Y(), p1.Z());
|
||||
p4.SetCoord(p1.X(), p1.Y(), p3.Z());
|
||||
}
|
||||
gp_Pnt2d p1_2d = ElCLib::To2d(p1, rectPlane);
|
||||
gp_Pnt2d p3_2d = ElCLib::To2d(p3, rectPlane);
|
||||
|
||||
gp_Pnt2d p2_2d(p3_2d.X(), p1_2d.Y());
|
||||
gp_Pnt2d p4_2d(p1_2d.X(), p3_2d.Y());
|
||||
|
||||
gp_Pnt p2 = ElCLib::To3d(p2_2d, rectPlane);
|
||||
gp_Pnt p4 = ElCLib::To3d(p4_2d, rectPlane);
|
||||
|
||||
const gp_Pnt vertices[] = {p1, p2, p3, p4};
|
||||
for (const auto& vertex : vertices) {
|
||||
bool isClose = false;
|
||||
switch (m_viewport->currentPlane()) {
|
||||
case ViewportWidget::SketchPlane::XY:
|
||||
isClose = qAbs(worldPos.x() - vertex.X()) < snapRectHalfSize && qAbs(worldPos.y() - vertex.Y()) < snapRectHalfSize;
|
||||
break;
|
||||
case ViewportWidget::SketchPlane::XZ:
|
||||
isClose = qAbs(worldPos.x() - vertex.X()) < snapRectHalfSize && qAbs(worldPos.z() - vertex.Z()) < snapRectHalfSize;
|
||||
break;
|
||||
case ViewportWidget::SketchPlane::YZ:
|
||||
isClose = qAbs(worldPos.y() - vertex.Y()) < snapRectHalfSize && qAbs(worldPos.z() - vertex.Z()) < snapRectHalfSize;
|
||||
break;
|
||||
case ViewportWidget::SketchPlane::NONE:
|
||||
break;
|
||||
}
|
||||
gp_Pnt2d vertex2d = ElCLib::To2d(vertex, plane);
|
||||
bool isClose = qAbs(worldPos2d.X() - vertex2d.X()) < snapRectHalfSize && qAbs(worldPos2d.Y() - vertex2d.Y()) < snapRectHalfSize;
|
||||
|
||||
if (isClose) {
|
||||
m_isSnappingVertex = true;
|
||||
@@ -144,43 +117,41 @@ void Snapping::paintGL() const
|
||||
}
|
||||
|
||||
QVector<GLfloat> vertices;
|
||||
auto currentPlaneOpt = m_viewport->currentPlane();
|
||||
if (!currentPlaneOpt) {
|
||||
return;
|
||||
}
|
||||
const auto& plane = currentPlaneOpt.value();
|
||||
const auto& xDir = plane.XDirection();
|
||||
const auto& yDir = plane.YDirection();
|
||||
QVector3D X(xDir.X(), xDir.Y(), xDir.Z());
|
||||
QVector3D Y(yDir.X(), yDir.Y(), yDir.Z());
|
||||
const float rectSize = 0.0075f * -m_viewport->camera()->zoom();
|
||||
|
||||
if (m_isSnappingOrigin) {
|
||||
const float rectSize = 0.0075f * -m_viewport->camera()->zoom();
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||
vertices << -rectSize << -rectSize << 0 << rectSize << -rectSize << 0;
|
||||
vertices << rectSize << -rectSize << 0 << rectSize << rectSize << 0;
|
||||
vertices << rectSize << rectSize << 0 << -rectSize << rectSize << 0;
|
||||
vertices << -rectSize << rectSize << 0 << -rectSize << -rectSize << 0;
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
vertices << -rectSize << 0 << -rectSize << rectSize << 0 << -rectSize;
|
||||
vertices << rectSize << 0 << -rectSize << rectSize << 0 << rectSize;
|
||||
vertices << rectSize << 0 << rectSize << -rectSize << 0 << rectSize;
|
||||
vertices << -rectSize << 0 << rectSize << -rectSize << 0 << -rectSize;
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) {
|
||||
vertices << 0 << -rectSize << -rectSize << 0 << rectSize << -rectSize;
|
||||
vertices << 0 << rectSize << -rectSize << 0 << rectSize << rectSize;
|
||||
vertices << 0 << rectSize << rectSize << 0 << -rectSize << rectSize;
|
||||
vertices << 0 << -rectSize << rectSize << 0 << -rectSize << -rectSize;
|
||||
}
|
||||
const auto& o = plane.Location();
|
||||
QVector3D O(o.X(), o.Y(), o.Z());
|
||||
|
||||
QVector3D p1 = O - rectSize * X - rectSize * Y;
|
||||
QVector3D p2 = O + rectSize * X - rectSize * Y;
|
||||
QVector3D p3 = O + rectSize * X + rectSize * Y;
|
||||
QVector3D p4 = O - rectSize * X + rectSize * Y;
|
||||
vertices << p1.x() << p1.y() << p1.z() << p2.x() << p2.y() << p2.z();
|
||||
vertices << p2.x() << p2.y() << p2.z() << p3.x() << p3.y() << p3.z();
|
||||
vertices << p3.x() << p3.y() << p3.z() << p4.x() << p4.y() << p4.z();
|
||||
vertices << p4.x() << p4.y() << p4.z() << p1.x() << p1.y() << p1.z();
|
||||
} else if (m_isSnappingVertex) {
|
||||
const float rectSize = 0.0075f * -m_viewport->camera()->zoom();
|
||||
const auto& v = m_snapVertex;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||
vertices << v.X() - rectSize << v.Y() - rectSize << v.Z() << v.X() + rectSize << v.Y() - rectSize << v.Z();
|
||||
vertices << v.X() + rectSize << v.Y() - rectSize << v.Z() << v.X() + rectSize << v.Y() + rectSize << v.Z();
|
||||
vertices << v.X() + rectSize << v.Y() + rectSize << v.Z() << v.X() - rectSize << v.Y() + rectSize << v.Z();
|
||||
vertices << v.X() - rectSize << v.Y() + rectSize << v.Z() << v.X() - rectSize << v.Y() - rectSize << v.Z();
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
vertices << v.X() - rectSize << v.Y() << v.Z() - rectSize << v.X() + rectSize << v.Y() << v.Z() - rectSize;
|
||||
vertices << v.X() + rectSize << v.Y() << v.Z() - rectSize << v.X() + rectSize << v.Y() << v.Z() + rectSize;
|
||||
vertices << v.X() + rectSize << v.Y() << v.Z() + rectSize << v.X() - rectSize << v.Y() << v.Z() + rectSize;
|
||||
vertices << v.X() - rectSize << v.Y() << v.Z() + rectSize << v.X() - rectSize << v.Y() << v.Z() - rectSize;
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) {
|
||||
vertices << v.X() << v.Y() - rectSize << v.Z() - rectSize << v.X() << v.Y() + rectSize << v.Z() - rectSize;
|
||||
vertices << v.X() << v.Y() + rectSize << v.Z() - rectSize << v.X() << v.Y() + rectSize << v.Z() + rectSize;
|
||||
vertices << v.X() << v.Y() + rectSize << v.Z() + rectSize << v.X() << v.Y() - rectSize << v.Z() + rectSize;
|
||||
vertices << v.X() << v.Y() - rectSize << v.Z() + rectSize << v.X() << v.Y() - rectSize << v.Z() - rectSize;
|
||||
}
|
||||
QVector3D V(v.X(), v.Y(), v.Z());
|
||||
|
||||
QVector3D p1 = V - rectSize * X - rectSize * Y;
|
||||
QVector3D p2 = V + rectSize * X - rectSize * Y;
|
||||
QVector3D p3 = V + rectSize * X + rectSize * Y;
|
||||
QVector3D p4 = V - rectSize * X + rectSize * Y;
|
||||
vertices << p1.x() << p1.y() << p1.z() << p2.x() << p2.y() << p2.z();
|
||||
vertices << p2.x() << p2.y() << p2.z() << p3.x() << p3.y() << p3.z();
|
||||
vertices << p3.x() << p3.y() << p3.z() << p4.x() << p4.y() << p4.z();
|
||||
vertices << p4.x() << p4.y() << p4.z() << p1.x() << p1.y() << p1.z();
|
||||
}
|
||||
m_viewport->shaderProgram()->setUniformValue(m_viewport->colorLoc(), QVector4D(1.0f, 1.0f, 0.0f, 0.5f));
|
||||
m_viewport->vbo().bind();
|
||||
|
||||
Reference in New Issue
Block a user