feat: Add vertex snapping and draw line endpoints
Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
@@ -161,6 +161,30 @@ void ViewportWidget::paintGL()
|
|||||||
}
|
}
|
||||||
glEnd();
|
glEnd();
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
|
} else if (m_isSnappingVertex) {
|
||||||
|
const float rectSize = 0.0075f * -m_zoom;
|
||||||
|
glColor4f(1.0, 1.0, 0.0, 0.5f);
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||||
|
glBegin(GL_LINE_LOOP);
|
||||||
|
if (m_currentPlane == SketchPlane::XY) {
|
||||||
|
glVertex3f(m_snapVertex.X() - rectSize, m_snapVertex.Y() - rectSize, m_snapVertex.Z());
|
||||||
|
glVertex3f(m_snapVertex.X() + rectSize, m_snapVertex.Y() - rectSize, m_snapVertex.Z());
|
||||||
|
glVertex3f(m_snapVertex.X() + rectSize, m_snapVertex.Y() + rectSize, m_snapVertex.Z());
|
||||||
|
glVertex3f(m_snapVertex.X() - rectSize, m_snapVertex.Y() + rectSize, m_snapVertex.Z());
|
||||||
|
} else if (m_currentPlane == SketchPlane::XZ) {
|
||||||
|
glVertex3f(m_snapVertex.X() - rectSize, m_snapVertex.Y(), m_snapVertex.Z() - rectSize);
|
||||||
|
glVertex3f(m_snapVertex.X() + rectSize, m_snapVertex.Y(), m_snapVertex.Z() - rectSize);
|
||||||
|
glVertex3f(m_snapVertex.X() + rectSize, m_snapVertex.Y(), m_snapVertex.Z() + rectSize);
|
||||||
|
glVertex3f(m_snapVertex.X() - rectSize, m_snapVertex.Y(), m_snapVertex.Z() + rectSize);
|
||||||
|
} else if (m_currentPlane == SketchPlane::YZ) {
|
||||||
|
glVertex3f(m_snapVertex.X(), m_snapVertex.Y() - rectSize, m_snapVertex.Z() - rectSize);
|
||||||
|
glVertex3f(m_snapVertex.X(), m_snapVertex.Y() + rectSize, m_snapVertex.Z() - rectSize);
|
||||||
|
glVertex3f(m_snapVertex.X(), m_snapVertex.Y() + rectSize, m_snapVertex.Z() + rectSize);
|
||||||
|
glVertex3f(m_snapVertex.X(), m_snapVertex.Y() - rectSize, m_snapVertex.Z() + rectSize);
|
||||||
|
}
|
||||||
|
glEnd();
|
||||||
|
glDisable(GL_BLEND);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_isDefiningLine && m_activeTool == static_cast<int>(ApplicationController::ToolType::Line)) {
|
if (m_isDefiningLine && m_activeTool == static_cast<int>(ApplicationController::ToolType::Line)) {
|
||||||
@@ -169,6 +193,10 @@ void ViewportWidget::paintGL()
|
|||||||
worldPos.setX(0);
|
worldPos.setX(0);
|
||||||
worldPos.setY(0);
|
worldPos.setY(0);
|
||||||
worldPos.setZ(0);
|
worldPos.setZ(0);
|
||||||
|
} else if (m_isSnappingVertex) {
|
||||||
|
worldPos.setX(m_snapVertex.X());
|
||||||
|
worldPos.setY(m_snapVertex.Y());
|
||||||
|
worldPos.setZ(m_snapVertex.Z());
|
||||||
}
|
}
|
||||||
glBegin(GL_LINES);
|
glBegin(GL_LINES);
|
||||||
glColor3f(1.0, 1.0, 0.0);
|
glColor3f(1.0, 1.0, 0.0);
|
||||||
@@ -209,6 +237,8 @@ void ViewportWidget::mousePressEvent(QMouseEvent *event)
|
|||||||
gp_Pnt p;
|
gp_Pnt p;
|
||||||
if (m_isSnappingOrigin) {
|
if (m_isSnappingOrigin) {
|
||||||
p.SetCoord(0, 0, 0);
|
p.SetCoord(0, 0, 0);
|
||||||
|
} else if (m_isSnappingVertex) {
|
||||||
|
p = m_snapVertex;
|
||||||
} else {
|
} else {
|
||||||
QVector3D worldPos = unproject(event->pos());
|
QVector3D worldPos = unproject(event->pos());
|
||||||
p.SetCoord(worldPos.x(), worldPos.y(), worldPos.z());
|
p.SetCoord(worldPos.x(), worldPos.y(), worldPos.z());
|
||||||
@@ -253,6 +283,54 @@ void ViewportWidget::mouseMoveEvent(QMouseEvent *event)
|
|||||||
|
|
||||||
if (shouldSnap != m_isSnappingOrigin) {
|
if (shouldSnap != m_isSnappingOrigin) {
|
||||||
m_isSnappingOrigin = shouldSnap;
|
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) {
|
||||||
|
QVector3D worldPos = unproject(m_currentMousePos);
|
||||||
|
const float snapRectHalfSize = 0.0075f * -m_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.y() - vertex.Y()) < snapRectHalfSize;
|
||||||
|
break;
|
||||||
|
case SketchPlane::XZ:
|
||||||
|
isClose = qAbs(worldPos.x() - vertex.X()) < snapRectHalfSize && qAbs(worldPos.z() - vertex.Z()) < 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -560,6 +638,7 @@ void ViewportWidget::drawSketch(const SketchFeature* sketch)
|
|||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
glLineWidth(2.0f);
|
glLineWidth(2.0f);
|
||||||
glColor3f(1.0, 1.0, 1.0);
|
glColor3f(1.0, 1.0, 1.0);
|
||||||
|
glPointSize(5.0f);
|
||||||
|
|
||||||
for (const auto& obj : sketch->objects()) {
|
for (const auto& obj : sketch->objects()) {
|
||||||
if (obj->type() == SketchObject::ObjectType::Line) {
|
if (obj->type() == SketchObject::ObjectType::Line) {
|
||||||
@@ -570,6 +649,11 @@ void ViewportWidget::drawSketch(const SketchFeature* sketch)
|
|||||||
glVertex3d(start.X(), start.Y(), start.Z());
|
glVertex3d(start.X(), start.Y(), start.Z());
|
||||||
glVertex3d(end.X(), end.Y(), end.Z());
|
glVertex3d(end.X(), end.Y(), end.Z());
|
||||||
glEnd();
|
glEnd();
|
||||||
|
|
||||||
|
glBegin(GL_POINTS);
|
||||||
|
glVertex3d(start.X(), start.Y(), start.Z());
|
||||||
|
glVertex3d(end.X(), end.Y(), end.Z());
|
||||||
|
glEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|||||||
@@ -91,6 +91,8 @@ private:
|
|||||||
gp_Pnt m_firstLinePoint;
|
gp_Pnt m_firstLinePoint;
|
||||||
QPoint m_currentMousePos;
|
QPoint m_currentMousePos;
|
||||||
bool m_isSnappingOrigin = false;
|
bool m_isSnappingOrigin = false;
|
||||||
|
bool m_isSnappingVertex = false;
|
||||||
|
gp_Pnt m_snapVertex;
|
||||||
|
|
||||||
QMap<int, QSvgRenderer*> m_toolIcons;
|
QMap<int, QSvgRenderer*> m_toolIcons;
|
||||||
QSvgRenderer* m_cursorRenderer = nullptr;
|
QSvgRenderer* m_cursorRenderer = nullptr;
|
||||||
|
|||||||
Reference in New Issue
Block a user