|
|
|
|
@@ -135,6 +135,10 @@ void ViewportWidget::paintGL()
|
|
|
|
|
glMatrixMode(GL_MODELVIEW);
|
|
|
|
|
glLoadMatrixf(model.constData());
|
|
|
|
|
|
|
|
|
|
if (m_isSelectingPlane) {
|
|
|
|
|
drawSelectionPlanes();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_currentPlane != SketchPlane::NONE) {
|
|
|
|
|
m_sketchGrid->paintGL(static_cast<SketchGrid::SketchPlane>(m_currentPlane), projection, model);
|
|
|
|
|
}
|
|
|
|
|
@@ -198,7 +202,7 @@ void ViewportWidget::paintGL()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_isDefiningLine && m_activeTool == static_cast<int>(ApplicationController::ToolType::Line)) {
|
|
|
|
|
QVector3D worldPos = unproject(m_currentMousePos);
|
|
|
|
|
QVector3D worldPos = unproject(m_currentMousePos, m_currentPlane);
|
|
|
|
|
if (m_isSnappingOrigin) {
|
|
|
|
|
worldPos.setX(0);
|
|
|
|
|
worldPos.setY(0);
|
|
|
|
|
@@ -286,14 +290,25 @@ void ViewportWidget::resizeGL(int w, int h)
|
|
|
|
|
|
|
|
|
|
void ViewportWidget::mousePressEvent(QMouseEvent *event)
|
|
|
|
|
{
|
|
|
|
|
if (event->button() == Qt::LeftButton && m_currentPlane != SketchPlane::NONE && m_activeTool == static_cast<int>(ApplicationController::ToolType::Line)) {
|
|
|
|
|
if (event->button() == Qt::LeftButton) {
|
|
|
|
|
if (m_isSelectingPlane) {
|
|
|
|
|
if (m_highlightedPlane != SketchPlane::NONE) {
|
|
|
|
|
emit planeSelected(m_highlightedPlane);
|
|
|
|
|
m_isSelectingPlane = false;
|
|
|
|
|
m_highlightedPlane = SketchPlane::NONE;
|
|
|
|
|
update();
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_currentPlane != SketchPlane::NONE && m_activeTool == static_cast<int>(ApplicationController::ToolType::Line)) {
|
|
|
|
|
gp_Pnt p;
|
|
|
|
|
if (m_isSnappingOrigin) {
|
|
|
|
|
p.SetCoord(0, 0, 0);
|
|
|
|
|
} else if (m_isSnappingVertex) {
|
|
|
|
|
p = m_snapVertex;
|
|
|
|
|
} else {
|
|
|
|
|
QVector3D worldPos = unproject(event->pos());
|
|
|
|
|
QVector3D worldPos = unproject(event->pos(), m_currentPlane);
|
|
|
|
|
if (m_isSnappingHorizontal) {
|
|
|
|
|
if (m_currentPlane == SketchPlane::XY) worldPos.setZ(m_firstLinePoint.Z());
|
|
|
|
|
else if (m_currentPlane == SketchPlane::XZ) worldPos.setY(m_firstLinePoint.Y());
|
|
|
|
|
@@ -314,6 +329,7 @@ void ViewportWidget::mousePressEvent(QMouseEvent *event)
|
|
|
|
|
m_firstLinePoint = p;
|
|
|
|
|
}
|
|
|
|
|
update();
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
lastPos = event->pos();
|
|
|
|
|
}
|
|
|
|
|
@@ -323,9 +339,17 @@ void ViewportWidget::mouseMoveEvent(QMouseEvent *event)
|
|
|
|
|
{
|
|
|
|
|
m_currentMousePos = event->pos();
|
|
|
|
|
|
|
|
|
|
if (m_isSelectingPlane) {
|
|
|
|
|
SketchPlane newHighlight = checkPlaneSelection(m_currentMousePos);
|
|
|
|
|
if (newHighlight != m_highlightedPlane) {
|
|
|
|
|
m_highlightedPlane = newHighlight;
|
|
|
|
|
update();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool shouldSnap = false;
|
|
|
|
|
if (m_currentPlane != SketchPlane::NONE && m_activeTool != static_cast<int>(ApplicationController::ToolType::None)) {
|
|
|
|
|
QVector3D worldPos = unproject(m_currentMousePos);
|
|
|
|
|
QVector3D worldPos = unproject(m_currentMousePos, m_currentPlane);
|
|
|
|
|
const float snapRectHalfSize = 0.0075f * -m_zoom;
|
|
|
|
|
|
|
|
|
|
switch (m_currentPlane) {
|
|
|
|
|
@@ -354,7 +378,7 @@ void ViewportWidget::mouseMoveEvent(QMouseEvent *event)
|
|
|
|
|
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);
|
|
|
|
|
QVector3D worldPos = unproject(m_currentMousePos, m_currentPlane);
|
|
|
|
|
const float snapRectHalfSize = 0.0075f * -m_zoom;
|
|
|
|
|
|
|
|
|
|
for (Feature* feature : m_document->features()) {
|
|
|
|
|
@@ -402,7 +426,7 @@ void ViewportWidget::mouseMoveEvent(QMouseEvent *event)
|
|
|
|
|
m_isSnappingVertical = false;
|
|
|
|
|
|
|
|
|
|
if (m_isDefiningLine && !m_isSnappingOrigin && !m_isSnappingVertex) {
|
|
|
|
|
QVector3D worldPos = unproject(m_currentMousePos);
|
|
|
|
|
QVector3D worldPos = unproject(m_currentMousePos, m_currentPlane);
|
|
|
|
|
QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z());
|
|
|
|
|
QVector3D delta = worldPos - startPos;
|
|
|
|
|
|
|
|
|
|
@@ -538,6 +562,13 @@ void ViewportWidget::onSketchModeStarted(SketchPlane plane)
|
|
|
|
|
animGroup->start(QAbstractAnimation::DeleteWhenStopped);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ViewportWidget::onPlaneSelectionModeStarted()
|
|
|
|
|
{
|
|
|
|
|
m_isSelectingPlane = true;
|
|
|
|
|
m_highlightedPlane = SketchPlane::NONE;
|
|
|
|
|
update();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ViewportWidget::onSketchModeEnded()
|
|
|
|
|
{
|
|
|
|
|
auto* animGroup = new QParallelAnimationGroup(this);
|
|
|
|
|
@@ -678,7 +709,7 @@ void ViewportWidget::onActiveToolChanged(int tool)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVector3D ViewportWidget::unproject(const QPoint& screenPos)
|
|
|
|
|
QVector3D ViewportWidget::unproject(const QPoint& screenPos, SketchPlane plane)
|
|
|
|
|
{
|
|
|
|
|
QMatrix4x4 model;
|
|
|
|
|
model.translate(m_panX, m_panY, m_zoom);
|
|
|
|
|
@@ -711,7 +742,7 @@ QVector3D ViewportWidget::unproject(const QPoint& screenPos)
|
|
|
|
|
QVector3D rayDir = (QVector3D(farPoint_world) - rayOrigin).normalized();
|
|
|
|
|
|
|
|
|
|
QVector3D planeNormal;
|
|
|
|
|
switch (m_currentPlane) {
|
|
|
|
|
switch (plane) {
|
|
|
|
|
case SketchPlane::XY: planeNormal = QVector3D(0, 1, 0); break;
|
|
|
|
|
case SketchPlane::XZ: planeNormal = QVector3D(0, 0, 1); break;
|
|
|
|
|
case SketchPlane::YZ: planeNormal = QVector3D(1, 0, 0); break;
|
|
|
|
|
@@ -754,3 +785,105 @@ void ViewportWidget::drawSketch(const SketchFeature* sketch)
|
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ViewportWidget::drawSelectionPlanes()
|
|
|
|
|
{
|
|
|
|
|
const float planeSize = 5.0f;
|
|
|
|
|
const float planeOffset = 1.0f;
|
|
|
|
|
|
|
|
|
|
glEnable(GL_BLEND);
|
|
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
|
|
|
glLineWidth(2.0f);
|
|
|
|
|
glDisable(GL_DEPTH_TEST);
|
|
|
|
|
|
|
|
|
|
// Draw back to front for proper blending
|
|
|
|
|
|
|
|
|
|
// XY Plane (Top), normal is Y (green)
|
|
|
|
|
glColor4f(0.0f, 1.0f, 0.0f, m_highlightedPlane == SketchPlane::XY ? 0.5f : 0.2f);
|
|
|
|
|
if (m_highlightedPlane == SketchPlane::XY) {
|
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
|
glVertex3f(planeOffset, 0, planeOffset);
|
|
|
|
|
glVertex3f(planeOffset + planeSize, 0, planeOffset);
|
|
|
|
|
glVertex3f(planeOffset + planeSize, 0, planeOffset + planeSize);
|
|
|
|
|
glVertex3f(planeOffset, 0, planeOffset + planeSize);
|
|
|
|
|
glEnd();
|
|
|
|
|
}
|
|
|
|
|
glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
|
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
|
|
|
glVertex3f(planeOffset, 0, planeOffset);
|
|
|
|
|
glVertex3f(planeOffset + planeSize, 0, planeOffset);
|
|
|
|
|
glVertex3f(planeOffset + planeSize, 0, planeOffset + planeSize);
|
|
|
|
|
glVertex3f(planeOffset, 0, planeOffset + planeSize);
|
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
|
|
// XZ Plane (Front), normal is Z (blue)
|
|
|
|
|
glColor4f(0.0f, 0.0f, 1.0f, m_highlightedPlane == SketchPlane::XZ ? 0.5f : 0.2f);
|
|
|
|
|
if (m_highlightedPlane == SketchPlane::XZ) {
|
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
|
glVertex3f(planeOffset, planeOffset, 0);
|
|
|
|
|
glVertex3f(planeOffset + planeSize, planeOffset, 0);
|
|
|
|
|
glVertex3f(planeOffset + planeSize, planeOffset + planeSize, 0);
|
|
|
|
|
glVertex3f(planeOffset, planeOffset + planeSize, 0);
|
|
|
|
|
glEnd();
|
|
|
|
|
}
|
|
|
|
|
glColor4f(0.0f, 0.0f, 1.0f, 1.0f);
|
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
|
|
|
glVertex3f(planeOffset, planeOffset, 0);
|
|
|
|
|
glVertex3f(planeOffset + planeSize, planeOffset, 0);
|
|
|
|
|
glVertex3f(planeOffset + planeSize, planeOffset + planeSize, 0);
|
|
|
|
|
glVertex3f(planeOffset, planeOffset + planeSize, 0);
|
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
|
|
// YZ Plane (Right), normal is X (red)
|
|
|
|
|
glColor4f(1.0f, 0.0f, 0.0f, m_highlightedPlane == SketchPlane::YZ ? 0.5f : 0.2f);
|
|
|
|
|
if (m_highlightedPlane == SketchPlane::YZ) {
|
|
|
|
|
glBegin(GL_QUADS);
|
|
|
|
|
glVertex3f(0, planeOffset, planeOffset);
|
|
|
|
|
glVertex3f(0, planeOffset + planeSize, planeOffset);
|
|
|
|
|
glVertex3f(0, planeOffset + planeSize, planeOffset + planeSize);
|
|
|
|
|
glVertex3f(0, planeOffset, planeOffset + planeSize);
|
|
|
|
|
glEnd();
|
|
|
|
|
}
|
|
|
|
|
glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
|
|
|
|
|
glBegin(GL_LINE_LOOP);
|
|
|
|
|
glVertex3f(0, planeOffset, planeOffset);
|
|
|
|
|
glVertex3f(0, planeOffset + planeSize, planeOffset);
|
|
|
|
|
glVertex3f(0, planeOffset + planeSize, planeOffset + planeSize);
|
|
|
|
|
glVertex3f(0, planeOffset, planeOffset + planeSize);
|
|
|
|
|
glEnd();
|
|
|
|
|
|
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
|
|
|
|
glDisable(GL_BLEND);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ViewportWidget::SketchPlane ViewportWidget::checkPlaneSelection(const QPoint& screenPos)
|
|
|
|
|
{
|
|
|
|
|
const float planeSize = 5.0f;
|
|
|
|
|
const float planeOffset = 1.0f;
|
|
|
|
|
|
|
|
|
|
QVector3D intersection;
|
|
|
|
|
|
|
|
|
|
// Check front to back to handle overlaps
|
|
|
|
|
// YZ plane (Right)
|
|
|
|
|
intersection = unproject(screenPos, SketchPlane::YZ);
|
|
|
|
|
if (intersection.y() >= planeOffset && intersection.y() <= planeOffset + planeSize &&
|
|
|
|
|
intersection.z() >= planeOffset && intersection.z() <= planeOffset + planeSize) {
|
|
|
|
|
return SketchPlane::YZ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// XZ plane (Front)
|
|
|
|
|
intersection = unproject(screenPos, SketchPlane::XZ);
|
|
|
|
|
if (intersection.x() >= planeOffset && intersection.x() <= planeOffset + planeSize &&
|
|
|
|
|
intersection.y() >= planeOffset && intersection.y() <= planeOffset + planeSize) {
|
|
|
|
|
return SketchPlane::XZ;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// XY plane (Top)
|
|
|
|
|
intersection = unproject(screenPos, SketchPlane::XY);
|
|
|
|
|
if (intersection.x() >= planeOffset && intersection.x() <= planeOffset + planeSize &&
|
|
|
|
|
intersection.z() >= planeOffset && intersection.z() <= planeOffset + planeSize) {
|
|
|
|
|
return SketchPlane::XY;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return SketchPlane::NONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|