refactor: Extract snapping logic into dedicated Snapping class
Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
185
src/Snapping.cpp
185
src/Snapping.cpp
@@ -0,0 +1,185 @@
|
|||||||
|
#include "Snapping.h"
|
||||||
|
|
||||||
|
#include "ViewportWidget.h"
|
||||||
|
#include "Camera.h"
|
||||||
|
#include "Document.h"
|
||||||
|
#include "SketchFeature.h"
|
||||||
|
#include "SketchLine.h"
|
||||||
|
#include "SketchRectangle.h"
|
||||||
|
#include "SketchObject.h"
|
||||||
|
#include "ApplicationController.h"
|
||||||
|
|
||||||
|
#include <QOpenGLShaderProgram>
|
||||||
|
#include <QVector>
|
||||||
|
#include <QtMath>
|
||||||
|
|
||||||
|
Snapping::Snapping(ViewportWidget* viewport) : m_viewport(viewport)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Snapping::update(const QPoint& mousePos)
|
||||||
|
{
|
||||||
|
bool oldIsSnappingOrigin = m_isSnappingOrigin;
|
||||||
|
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());
|
||||||
|
const float snapRectHalfSize = 0.0075f * -m_viewport->camera()->zoom();
|
||||||
|
|
||||||
|
switch (m_viewport->currentPlane()) {
|
||||||
|
case ViewportWidget::SketchPlane::XY:
|
||||||
|
shouldSnap = qAbs(worldPos.x()) < snapRectHalfSize && qAbs(worldPos.z()) < snapRectHalfSize;
|
||||||
|
break;
|
||||||
|
case ViewportWidget::SketchPlane::XZ:
|
||||||
|
shouldSnap = qAbs(worldPos.x()) < snapRectHalfSize && qAbs(worldPos.y()) < snapRectHalfSize;
|
||||||
|
break;
|
||||||
|
case ViewportWidget::SketchPlane::YZ:
|
||||||
|
shouldSnap = qAbs(worldPos.y()) < snapRectHalfSize && qAbs(worldPos.z()) < snapRectHalfSize;
|
||||||
|
break;
|
||||||
|
case ViewportWidget::SketchPlane::NONE:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_isSnappingOrigin = shouldSnap;
|
||||||
|
if (m_isSnappingOrigin) {
|
||||||
|
m_isSnappingVertex = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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());
|
||||||
|
const float snapRectHalfSize = 0.0075f * -m_viewport->camera()->zoom();
|
||||||
|
|
||||||
|
for (Feature* feature : m_viewport->document()->features()) {
|
||||||
|
if (auto sketch = dynamic_cast<SketchFeature*>(feature)) {
|
||||||
|
for (const auto& obj : sketch->objects()) {
|
||||||
|
if (obj->type() == SketchObject::ObjectType::Line) {
|
||||||
|
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.z() - vertex.Z()) < snapRectHalfSize;
|
||||||
|
break;
|
||||||
|
case ViewportWidget::SketchPlane::XZ:
|
||||||
|
isClose = qAbs(worldPos.x() - vertex.X()) < snapRectHalfSize && qAbs(worldPos.y() - vertex.Y()) < 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isClose) {
|
||||||
|
m_isSnappingVertex = true;
|
||||||
|
m_snapVertex = vertex;
|
||||||
|
goto end_snap_check;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (obj->type() == SketchObject::ObjectType::Rectangle) {
|
||||||
|
auto rect = static_cast<const SketchRectangle*>(obj);
|
||||||
|
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(), p1.Y(), p3.Z());
|
||||||
|
} else if (sketch->plane() == SketchFeature::SketchPlane::XZ) {
|
||||||
|
p2.SetCoord(p3.X(), p1.Y(), p1.Z());
|
||||||
|
p4.SetCoord(p1.X(), p3.Y(), p1.Z());
|
||||||
|
} else if (sketch->plane() == SketchFeature::SketchPlane::YZ) {
|
||||||
|
p2.SetCoord(p1.X(), p3.Y(), p1.Z());
|
||||||
|
p4.SetCoord(p1.X(), p1.Y(), p3.Z());
|
||||||
|
}
|
||||||
|
|
||||||
|
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.z() - vertex.Z()) < snapRectHalfSize;
|
||||||
|
break;
|
||||||
|
case ViewportWidget::SketchPlane::XZ:
|
||||||
|
isClose = qAbs(worldPos.x() - vertex.X()) < snapRectHalfSize && qAbs(worldPos.y() - vertex.Y()) < 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isClose) {
|
||||||
|
m_isSnappingVertex = true;
|
||||||
|
m_snapVertex = vertex;
|
||||||
|
goto end_snap_check;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end_snap_check:;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (oldIsSnappingOrigin != m_isSnappingOrigin) || (oldIsSnappingVertex != m_isSnappingVertex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Snapping::paintGL() const
|
||||||
|
{
|
||||||
|
if (!m_isSnappingOrigin && !m_isSnappingVertex) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVector<GLfloat> vertices;
|
||||||
|
if (m_isSnappingOrigin) {
|
||||||
|
const float rectSize = 0.0075f * -m_viewport->camera()->zoom();
|
||||||
|
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||||
|
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::XZ) {
|
||||||
|
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::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;
|
||||||
|
}
|
||||||
|
} 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() << 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::XZ) {
|
||||||
|
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::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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_viewport->shaderProgram()->setUniformValue(m_viewport->colorLoc(), QVector4D(1.0f, 1.0f, 0.0f, 0.5f));
|
||||||
|
m_viewport->vbo().bind();
|
||||||
|
m_viewport->vbo().allocate(vertices.constData(), vertices.size() * sizeof(GLfloat));
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
glDrawArrays(GL_LINES, 0, vertices.size() / 3);
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#ifndef SNAPPING_H
|
||||||
|
#define SNAPPING_H
|
||||||
|
|
||||||
|
#include <gp_Pnt.hxx>
|
||||||
|
#include <QPoint>
|
||||||
|
|
||||||
|
class ViewportWidget;
|
||||||
|
|
||||||
|
class Snapping
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit Snapping(ViewportWidget* viewport);
|
||||||
|
|
||||||
|
bool update(const QPoint& mousePos);
|
||||||
|
void paintGL() const;
|
||||||
|
|
||||||
|
bool isSnappingOrigin() const { return m_isSnappingOrigin; }
|
||||||
|
bool isSnappingVertex() const { return m_isSnappingVertex; }
|
||||||
|
const gp_Pnt& snapVertex() const { return m_snapVertex; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
ViewportWidget* m_viewport = nullptr;
|
||||||
|
bool m_isSnappingOrigin = false;
|
||||||
|
bool m_isSnappingVertex = false;
|
||||||
|
gp_Pnt m_snapVertex;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SNAPPING_H
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include "ViewportWidget.h"
|
#include "ViewportWidget.h"
|
||||||
|
#include "Snapping.h"
|
||||||
#include "Camera.h"
|
#include "Camera.h"
|
||||||
#include "ViewCube.h"
|
#include "ViewCube.h"
|
||||||
#include "SketchGrid.h"
|
#include "SketchGrid.h"
|
||||||
@@ -61,6 +62,8 @@ ViewportWidget::ViewportWidget(QWidget *parent)
|
|||||||
|
|
||||||
m_sketchTools.insert(static_cast<int>(ApplicationController::ToolType::Line), new LineTool(this));
|
m_sketchTools.insert(static_cast<int>(ApplicationController::ToolType::Line), new LineTool(this));
|
||||||
m_sketchTools.insert(static_cast<int>(ApplicationController::ToolType::Rectangle), new RectangleTool(this));
|
m_sketchTools.insert(static_cast<int>(ApplicationController::ToolType::Rectangle), new RectangleTool(this));
|
||||||
|
|
||||||
|
m_snapping = new Snapping(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewportWidget::~ViewportWidget()
|
ViewportWidget::~ViewportWidget()
|
||||||
@@ -74,6 +77,7 @@ ViewportWidget::~ViewportWidget()
|
|||||||
doneCurrent();
|
doneCurrent();
|
||||||
|
|
||||||
delete m_featureBrowser;
|
delete m_featureBrowser;
|
||||||
|
delete m_snapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewportWidget::setDocument(Document* document)
|
void ViewportWidget::setDocument(Document* document)
|
||||||
@@ -148,59 +152,7 @@ void ViewportWidget::paintGL()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<GLfloat> vertices;
|
m_snapping->paintGL();
|
||||||
if (m_isSnappingOrigin) {
|
|
||||||
const float rectSize = 0.0075f * -m_camera->zoom();
|
|
||||||
if (m_currentPlane == SketchPlane::XY) {
|
|
||||||
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_currentPlane == SketchPlane::XZ) {
|
|
||||||
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_currentPlane == 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;
|
|
||||||
}
|
|
||||||
m_shaderProgram->setUniformValue(m_colorLoc, QVector4D(1.0f, 1.0f, 0.0f, 0.5f));
|
|
||||||
m_vbo.bind();
|
|
||||||
m_vbo.allocate(vertices.constData(), vertices.size() * sizeof(GLfloat));
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
glDrawArrays(GL_LINES, 0, vertices.size() / 3);
|
|
||||||
glDisable(GL_BLEND);
|
|
||||||
} else if (m_isSnappingVertex) {
|
|
||||||
const float rectSize = 0.0075f * -m_camera->zoom();
|
|
||||||
const auto& v = m_snapVertex;
|
|
||||||
if (m_currentPlane == SketchPlane::XY) {
|
|
||||||
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_currentPlane == SketchPlane::XZ) {
|
|
||||||
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_currentPlane == 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;
|
|
||||||
}
|
|
||||||
m_shaderProgram->setUniformValue(m_colorLoc, QVector4D(1.0f, 1.0f, 0.0f, 0.5f));
|
|
||||||
m_vbo.bind();
|
|
||||||
m_vbo.allocate(vertices.constData(), vertices.size() * sizeof(GLfloat));
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
||||||
glDrawArrays(GL_LINES, 0, vertices.size() / 3);
|
|
||||||
glDisable(GL_BLEND);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_activeSketchTool) {
|
if (m_activeSketchTool) {
|
||||||
m_activeSketchTool->paintGL();
|
m_activeSketchTool->paintGL();
|
||||||
@@ -274,116 +226,7 @@ void ViewportWidget::mouseMoveEvent(QMouseEvent *event)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool shouldSnap = false;
|
if (m_snapping->update(m_currentMousePos)) {
|
||||||
if (m_currentPlane != SketchPlane::NONE && m_activeTool != static_cast<int>(ApplicationController::ToolType::None)) {
|
|
||||||
QVector3D worldPos = unproject(m_currentMousePos, m_currentPlane);
|
|
||||||
const float snapRectHalfSize = 0.0075f * -m_camera->zoom();
|
|
||||||
|
|
||||||
switch (m_currentPlane) {
|
|
||||||
case SketchPlane::XY:
|
|
||||||
shouldSnap = qAbs(worldPos.x()) < snapRectHalfSize && qAbs(worldPos.z()) < snapRectHalfSize;
|
|
||||||
break;
|
|
||||||
case SketchPlane::XZ:
|
|
||||||
shouldSnap = qAbs(worldPos.x()) < snapRectHalfSize && qAbs(worldPos.y()) < snapRectHalfSize;
|
|
||||||
break;
|
|
||||||
case SketchPlane::YZ:
|
|
||||||
shouldSnap = qAbs(worldPos.y()) < snapRectHalfSize && qAbs(worldPos.z()) < snapRectHalfSize;
|
|
||||||
break;
|
|
||||||
case SketchPlane::NONE:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldSnap != m_isSnappingOrigin) {
|
|
||||||
m_isSnappingOrigin = shouldSnap;
|
|
||||||
if (m_isSnappingOrigin) {
|
|
||||||
m_isSnappingVertex = false;
|
|
||||||
}
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool oldIsSnappingVertex = m_isSnappingVertex;
|
|
||||||
m_isSnappingVertex = false;
|
|
||||||
if (!m_isSnappingOrigin && m_document && m_currentPlane != SketchPlane::NONE && m_activeTool != static_cast<int>(ApplicationController::ToolType::None)) {
|
|
||||||
QVector3D worldPos = unproject(m_currentMousePos, m_currentPlane);
|
|
||||||
const float snapRectHalfSize = 0.0075f * -m_camera->zoom();
|
|
||||||
|
|
||||||
for (Feature* feature : m_document->features()) {
|
|
||||||
if (auto sketch = dynamic_cast<SketchFeature*>(feature)) {
|
|
||||||
for (const auto& obj : sketch->objects()) {
|
|
||||||
if (obj->type() == SketchObject::ObjectType::Line) {
|
|
||||||
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_currentPlane) {
|
|
||||||
case SketchPlane::XY:
|
|
||||||
isClose = qAbs(worldPos.x() - vertex.X()) < snapRectHalfSize && qAbs(worldPos.z() - vertex.Z()) < snapRectHalfSize;
|
|
||||||
break;
|
|
||||||
case SketchPlane::XZ:
|
|
||||||
isClose = qAbs(worldPos.x() - vertex.X()) < snapRectHalfSize && qAbs(worldPos.y() - vertex.Y()) < snapRectHalfSize;
|
|
||||||
break;
|
|
||||||
case SketchPlane::YZ:
|
|
||||||
isClose = qAbs(worldPos.y() - vertex.Y()) < snapRectHalfSize && qAbs(worldPos.z() - vertex.Z()) < snapRectHalfSize;
|
|
||||||
break;
|
|
||||||
case SketchPlane::NONE:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isClose) {
|
|
||||||
m_isSnappingVertex = true;
|
|
||||||
m_snapVertex = vertex;
|
|
||||||
goto end_snap_check;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (obj->type() == SketchObject::ObjectType::Rectangle) {
|
|
||||||
auto rect = static_cast<const SketchRectangle*>(obj);
|
|
||||||
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(), p1.Y(), p3.Z());
|
|
||||||
} else if (sketch->plane() == SketchFeature::SketchPlane::XZ) {
|
|
||||||
p2.SetCoord(p3.X(), p1.Y(), p1.Z());
|
|
||||||
p4.SetCoord(p1.X(), p3.Y(), p1.Z());
|
|
||||||
} else if (sketch->plane() == SketchFeature::SketchPlane::YZ) {
|
|
||||||
p2.SetCoord(p1.X(), p3.Y(), p1.Z());
|
|
||||||
p4.SetCoord(p1.X(), p1.Y(), p3.Z());
|
|
||||||
}
|
|
||||||
|
|
||||||
const gp_Pnt vertices[] = {p1, p2, p3, p4};
|
|
||||||
for (const auto& vertex : vertices) {
|
|
||||||
bool isClose = false;
|
|
||||||
switch (m_currentPlane) {
|
|
||||||
case SketchPlane::XY:
|
|
||||||
isClose = qAbs(worldPos.x() - vertex.X()) < snapRectHalfSize && qAbs(worldPos.z() - vertex.Z()) < snapRectHalfSize;
|
|
||||||
break;
|
|
||||||
case SketchPlane::XZ:
|
|
||||||
isClose = qAbs(worldPos.x() - vertex.X()) < snapRectHalfSize && qAbs(worldPos.y() - vertex.Y()) < snapRectHalfSize;
|
|
||||||
break;
|
|
||||||
case SketchPlane::YZ:
|
|
||||||
isClose = qAbs(worldPos.y() - vertex.Y()) < snapRectHalfSize && qAbs(worldPos.z() - vertex.Z()) < snapRectHalfSize;
|
|
||||||
break;
|
|
||||||
case SketchPlane::NONE:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isClose) {
|
|
||||||
m_isSnappingVertex = true;
|
|
||||||
m_snapVertex = vertex;
|
|
||||||
goto end_snap_check;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end_snap_check:;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (oldIsSnappingVertex != m_isSnappingVertex) {
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,6 +280,21 @@ void ViewportWidget::deactivateActiveTool()
|
|||||||
emit toolDeactivated();
|
emit toolDeactivated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ViewportWidget::isSnappingOrigin() const
|
||||||
|
{
|
||||||
|
return m_snapping->isSnappingOrigin();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ViewportWidget::isSnappingVertex() const
|
||||||
|
{
|
||||||
|
return m_snapping->isSnappingVertex();
|
||||||
|
}
|
||||||
|
|
||||||
|
const gp_Pnt& ViewportWidget::snapVertex() const
|
||||||
|
{
|
||||||
|
return m_snapping->snapVertex();
|
||||||
|
}
|
||||||
|
|
||||||
void ViewportWidget::setSnappingHorizontal(bool snapping)
|
void ViewportWidget::setSnappingHorizontal(bool snapping)
|
||||||
{
|
{
|
||||||
m_isSnappingHorizontal = snapping;
|
m_isSnappingHorizontal = snapping;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ class FeatureBrowser;
|
|||||||
class SketchFeature;
|
class SketchFeature;
|
||||||
class Camera;
|
class Camera;
|
||||||
class SketchTool;
|
class SketchTool;
|
||||||
|
class Snapping;
|
||||||
|
|
||||||
class ViewportWidget : public QOpenGLWidget, protected QOpenGLFunctions
|
class ViewportWidget : public QOpenGLWidget, protected QOpenGLFunctions
|
||||||
{
|
{
|
||||||
@@ -45,11 +46,13 @@ public:
|
|||||||
QOpenGLBuffer& vbo() { return m_vbo; }
|
QOpenGLBuffer& vbo() { return m_vbo; }
|
||||||
int colorLoc() const { return m_colorLoc; }
|
int colorLoc() const { return m_colorLoc; }
|
||||||
Camera* camera() const { return m_camera; }
|
Camera* camera() const { return m_camera; }
|
||||||
|
Document* document() const { return m_document; }
|
||||||
SketchPlane currentPlane() const { return m_currentPlane; }
|
SketchPlane currentPlane() const { return m_currentPlane; }
|
||||||
const QPoint& currentMousePos() const { return m_currentMousePos; }
|
const QPoint& currentMousePos() const { return m_currentMousePos; }
|
||||||
bool isSnappingOrigin() const { return m_isSnappingOrigin; }
|
bool isSnappingOrigin() const;
|
||||||
bool isSnappingVertex() const { return m_isSnappingVertex; }
|
bool isSnappingVertex() const;
|
||||||
const gp_Pnt& snapVertex() const { return m_snapVertex; }
|
const gp_Pnt& snapVertex() const;
|
||||||
|
int activeTool() const { return m_activeTool; }
|
||||||
bool isSnappingHorizontal() const { return m_isSnappingHorizontal; }
|
bool isSnappingHorizontal() const { return m_isSnappingHorizontal; }
|
||||||
bool isSnappingVertical() const { return m_isSnappingVertical; }
|
bool isSnappingVertical() const { return m_isSnappingVertical; }
|
||||||
void setSnappingHorizontal(bool snapping);
|
void setSnappingHorizontal(bool snapping);
|
||||||
@@ -111,9 +114,7 @@ private:
|
|||||||
SketchTool* m_activeSketchTool = nullptr;
|
SketchTool* m_activeSketchTool = nullptr;
|
||||||
QMap<int, SketchTool*> m_sketchTools;
|
QMap<int, SketchTool*> m_sketchTools;
|
||||||
QPoint m_currentMousePos;
|
QPoint m_currentMousePos;
|
||||||
bool m_isSnappingOrigin = false;
|
Snapping* m_snapping = nullptr;
|
||||||
bool m_isSnappingVertex = false;
|
|
||||||
gp_Pnt m_snapVertex;
|
|
||||||
bool m_isSnappingHorizontal = false;
|
bool m_isSnappingHorizontal = false;
|
||||||
bool m_isSnappingVertical = false;
|
bool m_isSnappingVertical = false;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user