Compare commits
2 Commits
master
..
f22c14e8ad
| Author | SHA1 | Date | |
|---|---|---|---|
| f22c14e8ad | |||
| 95dfacd994 |
@@ -7,7 +7,7 @@
|
||||
On Debian 12:
|
||||
|
||||
```bash
|
||||
$ sudo apt install cmake qt6-base-dev qt6-svg-dev libtbb-dev libfontconfig1-dev
|
||||
$ sudo apt install cmake qt6-base-dev qt6-svg-dev libtbb-dev
|
||||
$ sudo apt install libocct-foundation-dev libocct-modeling-data-dev libocct-modeling-algorithms-dev libocct-visualization-dev
|
||||
|
||||
$ mkdir build
|
||||
@@ -22,7 +22,7 @@ $ ./OpenCAD
|
||||
|
||||
## License
|
||||
|
||||
This program is free and open-source software licensed under the GNU GPLv3 (or later). Please see the `LICENSE.txt` file for details.
|
||||
This program is free and open-source software licensed under the GNU GPLv3. Please see the `LICENSE.txt` file for details.
|
||||
|
||||
That means you have the right to study, change, and distribute the software and source code to anyone and for any purpose as long as you grant the same rights when distributing it.
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#include "ApplicationController.h"
|
||||
#include "Document.h"
|
||||
@@ -13,16 +13,6 @@
|
||||
#include "SketchCircle.h"
|
||||
#include "MainWindow.h"
|
||||
|
||||
#include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
#include <BRepBuilderAPI_MakeWire.hxx>
|
||||
#include <GC_MakeSegment.hxx>
|
||||
#include <ElCLib.hxx>
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <gp_Circ.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
|
||||
#include <QInputDialog>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
@@ -127,12 +117,26 @@ void ApplicationController::beginSketchCreation()
|
||||
emit planeSelectionModeStarted();
|
||||
}
|
||||
|
||||
void ApplicationController::onPlaneSelected(const gp_Ax2& plane)
|
||||
void ApplicationController::onPlaneSelected(ViewportWidget::SketchPlane plane)
|
||||
{
|
||||
auto feature = new SketchFeature("Sketch");
|
||||
m_activeSketch = feature;
|
||||
|
||||
feature->setPlane(plane);
|
||||
switch (plane) {
|
||||
case ViewportWidget::SketchPlane::XY:
|
||||
feature->setPlane(SketchFeature::SketchPlane::XY);
|
||||
break;
|
||||
case ViewportWidget::SketchPlane::XZ:
|
||||
feature->setPlane(SketchFeature::SketchPlane::XZ);
|
||||
break;
|
||||
case ViewportWidget::SketchPlane::YZ:
|
||||
feature->setPlane(SketchFeature::SketchPlane::YZ);
|
||||
break;
|
||||
case ViewportWidget::SketchPlane::NONE:
|
||||
delete feature;
|
||||
m_activeSketch = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
m_document->addFeature(feature);
|
||||
emit sketchModeStarted(plane);
|
||||
@@ -142,10 +146,6 @@ void ApplicationController::addLine(const gp_Pnt& start, const gp_Pnt& end)
|
||||
{
|
||||
if (m_activeSketch) {
|
||||
m_activeSketch->addObject(new SketchLine(start, end));
|
||||
|
||||
Handle(Geom_TrimmedCurve) segment = GC_MakeSegment(start, end);
|
||||
TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(segment);
|
||||
m_activeSketch->addShape(edge);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,27 +153,6 @@ void ApplicationController::addRectangle(const gp_Pnt& corner1, const gp_Pnt& co
|
||||
{
|
||||
if (m_activeSketch) {
|
||||
m_activeSketch->addObject(new SketchRectangle(corner1, corner2));
|
||||
|
||||
const auto& plane = m_activeSketch->plane();
|
||||
|
||||
gp_Pnt2d p1_2d(gp_Vec(plane.Location(), corner1).Dot(plane.XDirection()), gp_Vec(plane.Location(), corner1).Dot(plane.YDirection()));
|
||||
gp_Pnt2d p3_2d(gp_Vec(plane.Location(), corner2).Dot(plane.XDirection()), gp_Vec(plane.Location(), corner2).Dot(plane.YDirection()));
|
||||
|
||||
gp_Pnt2d p2_2d(p3_2d.X(), p1_2d.Y());
|
||||
gp_Pnt2d p4_2d(p1_2d.X(), p3_2d.Y());
|
||||
|
||||
gp_Pnt p2_3d = ElCLib::To3d(plane, p2_2d);
|
||||
gp_Pnt p4_3d = ElCLib::To3d(plane, p4_2d);
|
||||
|
||||
TopoDS_Edge e1 = BRepBuilderAPI_MakeEdge(corner1, p2_3d);
|
||||
TopoDS_Edge e2 = BRepBuilderAPI_MakeEdge(p2_3d, corner2);
|
||||
TopoDS_Edge e3 = BRepBuilderAPI_MakeEdge(corner2, p4_3d);
|
||||
TopoDS_Edge e4 = BRepBuilderAPI_MakeEdge(p4_3d, corner1);
|
||||
|
||||
BRepBuilderAPI_MakeWire wireMaker(e1, e2, e3, e4);
|
||||
if (wireMaker.IsDone()) {
|
||||
m_activeSketch->addShape(wireMaker.Shape());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,13 +160,6 @@ void ApplicationController::addCircle(const gp_Pnt& center, double radius)
|
||||
{
|
||||
if (m_activeSketch) {
|
||||
m_activeSketch->addObject(new SketchCircle(center, radius));
|
||||
|
||||
const auto& sketchPlane = m_activeSketch->plane();
|
||||
gp_Ax2 axis(center, sketchPlane.Direction());
|
||||
|
||||
gp_Circ circle(axis, radius);
|
||||
TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(circle);
|
||||
m_activeSketch->addShape(edge);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#ifndef APPLICATIONCONTROLLER_H
|
||||
#define APPLICATIONCONTROLLER_H
|
||||
|
||||
#include <QObject>
|
||||
#include "ViewportWidget.h" // For SketchPlane enum
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Ax2.hxx>
|
||||
|
||||
class Document;
|
||||
class MainWindow;
|
||||
@@ -47,12 +47,12 @@ public slots:
|
||||
bool saveDocumentAs();
|
||||
|
||||
void beginSketchCreation();
|
||||
void onPlaneSelected(const gp_Ax2& plane);
|
||||
void onPlaneSelected(ViewportWidget::SketchPlane plane);
|
||||
void endSketch();
|
||||
|
||||
signals:
|
||||
void planeSelectionModeStarted();
|
||||
void sketchModeStarted(const gp_Ax2& plane);
|
||||
void sketchModeStarted(ViewportWidget::SketchPlane plane);
|
||||
void sketchModeEnded();
|
||||
void currentFileChanged(const QString& path);
|
||||
void activeToolChanged(ToolType tool);
|
||||
|
||||
+21
-25
@@ -1,13 +1,12 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#include "Camera.h"
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include "ViewportWidget.h"
|
||||
#include <QApplication>
|
||||
#include <QWheelEvent>
|
||||
#include <QPropertyAnimation>
|
||||
@@ -203,28 +202,25 @@ void Camera::restoreState()
|
||||
setZoom(m_savedZoom);
|
||||
}
|
||||
|
||||
void Camera::animateToPlaneView(const gp_Ax2& plane)
|
||||
void Camera::animateToPlaneView(int plane)
|
||||
{
|
||||
const auto& normal = plane.Direction();
|
||||
QVector3D n(normal.X(), normal.Y(), normal.Z());
|
||||
QVector3D d;
|
||||
|
||||
// This logic preserves the quirky view directions of the original implementation.
|
||||
// For XZ-like planes (normal is mostly along Y), the view is aligned WITH the plane normal.
|
||||
// For other planes, it's aligned AGAINST the normal.
|
||||
if (qAbs(n.y()) > 0.99) {
|
||||
d = n;
|
||||
} else {
|
||||
d = -n;
|
||||
}
|
||||
|
||||
float targetXRot = qRadiansToDegrees(asin(-d.z())) * 16.0f;
|
||||
float targetYRot;
|
||||
|
||||
if (qAbs(d.z()) > 0.9999) { // Top/bottom-like view, Y rotation is arbitrary
|
||||
targetYRot = 0; // Set to 0 for stability
|
||||
} else {
|
||||
targetYRot = qRadiansToDegrees(atan2(d.x(), d.y())) * 16.0f;
|
||||
float targetXRot = xRotation();
|
||||
float targetYRot = yRotation();
|
||||
switch (static_cast<ViewportWidget::SketchPlane>(plane)) {
|
||||
case ViewportWidget::SketchPlane::XY: // Top view
|
||||
targetXRot = 90 * 16;
|
||||
targetYRot = 0;
|
||||
break;
|
||||
case ViewportWidget::SketchPlane::XZ: // Front view
|
||||
targetXRot = 0;
|
||||
targetYRot = 0;
|
||||
break;
|
||||
case ViewportWidget::SketchPlane::YZ: // Right view
|
||||
targetXRot = 0;
|
||||
targetYRot = -90 * 16;
|
||||
break;
|
||||
case ViewportWidget::SketchPlane::NONE:
|
||||
break;
|
||||
}
|
||||
|
||||
auto* animGroup = new QParallelAnimationGroup(this);
|
||||
|
||||
+3
-5
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#ifndef CAMERA_H
|
||||
#define CAMERA_H
|
||||
@@ -14,8 +14,6 @@
|
||||
#include <QMouseEvent>
|
||||
#include <QWheelEvent>
|
||||
|
||||
#include <gp_Ax2.hxx>
|
||||
|
||||
class Camera : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -48,7 +46,7 @@ public:
|
||||
void saveState();
|
||||
void restoreState();
|
||||
|
||||
void animateToPlaneView(const gp_Ax2& plane);
|
||||
void animateToPlaneView(int plane);
|
||||
void animateRestoreState();
|
||||
void animateToHomeView();
|
||||
|
||||
|
||||
+55
-49
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#include "CircleTool.h"
|
||||
#include "ViewportWidget.h"
|
||||
@@ -15,10 +15,6 @@
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <cmath>
|
||||
#include <QtMath>
|
||||
#include <optional>
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <ElCLib.hxx>
|
||||
|
||||
CircleTool::CircleTool(ViewportWidget* viewport)
|
||||
: SketchTool(viewport)
|
||||
@@ -39,18 +35,14 @@ void CircleTool::activate()
|
||||
|
||||
void CircleTool::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
auto currentPlaneOpt = m_viewport->currentPlane();
|
||||
if (!currentPlaneOpt) return;
|
||||
const auto& plane = currentPlaneOpt.value();
|
||||
|
||||
gp_Pnt p;
|
||||
if (!m_isDefining) {
|
||||
if (m_viewport->isSnappingOrigin()) {
|
||||
p = plane.Location();
|
||||
p.SetCoord(0, 0, 0);
|
||||
} else if (m_viewport->isSnappingVertex()) {
|
||||
p = m_viewport->snapVertex();
|
||||
} else {
|
||||
QVector3D worldPos = m_viewport->unproject(event->pos(), plane);
|
||||
QVector3D worldPos = m_viewport->unproject(event->pos(), m_viewport->currentPlane());
|
||||
p.SetCoord(worldPos.x(), worldPos.y(), worldPos.z());
|
||||
}
|
||||
m_centerPoint = p;
|
||||
@@ -78,22 +70,24 @@ void CircleTool::mousePressEvent(QMouseEvent *event)
|
||||
}
|
||||
|
||||
if (diameterFromInput) {
|
||||
QVector3D mousePos = m_viewport->unproject(event->pos(), plane);
|
||||
QVector3D mousePos = m_viewport->unproject(event->pos(), m_viewport->currentPlane());
|
||||
QVector3D mouseDir = mousePos - centerPos;
|
||||
if (mouseDir.lengthSquared() < 1e-9) {
|
||||
const auto& xDir = plane.XDirection();
|
||||
mouseDir = QVector3D(xDir.X(), xDir.Y(), xDir.Z());
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
mouseDir = QVector3D(1, 0, 0);
|
||||
} else { // YZ
|
||||
mouseDir = QVector3D(0, 1, 0);
|
||||
}
|
||||
}
|
||||
double radius = inputDiameter / 2.0;
|
||||
worldPos = centerPos + mouseDir.normalized() * radius;
|
||||
} else {
|
||||
if (m_viewport->isSnappingOrigin()) {
|
||||
const auto& origin = plane.Location();
|
||||
worldPos.setX(origin.X()); worldPos.setY(origin.Y()); worldPos.setZ(origin.Z());
|
||||
worldPos.setX(0); worldPos.setY(0); worldPos.setZ(0);
|
||||
} else if (m_viewport->isSnappingVertex()) {
|
||||
worldPos = QVector3D(m_viewport->snapVertex().X(), m_viewport->snapVertex().Y(), m_viewport->snapVertex().Z());
|
||||
} else {
|
||||
worldPos = m_viewport->unproject(event->pos(), plane);
|
||||
worldPos = m_viewport->unproject(event->pos(), m_viewport->currentPlane());
|
||||
}
|
||||
}
|
||||
p.SetCoord(worldPos.x(), worldPos.y(), worldPos.z());
|
||||
@@ -109,10 +103,6 @@ void CircleTool::mouseMoveEvent(QMouseEvent *event)
|
||||
|
||||
void CircleTool::finalizeCreation()
|
||||
{
|
||||
auto currentPlaneOpt = m_viewport->currentPlane();
|
||||
if (!currentPlaneOpt) return;
|
||||
const auto& plane = currentPlaneOpt.value();
|
||||
|
||||
QVector3D worldPos;
|
||||
QVector3D centerPos(m_centerPoint.X(), m_centerPoint.Y(), m_centerPoint.Z());
|
||||
|
||||
@@ -127,16 +117,19 @@ void CircleTool::finalizeCreation()
|
||||
}
|
||||
|
||||
if (diameterFromInput) {
|
||||
QVector3D mousePos = m_viewport->unproject(m_viewport->currentMousePos(), plane);
|
||||
QVector3D mousePos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane());
|
||||
QVector3D mouseDir = mousePos - centerPos;
|
||||
if (mouseDir.lengthSquared() < 1e-9) {
|
||||
const auto& xDir = plane.XDirection();
|
||||
mouseDir = QVector3D(xDir.X(), xDir.Y(), xDir.Z());
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
mouseDir = QVector3D(1, 0, 0);
|
||||
} else { // YZ
|
||||
mouseDir = QVector3D(0, 1, 0);
|
||||
}
|
||||
}
|
||||
double radius = inputDiameter / 2.0;
|
||||
worldPos = centerPos + mouseDir.normalized() * radius;
|
||||
} else {
|
||||
worldPos = m_viewport->unproject(m_viewport->currentMousePos(), plane);
|
||||
worldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane());
|
||||
}
|
||||
|
||||
gp_Pnt p;
|
||||
@@ -148,10 +141,7 @@ void CircleTool::finalizeCreation()
|
||||
|
||||
void CircleTool::paintGL()
|
||||
{
|
||||
auto currentPlaneOpt = m_viewport->currentPlane();
|
||||
if (!m_isDefining || !currentPlaneOpt) return;
|
||||
const auto& plane = currentPlaneOpt.value();
|
||||
|
||||
if (m_isDefining) {
|
||||
QVector<GLfloat> vertices;
|
||||
QVector3D worldPos;
|
||||
QVector3D centerPos(m_centerPoint.X(), m_centerPoint.Y(), m_centerPoint.Z());
|
||||
@@ -166,7 +156,7 @@ void CircleTool::paintGL()
|
||||
if (ok) diameterFromInput = true;
|
||||
}
|
||||
|
||||
QVector3D mousePos = m_viewport->unproject(m_viewport->currentMousePos(), plane);
|
||||
QVector3D mousePos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane());
|
||||
|
||||
double radius;
|
||||
if (diameterFromInput) {
|
||||
@@ -174,8 +164,7 @@ void CircleTool::paintGL()
|
||||
} else {
|
||||
worldPos = mousePos;
|
||||
if (m_viewport->isSnappingOrigin()) {
|
||||
const auto& origin = plane.Location();
|
||||
worldPos.setX(origin.X()); worldPos.setY(origin.Y()); worldPos.setZ(origin.Z());
|
||||
worldPos.setX(0); worldPos.setY(0); worldPos.setZ(0);
|
||||
} else if (m_viewport->isSnappingVertex()) {
|
||||
worldPos.setX(m_viewport->snapVertex().X()); worldPos.setY(m_viewport->snapVertex().Y()); worldPos.setZ(m_viewport->snapVertex().Z());
|
||||
}
|
||||
@@ -183,18 +172,34 @@ void CircleTool::paintGL()
|
||||
}
|
||||
|
||||
const int segments = 64;
|
||||
const auto& xDir = plane.XDirection();
|
||||
const auto& yDir = plane.YDirection();
|
||||
QVector3D u_axis(xDir.X(), xDir.Y(), xDir.Z());
|
||||
QVector3D v_axis(yDir.X(), yDir.Y(), yDir.Z());
|
||||
|
||||
for (int i = 0; i < segments; ++i) {
|
||||
double angle1 = i * 2.0 * M_PI / segments;
|
||||
double angle2 = (i + 1) * 2.0 * M_PI / segments;
|
||||
|
||||
QVector3D p1 = centerPos + radius * (qCos(angle1) * u_axis + qSin(angle1) * v_axis);
|
||||
QVector3D p2 = centerPos + radius * (qCos(angle2) * u_axis + qSin(angle2) * v_axis);
|
||||
QVector3D p1, p2;
|
||||
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||
p1.setX(centerPos.x() + radius * qCos(angle1));
|
||||
p1.setY(centerPos.y() + radius * qSin(angle1));
|
||||
p1.setZ(centerPos.z());
|
||||
p2.setX(centerPos.x() + radius * qCos(angle2));
|
||||
p2.setY(centerPos.y() + radius * qSin(angle2));
|
||||
p2.setZ(centerPos.z());
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
p1.setX(centerPos.x() + radius * qCos(angle1));
|
||||
p1.setY(centerPos.y());
|
||||
p1.setZ(centerPos.z() + radius * qSin(angle1));
|
||||
p2.setX(centerPos.x() + radius * qCos(angle2));
|
||||
p2.setY(centerPos.y());
|
||||
p2.setZ(centerPos.z() + radius * qSin(angle2));
|
||||
} else { // YZ
|
||||
p1.setX(centerPos.x());
|
||||
p1.setY(centerPos.y() + radius * qCos(angle1));
|
||||
p1.setZ(centerPos.z() + radius * qSin(angle1));
|
||||
p2.setX(centerPos.x());
|
||||
p2.setY(centerPos.y() + radius * qCos(angle2));
|
||||
p2.setZ(centerPos.z() + radius * qSin(angle2));
|
||||
}
|
||||
vertices << p1.x() << p1.y() << p1.z();
|
||||
vertices << p2.x() << p2.y() << p2.z();
|
||||
}
|
||||
@@ -203,14 +208,12 @@ void CircleTool::paintGL()
|
||||
m_viewport->vbo().bind();
|
||||
m_viewport->vbo().allocate(vertices.constData(), vertices.size() * sizeof(GLfloat));
|
||||
glDrawArrays(GL_LINES, 0, segments * 2);
|
||||
}
|
||||
}
|
||||
|
||||
void CircleTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMatrix4x4& projection)
|
||||
{
|
||||
auto currentPlaneOpt = m_viewport->currentPlane();
|
||||
if (!m_isDefining || !currentPlaneOpt) return;
|
||||
const auto& plane = currentPlaneOpt.value();
|
||||
|
||||
if (m_isDefining) {
|
||||
QVector3D worldPos;
|
||||
QVector3D centerPos(m_centerPoint.X(), m_centerPoint.Y(), m_centerPoint.Z());
|
||||
|
||||
@@ -224,7 +227,7 @@ void CircleTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const Q
|
||||
if (ok) diameterFromInput = true;
|
||||
}
|
||||
|
||||
QVector3D mousePos = m_viewport->unproject(m_viewport->currentMousePos(), plane);
|
||||
QVector3D mousePos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane());
|
||||
QVector3D edgePos;
|
||||
double diameter;
|
||||
|
||||
@@ -232,15 +235,17 @@ void CircleTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const Q
|
||||
diameter = inputDiameter;
|
||||
QVector3D mouseDir = mousePos - centerPos;
|
||||
if (mouseDir.lengthSquared() < 1e-9) {
|
||||
const auto& xDir = plane.XDirection();
|
||||
mouseDir = QVector3D(xDir.X(), xDir.Y(), xDir.Z());
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
mouseDir = QVector3D(1, 0, 0);
|
||||
} else { // YZ
|
||||
mouseDir = QVector3D(0, 1, 0);
|
||||
}
|
||||
}
|
||||
edgePos = centerPos + mouseDir.normalized() * (diameter / 2.0);
|
||||
} else {
|
||||
edgePos = mousePos;
|
||||
if (m_viewport->isSnappingOrigin()) {
|
||||
const auto& origin = plane.Location();
|
||||
edgePos.setX(origin.X()); edgePos.setY(origin.Y()); edgePos.setZ(origin.Z());
|
||||
edgePos.setX(0); edgePos.setY(0); edgePos.setZ(0);
|
||||
} else if (m_viewport->isSnappingVertex()) {
|
||||
edgePos.setX(m_viewport->snapVertex().X()); edgePos.setY(m_viewport->snapVertex().Y()); edgePos.setZ(m_viewport->snapVertex().Z());
|
||||
}
|
||||
@@ -265,4 +270,5 @@ void CircleTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const Q
|
||||
painter.setPen(Qt::white);
|
||||
painter.drawText(textRect, Qt::AlignCenter, diameterText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#ifndef CIRCLETOOL_H
|
||||
#define CIRCLETOOL_H
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#include "DebugWindow.h"
|
||||
#include "Camera.h"
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#ifndef DEBUGWINDOW_H
|
||||
#define DEBUGWINDOW_H
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#include "Document.h"
|
||||
#include "Feature.h"
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#ifndef DOCUMENT_H
|
||||
#define DOCUMENT_H
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#include "Feature.h"
|
||||
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#ifndef FEATURE_H
|
||||
#define FEATURE_H
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#include "FeatureBrowser.h"
|
||||
#include "Document.h"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#ifndef FEATUREBROWSER_H
|
||||
#define FEATUREBROWSER_H
|
||||
|
||||
+238
-243
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#include "LineTool.h"
|
||||
#include "ViewportWidget.h"
|
||||
@@ -13,13 +13,6 @@
|
||||
#include <QPainter>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QtMath>
|
||||
#include <optional>
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Dir2d.hxx>
|
||||
#include <gp_Vec2d.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <ElCLib.hxx>
|
||||
|
||||
LineTool::LineTool(ViewportWidget* viewport)
|
||||
: SketchTool(viewport)
|
||||
@@ -41,10 +34,6 @@ void LineTool::activate()
|
||||
|
||||
void LineTool::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
auto currentPlaneOpt = m_viewport->currentPlane();
|
||||
if (!currentPlaneOpt) return;
|
||||
const auto& plane = currentPlaneOpt.value();
|
||||
|
||||
gp_Pnt p;
|
||||
QString dimInput = m_viewport->property("dimensionInput").toString();
|
||||
QString angleInput = m_viewport->property("angleInput").toString();
|
||||
@@ -75,23 +64,19 @@ void LineTool::mousePressEvent(QMouseEvent *event)
|
||||
if (m_viewport->property("isChainedLine").toBool()) {
|
||||
refDir = m_viewport->property("previousLineDirection").value<QVector3D>();
|
||||
} else {
|
||||
const auto& xDir = plane.XDirection();
|
||||
refDir = QVector3D(xDir.X(), xDir.Y(), xDir.Z());
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) refDir = QVector3D(1, 0, 0);
|
||||
else refDir = QVector3D(0, 1, 0);
|
||||
}
|
||||
QVector3D currentMouseWorldPos = m_viewport->unproject(event->pos(), plane);
|
||||
QVector3D currentMouseWorldPos = m_viewport->unproject(event->pos(), m_viewport->currentPlane());
|
||||
QVector3D mouseVec = currentMouseWorldPos - startPos;
|
||||
|
||||
gp_Pnt startPnt(startPos.x(), startPos.y(), startPos.z());
|
||||
gp_Pnt mousePnt(currentMouseWorldPos.x(), currentMouseWorldPos.y(), currentMouseWorldPos.z());
|
||||
gp_Dir refDirGp(refDir.x(), refDir.y(), refDir.z());
|
||||
|
||||
gp_Pnt2d startPnt2d(gp_Vec(plane.Location(), startPnt).Dot(plane.XDirection()), gp_Vec(plane.Location(), startPnt).Dot(plane.YDirection()));
|
||||
gp_Pnt2d mousePnt2d(gp_Vec(plane.Location(), mousePnt).Dot(plane.XDirection()), gp_Vec(plane.Location(), mousePnt).Dot(plane.YDirection()));
|
||||
gp_Dir2d refDir2d(refDirGp.Dot(plane.XDirection()), refDirGp.Dot(plane.YDirection()));
|
||||
|
||||
gp_Vec2d mouseVec2d(startPnt2d, mousePnt2d);
|
||||
double mouseAngle = qRadiansToDegrees(atan2(mouseVec2d.Y(), mouseVec2d.X()));
|
||||
double refAngle = qRadiansToDegrees(atan2(refDir2d.Y(), refDir2d.X()));
|
||||
double mouseAngle;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) mouseAngle = qRadiansToDegrees(atan2(mouseVec.y(), mouseVec.x()));
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.x()));
|
||||
else mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.y()));
|
||||
double refAngle;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) refAngle = qRadiansToDegrees(atan2(refDir.y(), refDir.x()));
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) refAngle = qRadiansToDegrees(atan2(refDir.z(), refDir.x()));
|
||||
else refAngle = qRadiansToDegrees(atan2(refDir.z(), refDir.y()));
|
||||
double relativeMouseAngle = mouseAngle - refAngle;
|
||||
while (relativeMouseAngle <= -180.0) relativeMouseAngle += 360.0;
|
||||
while (relativeMouseAngle > 180.0) relativeMouseAngle -= 360.0;
|
||||
@@ -106,9 +91,10 @@ void LineTool::mousePressEvent(QMouseEvent *event)
|
||||
snappedAngle = -inputAngleDegrees;
|
||||
}
|
||||
double finalAngleRad = qDegreesToRadians(refAngle + snappedAngle);
|
||||
gp_Dir2d finalDir2d(cos(finalAngleRad), sin(finalAngleRad));
|
||||
gp_Dir finalDir3d = ElCLib::To3d(plane, finalDir2d);
|
||||
QVector3D finalDir(finalDir3d.X(), finalDir3d.Y(), finalDir3d.Z());
|
||||
QVector3D finalDir;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) finalDir = QVector3D(cos(finalAngleRad), sin(finalAngleRad), 0);
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) finalDir = QVector3D(cos(finalAngleRad), 0, sin(finalAngleRad));
|
||||
else finalDir = QVector3D(0, cos(finalAngleRad), sin(finalAngleRad));
|
||||
double lineLength;
|
||||
if (lengthFromInput) lineLength = inputLength;
|
||||
else {
|
||||
@@ -117,37 +103,34 @@ void LineTool::mousePressEvent(QMouseEvent *event)
|
||||
}
|
||||
worldPos = startPos + lineLength * finalDir;
|
||||
} else if (lengthFromInput) {
|
||||
QVector3D currentMouseWorldPos = m_viewport->unproject(event->pos(), plane);
|
||||
QVector3D currentMouseWorldPos = m_viewport->unproject(event->pos(), m_viewport->currentPlane());
|
||||
QVector3D dir = (currentMouseWorldPos - startPos);
|
||||
if (dir.length() > 1e-6) {
|
||||
dir.normalize();
|
||||
worldPos = startPos + inputLength * dir;
|
||||
} else {
|
||||
const auto& xDir = plane.XDirection();
|
||||
worldPos = startPos + inputLength * QVector3D(xDir.X(), xDir.Y(), xDir.Z());
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) worldPos = startPos + QVector3D(inputLength, 0, 0);
|
||||
else worldPos = startPos + QVector3D(0, inputLength, 0);
|
||||
}
|
||||
}
|
||||
p.SetCoord(worldPos.x(), worldPos.y(), worldPos.z());
|
||||
} else {
|
||||
if (m_viewport->isSnappingOrigin()) {
|
||||
p = plane.Location();
|
||||
p.SetCoord(0, 0, 0);
|
||||
} else if (m_viewport->isSnappingVertex()) {
|
||||
p = m_viewport->snapVertex();
|
||||
} else {
|
||||
QVector3D worldPosQ = m_viewport->unproject(event->pos(), plane);
|
||||
gp_Pnt worldPos(worldPosQ.x(), worldPosQ.y(), worldPosQ.z());
|
||||
|
||||
if (m_viewport->isSnappingHorizontal() || m_viewport->isSnappingVertical()) {
|
||||
gp_Pnt2d worldPos2d(gp_Vec(plane.Location(), worldPos).Dot(plane.XDirection()), gp_Vec(plane.Location(), worldPos).Dot(plane.YDirection()));
|
||||
gp_Pnt2d firstPoint2d(gp_Vec(plane.Location(), m_firstLinePoint).Dot(plane.XDirection()), gp_Vec(plane.Location(), m_firstLinePoint).Dot(plane.YDirection()));
|
||||
QVector3D worldPos = m_viewport->unproject(event->pos(), m_viewport->currentPlane());
|
||||
if (m_viewport->isSnappingHorizontal()) {
|
||||
worldPos2d.SetY(firstPoint2d.Y());
|
||||
} else { // vertical
|
||||
worldPos2d.SetX(firstPoint2d.X());
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) worldPos.setY(m_firstLinePoint.Y());
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) worldPos.setZ(m_firstLinePoint.Z());
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) worldPos.setZ(m_firstLinePoint.Z());
|
||||
} else if (m_viewport->isSnappingVertical()) {
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) worldPos.setX(m_firstLinePoint.X());
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) worldPos.setX(m_firstLinePoint.X());
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) worldPos.setY(m_firstLinePoint.Y());
|
||||
}
|
||||
worldPos = ElCLib::To3d(plane, worldPos2d);
|
||||
}
|
||||
p = worldPos;
|
||||
p.SetCoord(worldPos.x(), worldPos.y(), worldPos.z());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,27 +157,27 @@ void LineTool::mousePressEvent(QMouseEvent *event)
|
||||
|
||||
void LineTool::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
auto currentPlaneOpt = m_viewport->currentPlane();
|
||||
if (!m_isDefining || !currentPlaneOpt) return;
|
||||
const auto& plane = currentPlaneOpt.value();
|
||||
|
||||
bool oldIsSnappingHorizontal = m_viewport->isSnappingHorizontal();
|
||||
bool oldIsSnappingVertical = m_viewport->isSnappingVertical();
|
||||
m_viewport->setSnappingHorizontal(false);
|
||||
m_viewport->setSnappingVertical(false);
|
||||
|
||||
if (m_isDefining && !m_viewport->isSnappingOrigin() && !m_viewport->isSnappingVertex()) {
|
||||
QVector3D worldPosQ = m_viewport->unproject(m_viewport->currentMousePos(), plane);
|
||||
gp_Pnt worldPos(worldPosQ.x(), worldPosQ.y(), worldPosQ.z());
|
||||
gp_Pnt startPos = m_firstLinePoint;
|
||||
QVector3D worldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane());
|
||||
QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z());
|
||||
QVector3D delta = worldPos - startPos;
|
||||
|
||||
gp_Pnt2d worldPos2d(gp_Vec(plane.Location(), worldPos).Dot(plane.XDirection()), gp_Vec(plane.Location(), worldPos).Dot(plane.YDirection()));
|
||||
gp_Pnt2d startPos2d(gp_Vec(plane.Location(), startPos).Dot(plane.XDirection()), gp_Vec(plane.Location(), startPos).Dot(plane.YDirection()));
|
||||
gp_Vec2d delta(startPos2d, worldPos2d);
|
||||
|
||||
if (delta.Magnitude() > 1e-6) {
|
||||
if (delta.length() > 1e-6) {
|
||||
const double snapAngleThreshold = qDegreesToRadians(2.0);
|
||||
double angle = atan2(delta.Y(), delta.X());
|
||||
double angle = 0;
|
||||
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||
angle = atan2(delta.y(), delta.x());
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
angle = atan2(delta.z(), delta.x());
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) {
|
||||
angle = atan2(delta.z(), delta.y());
|
||||
}
|
||||
|
||||
if (qAbs(sin(angle)) < sin(snapAngleThreshold)) {
|
||||
m_viewport->setSnappingHorizontal(true);
|
||||
@@ -211,10 +194,6 @@ void LineTool::mouseMoveEvent(QMouseEvent *event)
|
||||
|
||||
void LineTool::finalizeCreation()
|
||||
{
|
||||
auto currentPlaneOpt = m_viewport->currentPlane();
|
||||
if (!currentPlaneOpt) return;
|
||||
const auto& plane = currentPlaneOpt.value();
|
||||
|
||||
QVector3D worldPos;
|
||||
QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z());
|
||||
// This is duplicated from paintGL to ensure consistent line creation
|
||||
@@ -241,23 +220,19 @@ void LineTool::finalizeCreation()
|
||||
if (m_viewport->property("isChainedLine").toBool()) {
|
||||
refDir = m_viewport->property("previousLineDirection").value<QVector3D>();
|
||||
} else {
|
||||
const auto& xDir = plane.XDirection();
|
||||
refDir = QVector3D(xDir.X(), xDir.Y(), xDir.Z());
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) refDir = QVector3D(1, 0, 0);
|
||||
else refDir = QVector3D(0, 1, 0);
|
||||
}
|
||||
QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), plane);
|
||||
QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane());
|
||||
QVector3D mouseVec = currentMouseWorldPos - startPos;
|
||||
|
||||
gp_Pnt startPnt(startPos.x(), startPos.y(), startPos.z());
|
||||
gp_Pnt mousePnt(currentMouseWorldPos.x(), currentMouseWorldPos.y(), currentMouseWorldPos.z());
|
||||
gp_Dir refDirGp(refDir.x(), refDir.y(), refDir.z());
|
||||
|
||||
gp_Pnt2d startPnt2d(gp_Vec(plane.Location(), startPnt).Dot(plane.XDirection()), gp_Vec(plane.Location(), startPnt).Dot(plane.YDirection()));
|
||||
gp_Pnt2d mousePnt2d(gp_Vec(plane.Location(), mousePnt).Dot(plane.XDirection()), gp_Vec(plane.Location(), mousePnt).Dot(plane.YDirection()));
|
||||
gp_Dir2d refDir2d(refDirGp.Dot(plane.XDirection()), refDirGp.Dot(plane.YDirection()));
|
||||
|
||||
gp_Vec2d mouseVec2d(startPnt2d, mousePnt2d);
|
||||
double mouseAngle = qRadiansToDegrees(atan2(mouseVec2d.Y(), mouseVec2d.X()));
|
||||
double refAngle = qRadiansToDegrees(atan2(refDir2d.Y(), refDir2d.X()));
|
||||
double mouseAngle;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) mouseAngle = qRadiansToDegrees(atan2(mouseVec.y(), mouseVec.x()));
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.x()));
|
||||
else mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.y()));
|
||||
double refAngle;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) refAngle = qRadiansToDegrees(atan2(refDir.y(), refDir.x()));
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) refAngle = qRadiansToDegrees(atan2(refDir.z(), refDir.x()));
|
||||
else refAngle = qRadiansToDegrees(atan2(refDir.z(), refDir.y()));
|
||||
double relativeMouseAngle = mouseAngle - refAngle;
|
||||
while (relativeMouseAngle <= -180.0) relativeMouseAngle += 360.0;
|
||||
while (relativeMouseAngle > 180.0) relativeMouseAngle -= 360.0;
|
||||
@@ -272,9 +247,10 @@ void LineTool::finalizeCreation()
|
||||
snappedAngle = -inputAngleDegrees;
|
||||
}
|
||||
double finalAngleRad = qDegreesToRadians(refAngle + snappedAngle);
|
||||
gp_Dir2d finalDir2d(cos(finalAngleRad), sin(finalAngleRad));
|
||||
gp_Dir finalDir3d = ElCLib::To3d(plane, finalDir2d);
|
||||
QVector3D finalDir(finalDir3d.X(), finalDir3d.Y(), finalDir3d.Z());
|
||||
QVector3D finalDir;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) finalDir = QVector3D(cos(finalAngleRad), sin(finalAngleRad), 0);
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) finalDir = QVector3D(cos(finalAngleRad), 0, sin(finalAngleRad));
|
||||
else finalDir = QVector3D(0, cos(finalAngleRad), sin(finalAngleRad));
|
||||
double lineLength;
|
||||
if (lengthFromInput) lineLength = inputLength;
|
||||
else {
|
||||
@@ -283,17 +259,17 @@ void LineTool::finalizeCreation()
|
||||
}
|
||||
worldPos = startPos + lineLength * finalDir;
|
||||
} else if (lengthFromInput) {
|
||||
QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), plane);
|
||||
QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane());
|
||||
QVector3D dir = (currentMouseWorldPos - startPos);
|
||||
if (dir.length() > 1e-6) {
|
||||
dir.normalize();
|
||||
worldPos = startPos + inputLength * dir;
|
||||
} else {
|
||||
const auto& xDir = plane.XDirection();
|
||||
worldPos = startPos + inputLength * QVector3D(xDir.X(), xDir.Y(), xDir.Z());
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) worldPos = startPos + QVector3D(inputLength, 0, 0);
|
||||
else worldPos = startPos + QVector3D(0, inputLength, 0);
|
||||
}
|
||||
} else {
|
||||
worldPos = m_viewport->unproject(m_viewport->currentMousePos(), plane);
|
||||
worldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane());
|
||||
}
|
||||
|
||||
gp_Pnt p;
|
||||
@@ -313,10 +289,6 @@ void LineTool::finalizeCreation()
|
||||
void LineTool::paintGL()
|
||||
{
|
||||
if (m_isDefining) {
|
||||
auto currentPlaneOpt = m_viewport->currentPlane();
|
||||
if (!currentPlaneOpt) return;
|
||||
const auto& plane = currentPlaneOpt.value();
|
||||
|
||||
QVector<GLfloat> vertices;
|
||||
QVector3D worldPos;
|
||||
QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z());
|
||||
@@ -344,24 +316,26 @@ void LineTool::paintGL()
|
||||
if (m_viewport->property("isChainedLine").toBool()) {
|
||||
refDir = m_viewport->property("previousLineDirection").value<QVector3D>();
|
||||
} else {
|
||||
const auto& xDir = plane.XDirection();
|
||||
refDir = QVector3D(xDir.X(), xDir.Y(), xDir.Z());
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
refDir = QVector3D(1, 0, 0);
|
||||
} else { // YZ
|
||||
refDir = QVector3D(0, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), plane);
|
||||
QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane());
|
||||
QVector3D mouseVec = currentMouseWorldPos - startPos;
|
||||
|
||||
gp_Pnt startPnt(startPos.x(), startPos.y(), startPos.z());
|
||||
gp_Pnt mousePnt(currentMouseWorldPos.x(), currentMouseWorldPos.y(), currentMouseWorldPos.z());
|
||||
gp_Dir refDirGp(refDir.x(), refDir.y(), refDir.z());
|
||||
// Quadrant snapping
|
||||
double mouseAngle;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) mouseAngle = qRadiansToDegrees(atan2(mouseVec.y(), mouseVec.x()));
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.x()));
|
||||
else mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.y()));
|
||||
|
||||
gp_Pnt2d startPnt2d(gp_Vec(plane.Location(), startPnt).Dot(plane.XDirection()), gp_Vec(plane.Location(), startPnt).Dot(plane.YDirection()));
|
||||
gp_Pnt2d mousePnt2d(gp_Vec(plane.Location(), mousePnt).Dot(plane.XDirection()), gp_Vec(plane.Location(), mousePnt).Dot(plane.YDirection()));
|
||||
gp_Dir2d refDir2d(refDirGp.Dot(plane.XDirection()), refDirGp.Dot(plane.YDirection()));
|
||||
|
||||
gp_Vec2d mouseVec2d(startPnt2d, mousePnt2d);
|
||||
double mouseAngle = qRadiansToDegrees(atan2(mouseVec2d.Y(), mouseVec2d.X()));
|
||||
double refAngle = qRadiansToDegrees(atan2(refDir2d.Y(), refDir2d.X()));
|
||||
double refAngle;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) refAngle = qRadiansToDegrees(atan2(refDir.y(), refDir.x()));
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) refAngle = qRadiansToDegrees(atan2(refDir.z(), refDir.x()));
|
||||
else refAngle = qRadiansToDegrees(atan2(refDir.z(), refDir.y()));
|
||||
|
||||
double relativeMouseAngle = mouseAngle - refAngle;
|
||||
while (relativeMouseAngle <= -180.0) relativeMouseAngle += 360.0;
|
||||
@@ -379,9 +353,10 @@ void LineTool::paintGL()
|
||||
}
|
||||
|
||||
double finalAngleRad = qDegreesToRadians(refAngle + snappedAngle);
|
||||
gp_Dir2d finalDir2d(cos(finalAngleRad), sin(finalAngleRad));
|
||||
gp_Dir finalDir3d = ElCLib::To3d(plane, finalDir2d);
|
||||
QVector3D finalDir(finalDir3d.X(), finalDir3d.Y(), finalDir3d.Z());
|
||||
QVector3D finalDir;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) finalDir = QVector3D(cos(finalAngleRad), sin(finalAngleRad), 0);
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) finalDir = QVector3D(cos(finalAngleRad), 0, sin(finalAngleRad));
|
||||
else finalDir = QVector3D(0, cos(finalAngleRad), sin(finalAngleRad));
|
||||
|
||||
double lineLength;
|
||||
if (lengthFromInput) {
|
||||
@@ -393,34 +368,33 @@ void LineTool::paintGL()
|
||||
worldPos = startPos + lineLength * finalDir;
|
||||
|
||||
} else if (lengthFromInput) {
|
||||
QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), plane);
|
||||
QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane());
|
||||
QVector3D dir = (currentMouseWorldPos - startPos);
|
||||
if (dir.length() > 1e-6) {
|
||||
dir.normalize();
|
||||
worldPos = startPos + inputLength * dir;
|
||||
} else {
|
||||
const auto& xDir = plane.XDirection();
|
||||
worldPos = startPos + inputLength * QVector3D(xDir.X(), xDir.Y(), xDir.Z());
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
worldPos = startPos + QVector3D(inputLength, 0, 0);
|
||||
} else {
|
||||
worldPos = startPos + QVector3D(0, inputLength, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
worldPos = m_viewport->unproject(m_viewport->currentMousePos(), plane);
|
||||
gp_Pnt worldPosPnt(worldPos.x(), worldPos.y(), worldPos.z());
|
||||
|
||||
worldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane());
|
||||
if (m_viewport->isSnappingOrigin()) {
|
||||
worldPosPnt = plane.Location();
|
||||
worldPos.setX(0); worldPos.setY(0); worldPos.setZ(0);
|
||||
} else if (m_viewport->isSnappingVertex()) {
|
||||
worldPosPnt = m_viewport->snapVertex();
|
||||
} else if (m_viewport->isSnappingHorizontal() || m_viewport->isSnappingVertical()) {
|
||||
gp_Pnt2d worldPos2d(gp_Vec(plane.Location(), worldPosPnt).Dot(plane.XDirection()), gp_Vec(plane.Location(), worldPosPnt).Dot(plane.YDirection()));
|
||||
gp_Pnt2d firstPoint2d(gp_Vec(plane.Location(), m_firstLinePoint).Dot(plane.XDirection()), gp_Vec(plane.Location(), m_firstLinePoint).Dot(plane.YDirection()));
|
||||
if (m_viewport->isSnappingHorizontal()) {
|
||||
worldPos2d.SetY(firstPoint2d.Y());
|
||||
} else { // vertical
|
||||
worldPos2d.SetX(firstPoint2d.X());
|
||||
worldPos.setX(m_viewport->snapVertex().X()); worldPos.setY(m_viewport->snapVertex().Y()); worldPos.setZ(m_viewport->snapVertex().Z());
|
||||
} else if (m_viewport->isSnappingHorizontal()) {
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) worldPos.setY(m_firstLinePoint.Y());
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) worldPos.setZ(m_firstLinePoint.Z());
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) worldPos.setZ(m_firstLinePoint.Z());
|
||||
} else if (m_viewport->isSnappingVertical()) {
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) worldPos.setX(m_firstLinePoint.X());
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) worldPos.setX(m_firstLinePoint.X());
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) worldPos.setY(m_firstLinePoint.Y());
|
||||
}
|
||||
worldPosPnt = ElCLib::To3d(plane, worldPos2d);
|
||||
}
|
||||
worldPos.setX(worldPosPnt.X()); worldPos.setY(worldPosPnt.Y()); worldPos.setZ(worldPosPnt.Z());
|
||||
}
|
||||
|
||||
vertices << m_firstLinePoint.X() << m_firstLinePoint.Y() << m_firstLinePoint.Z();
|
||||
@@ -442,25 +416,23 @@ void LineTool::paintGL()
|
||||
if (m_viewport->property("isChainedLine").toBool()) {
|
||||
refDir = m_viewport->property("previousLineDirection").value<QVector3D>();
|
||||
} else {
|
||||
const auto& xDir = plane.XDirection();
|
||||
refDir = QVector3D(xDir.X(), xDir.Y(), xDir.Z());
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) refDir = QVector3D(1, 0, 0);
|
||||
else refDir = QVector3D(0, 1, 0);
|
||||
}
|
||||
|
||||
if (angleFromInput) {
|
||||
QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), plane);
|
||||
QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane());
|
||||
QVector3D mouseVec = currentMouseWorldPos - startPos;
|
||||
|
||||
gp_Pnt startPnt(startPos.x(), startPos.y(), startPos.z());
|
||||
gp_Pnt mousePnt(currentMouseWorldPos.x(), currentMouseWorldPos.y(), currentMouseWorldPos.z());
|
||||
gp_Dir refDirGp(refDir.x(), refDir.y(), refDir.z());
|
||||
double mouseAngle;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) mouseAngle = qRadiansToDegrees(atan2(mouseVec.y(), mouseVec.x()));
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.x()));
|
||||
else mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.y()));
|
||||
|
||||
gp_Pnt2d startPnt2d(gp_Vec(plane.Location(), startPnt).Dot(plane.XDirection()), gp_Vec(plane.Location(), startPnt).Dot(plane.YDirection()));
|
||||
gp_Pnt2d mousePnt2d(gp_Vec(plane.Location(), mousePnt).Dot(plane.XDirection()), gp_Vec(plane.Location(), mousePnt).Dot(plane.YDirection()));
|
||||
gp_Dir2d refDir2d(refDirGp.Dot(plane.XDirection()), refDirGp.Dot(plane.YDirection()));
|
||||
|
||||
gp_Vec2d mouseVec2d(startPnt2d, mousePnt2d);
|
||||
double mouseAngle = qRadiansToDegrees(atan2(mouseVec2d.Y(), mouseVec2d.X()));
|
||||
double refAngleForQuadrant = qRadiansToDegrees(atan2(refDir2d.Y(), refDir2d.X()));
|
||||
double refAngleForQuadrant;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) refAngleForQuadrant = qRadiansToDegrees(atan2(refDir.y(), refDir.x()));
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) refAngleForQuadrant = qRadiansToDegrees(atan2(refDir.z(), refDir.x()));
|
||||
else refAngleForQuadrant = qRadiansToDegrees(atan2(refDir.z(), refDir.y()));
|
||||
|
||||
double relativeMouseAngle = mouseAngle - refAngleForQuadrant;
|
||||
while (relativeMouseAngle <= -180.0) relativeMouseAngle += 360.0;
|
||||
@@ -475,14 +447,16 @@ void LineTool::paintGL()
|
||||
}
|
||||
}
|
||||
|
||||
gp_Dir refDirGp(refDir.x(), refDir.y(), refDir.z());
|
||||
gp_Dir lineDirGp(lineVec.x(), lineVec.y(), lineVec.z());
|
||||
|
||||
gp_Dir2d refDir2d(refDirGp.Dot(plane.XDirection()), refDirGp.Dot(plane.YDirection()));
|
||||
gp_Dir2d lineDir2d(lineDirGp.Dot(plane.XDirection()), lineDirGp.Dot(plane.YDirection()));
|
||||
|
||||
refAngle = atan2(refDir2d.Y(), refDir2d.X());
|
||||
lineAngle = atan2(lineDir2d.Y(), lineDir2d.X());
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||
refAngle = atan2(refDir.y(), refDir.x());
|
||||
lineAngle = atan2(lineVec.y(), lineVec.x());
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
refAngle = atan2(refDir.z(), refDir.x());
|
||||
lineAngle = atan2(lineVec.z(), lineVec.x());
|
||||
} else { // YZ
|
||||
refAngle = atan2(refDir.z(), refDir.y());
|
||||
lineAngle = atan2(lineVec.z(), lineVec.y());
|
||||
}
|
||||
|
||||
angleDiff = lineAngle - refAngle;
|
||||
while (angleDiff <= -M_PI) angleDiff += 2 * M_PI;
|
||||
@@ -492,11 +466,14 @@ void LineTool::paintGL()
|
||||
|
||||
vertices.clear();
|
||||
|
||||
gp_Dir lineDirGp(lineVec.x(), lineVec.y(), lineVec.z());
|
||||
gp_Dir2d lineDir2d(lineDirGp.Dot(plane.XDirection()), lineDirGp.Dot(plane.YDirection()));
|
||||
gp_Dir2d perpDir2d(-lineDir2d.Y(), lineDir2d.X());
|
||||
gp_Dir perpDir3d = ElCLib::To3d(plane, perpDir2d);
|
||||
QVector3D perpVec(perpDir3d.X(), perpDir3d.Y(), perpDir3d.Z());
|
||||
QVector3D perpVec;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||
perpVec = QVector3D(-lineVec.y(), lineVec.x(), 0).normalized();
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
perpVec = QVector3D(-lineVec.z(), 0, lineVec.x()).normalized();
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) {
|
||||
perpVec = QVector3D(0, -lineVec.z(), lineVec.y()).normalized();
|
||||
}
|
||||
|
||||
if (angleDiff < 0) {
|
||||
perpVec = -perpVec;
|
||||
@@ -543,11 +520,9 @@ void LineTool::paintGL()
|
||||
for (int i = 0; i <= numSegments; ++i) {
|
||||
double angle = refAngle + (lineAngle - refAngle) * i / numSegments;
|
||||
QVector3D p;
|
||||
const auto& xDir = plane.XDirection();
|
||||
const auto& yDir = plane.YDirection();
|
||||
QVector3D u_axis(xDir.X(), xDir.Y(), xDir.Z());
|
||||
QVector3D v_axis(yDir.X(), yDir.Y(), yDir.Z());
|
||||
p = startPos + radius * (cos(angle) * u_axis + sin(angle) * v_axis);
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) p = startPos + radius * QVector3D(cos(angle), sin(angle), 0);
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) p = startPos + radius * QVector3D(cos(angle), 0, sin(angle));
|
||||
else p = startPos + radius * QVector3D(0, cos(angle), sin(angle));
|
||||
vertices << p.x() << p.y() << p.z();
|
||||
}
|
||||
glLineWidth(1.0f);
|
||||
@@ -565,13 +540,17 @@ void LineTool::paintGL()
|
||||
// End arrowhead
|
||||
QVector3D endPoint(vertices[vertices.size()-3], vertices[vertices.size()-2], vertices[vertices.size()-1]);
|
||||
double endAngle = lineAngle;
|
||||
const auto& xDir = plane.XDirection();
|
||||
const auto& yDir = plane.YDirection();
|
||||
QVector3D u_axis(xDir.X(), xDir.Y(), xDir.Z());
|
||||
QVector3D v_axis(yDir.X(), yDir.Y(), yDir.Z());
|
||||
QVector3D radialDir_end, tangentDir_end;
|
||||
radialDir_end = cos(endAngle) * u_axis + sin(endAngle) * v_axis;
|
||||
tangentDir_end = -sin(endAngle) * u_axis + cos(endAngle) * v_axis;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||
radialDir_end = QVector3D(cos(endAngle), sin(endAngle), 0);
|
||||
tangentDir_end = QVector3D(-sin(endAngle), cos(endAngle), 0);
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
radialDir_end = QVector3D(cos(endAngle), 0, sin(endAngle));
|
||||
tangentDir_end = QVector3D(-sin(endAngle), 0, cos(endAngle));
|
||||
} else {
|
||||
radialDir_end = QVector3D(0, cos(endAngle), sin(endAngle));
|
||||
tangentDir_end = QVector3D(0, -sin(endAngle), cos(endAngle));
|
||||
}
|
||||
QVector3D arc_arrow_base_end = endPoint - sign * arcArrowLength * tangentDir_end;
|
||||
QVector3D arc_arrowP1_end = arc_arrow_base_end + arcArrowWidth * radialDir_end;
|
||||
QVector3D arc_arrowP2_end = arc_arrow_base_end - arcArrowWidth * radialDir_end;
|
||||
@@ -582,8 +561,16 @@ void LineTool::paintGL()
|
||||
QVector3D startPoint(vertices[0], vertices[1], vertices[2]);
|
||||
double startAngle = refAngle;
|
||||
QVector3D radialDir_start, tangentDir_start;
|
||||
radialDir_start = cos(startAngle) * u_axis + sin(startAngle) * v_axis;
|
||||
tangentDir_start = -sin(startAngle) * u_axis + cos(startAngle) * v_axis;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||
radialDir_start = QVector3D(cos(startAngle), sin(startAngle), 0);
|
||||
tangentDir_start = QVector3D(-sin(startAngle), cos(startAngle), 0);
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
radialDir_start = QVector3D(cos(startAngle), 0, sin(startAngle));
|
||||
tangentDir_start = QVector3D(-sin(startAngle), 0, cos(startAngle));
|
||||
} else {
|
||||
radialDir_start = QVector3D(0, cos(startAngle), sin(startAngle));
|
||||
tangentDir_start = QVector3D(0, -sin(startAngle), cos(startAngle));
|
||||
}
|
||||
QVector3D arc_arrow_base_start = startPoint + sign * arcArrowLength * tangentDir_start;
|
||||
QVector3D arc_arrowP1_start = arc_arrow_base_start + arcArrowWidth * radialDir_start;
|
||||
QVector3D arc_arrowP2_start = arc_arrow_base_start - arcArrowWidth * radialDir_start;
|
||||
@@ -602,21 +589,29 @@ void LineTool::paintGL()
|
||||
QVector3D midPoint = (startPos + worldPos) / 2.0;
|
||||
const float indicatorSize = 0.02f * -m_viewport->camera()->zoom();
|
||||
const float indicatorOffset = 0.02f * -m_viewport->camera()->zoom();
|
||||
const auto& xDir = plane.XDirection();
|
||||
const auto& yDir = plane.YDirection();
|
||||
QVector3D u_axis(xDir.X(), xDir.Y(), xDir.Z());
|
||||
QVector3D v_axis(yDir.X(), yDir.Y(), yDir.Z());
|
||||
|
||||
QVector3D p1, p2;
|
||||
if (m_viewport->isSnappingHorizontal()) {
|
||||
p1 = midPoint - indicatorSize * v_axis + indicatorOffset * u_axis;
|
||||
p2 = midPoint + indicatorSize * v_axis + indicatorOffset * u_axis;
|
||||
} else { // m_isSnappingVertical
|
||||
p1 = midPoint - indicatorSize * u_axis + indicatorOffset * v_axis;
|
||||
p2 = midPoint + indicatorSize * u_axis + indicatorOffset * v_axis;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||
vertices << midPoint.x() - indicatorSize << midPoint.y() + indicatorOffset << midPoint.z();
|
||||
vertices << midPoint.x() + indicatorSize << midPoint.y() + indicatorOffset << midPoint.z();
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
vertices << midPoint.x() - indicatorSize << midPoint.y() << midPoint.z() + indicatorOffset;
|
||||
vertices << midPoint.x() + indicatorSize << midPoint.y() << midPoint.z() + indicatorOffset;
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) {
|
||||
vertices << midPoint.x() << midPoint.y() - indicatorSize << midPoint.z() + indicatorOffset;
|
||||
vertices << midPoint.x() << midPoint.y() + indicatorSize << midPoint.z() + indicatorOffset;
|
||||
}
|
||||
} else { // m_isSnappingVertical
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||
vertices << midPoint.x() + indicatorOffset << midPoint.y() - indicatorSize << midPoint.z();
|
||||
vertices << midPoint.x() + indicatorOffset << midPoint.y() + indicatorSize << midPoint.z();
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
vertices << midPoint.x() + indicatorOffset << midPoint.y() << midPoint.z() - indicatorSize;
|
||||
vertices << midPoint.x() + indicatorOffset << midPoint.y() << midPoint.z() + indicatorSize;
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) {
|
||||
vertices << midPoint.x() << midPoint.y() + indicatorOffset << midPoint.z() - indicatorSize;
|
||||
vertices << midPoint.x() << midPoint.y() + indicatorOffset << midPoint.z() + indicatorSize;
|
||||
}
|
||||
}
|
||||
vertices << p1.x() << p1.y() << p1.z();
|
||||
vertices << p2.x() << p2.y() << p2.z();
|
||||
m_viewport->vbo().bind();
|
||||
m_viewport->vbo().allocate(vertices.constData(), vertices.size() * sizeof(GLfloat));
|
||||
glDrawArrays(GL_LINES, 0, 2);
|
||||
@@ -627,10 +622,6 @@ void LineTool::paintGL()
|
||||
void LineTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMatrix4x4& projection)
|
||||
{
|
||||
if (m_isDefining) {
|
||||
auto currentPlaneOpt = m_viewport->currentPlane();
|
||||
if (!currentPlaneOpt) return;
|
||||
const auto& plane = currentPlaneOpt.value();
|
||||
|
||||
QVector3D worldPos;
|
||||
QVector3D startPos(m_firstLinePoint.X(), m_firstLinePoint.Y(), m_firstLinePoint.Z());
|
||||
QString dimText;
|
||||
@@ -660,24 +651,25 @@ void LineTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMa
|
||||
if (m_viewport->property("isChainedLine").toBool()) {
|
||||
refDir = m_viewport->property("previousLineDirection").value<QVector3D>();
|
||||
} else {
|
||||
const auto& xDir = plane.XDirection();
|
||||
refDir = QVector3D(xDir.X(), xDir.Y(), xDir.Z());
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
refDir = QVector3D(1, 0, 0);
|
||||
} else { // YZ
|
||||
refDir = QVector3D(0, 1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), plane);
|
||||
QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane());
|
||||
QVector3D mouseVec = currentMouseWorldPos - startPos;
|
||||
|
||||
gp_Pnt startPnt(startPos.x(), startPos.y(), startPos.z());
|
||||
gp_Pnt mousePnt(currentMouseWorldPos.x(), currentMouseWorldPos.y(), currentMouseWorldPos.z());
|
||||
gp_Dir refDirGp(refDir.x(), refDir.y(), refDir.z());
|
||||
double mouseAngle;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) mouseAngle = qRadiansToDegrees(atan2(mouseVec.y(), mouseVec.x()));
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.x()));
|
||||
else mouseAngle = qRadiansToDegrees(atan2(mouseVec.z(), mouseVec.y()));
|
||||
|
||||
gp_Pnt2d startPnt2d(gp_Vec(plane.Location(), startPnt).Dot(plane.XDirection()), gp_Vec(plane.Location(), startPnt).Dot(plane.YDirection()));
|
||||
gp_Pnt2d mousePnt2d(gp_Vec(plane.Location(), mousePnt).Dot(plane.XDirection()), gp_Vec(plane.Location(), mousePnt).Dot(plane.YDirection()));
|
||||
gp_Dir2d refDir2d(refDirGp.Dot(plane.XDirection()), refDirGp.Dot(plane.YDirection()));
|
||||
|
||||
gp_Vec2d mouseVec2d(startPnt2d, mousePnt2d);
|
||||
double mouseAngle = qRadiansToDegrees(atan2(mouseVec2d.Y(), mouseVec2d.X()));
|
||||
double refAngle = qRadiansToDegrees(atan2(refDir2d.Y(), refDir2d.X()));
|
||||
double refAngle;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) refAngle = qRadiansToDegrees(atan2(refDir.y(), refDir.x()));
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) refAngle = qRadiansToDegrees(atan2(refDir.z(), refDir.x()));
|
||||
else refAngle = qRadiansToDegrees(atan2(refDir.z(), refDir.y()));
|
||||
|
||||
double relativeMouseAngle = mouseAngle - refAngle;
|
||||
while (relativeMouseAngle <= -180.0) relativeMouseAngle += 360.0;
|
||||
@@ -695,9 +687,10 @@ void LineTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMa
|
||||
}
|
||||
|
||||
double finalAngleRad = qDegreesToRadians(refAngle + snappedAngle);
|
||||
gp_Dir2d finalDir2d(cos(finalAngleRad), sin(finalAngleRad));
|
||||
gp_Dir finalDir3d = ElCLib::To3d(plane, finalDir2d);
|
||||
QVector3D finalDir(finalDir3d.X(), finalDir3d.Y(), finalDir3d.Z());
|
||||
QVector3D finalDir;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) finalDir = QVector3D(cos(finalAngleRad), sin(finalAngleRad), 0);
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) finalDir = QVector3D(cos(finalAngleRad), 0, sin(finalAngleRad));
|
||||
else finalDir = QVector3D(0, cos(finalAngleRad), sin(finalAngleRad));
|
||||
|
||||
if (lengthFromInput) {
|
||||
lineLength = inputLength;
|
||||
@@ -709,34 +702,33 @@ void LineTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMa
|
||||
|
||||
} else if (lengthFromInput) {
|
||||
lineLength = inputLength;
|
||||
QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), plane);
|
||||
QVector3D currentMouseWorldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane());
|
||||
QVector3D dir = (currentMouseWorldPos - startPos);
|
||||
if (dir.length() > 1e-6) {
|
||||
dir.normalize();
|
||||
worldPos = startPos + inputLength * dir;
|
||||
} else {
|
||||
const auto& xDir = plane.XDirection();
|
||||
worldPos = startPos + inputLength * QVector3D(xDir.X(), xDir.Y(), xDir.Z());
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
worldPos = startPos + QVector3D(inputLength, 0, 0);
|
||||
} else {
|
||||
worldPos = startPos + QVector3D(0, inputLength, 0);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
worldPos = m_viewport->unproject(m_viewport->currentMousePos(), plane);
|
||||
gp_Pnt worldPosPnt(worldPos.x(), worldPos.y(), worldPos.z());
|
||||
|
||||
worldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane());
|
||||
if (m_viewport->isSnappingOrigin()) {
|
||||
worldPosPnt = plane.Location();
|
||||
worldPos.setX(0); worldPos.setY(0); worldPos.setZ(0);
|
||||
} else if (m_viewport->isSnappingVertex()) {
|
||||
worldPosPnt = m_viewport->snapVertex();
|
||||
} else if (m_viewport->isSnappingHorizontal() || m_viewport->isSnappingVertical()) {
|
||||
gp_Pnt2d worldPos2d(gp_Vec(plane.Location(), worldPosPnt).Dot(plane.XDirection()), gp_Vec(plane.Location(), worldPosPnt).Dot(plane.YDirection()));
|
||||
gp_Pnt2d firstPoint2d(gp_Vec(plane.Location(), m_firstLinePoint).Dot(plane.XDirection()), gp_Vec(plane.Location(), m_firstLinePoint).Dot(plane.YDirection()));
|
||||
if (m_viewport->isSnappingHorizontal()) {
|
||||
worldPos2d.SetY(firstPoint2d.Y());
|
||||
} else { // vertical
|
||||
worldPos2d.SetX(firstPoint2d.X());
|
||||
worldPos.setX(m_viewport->snapVertex().X()); worldPos.setY(m_viewport->snapVertex().Y()); worldPos.setZ(m_viewport->snapVertex().Z());
|
||||
} else if (m_viewport->isSnappingHorizontal()) {
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) worldPos.setY(m_firstLinePoint.Y());
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) worldPos.setZ(m_firstLinePoint.Z());
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) worldPos.setZ(m_firstLinePoint.Z());
|
||||
} else if (m_viewport->isSnappingVertical()) {
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) worldPos.setX(m_firstLinePoint.X());
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) worldPos.setX(m_firstLinePoint.X());
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) worldPos.setY(m_firstLinePoint.Y());
|
||||
}
|
||||
worldPosPnt = ElCLib::To3d(plane, worldPos2d);
|
||||
}
|
||||
worldPos.setX(worldPosPnt.X()); worldPos.setY(worldPosPnt.Y()); worldPos.setZ(worldPosPnt.Z());
|
||||
lineLength = (worldPos - startPos).length();
|
||||
}
|
||||
|
||||
@@ -747,26 +739,24 @@ void LineTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMa
|
||||
if (m_viewport->property("isChainedLine").toBool()) {
|
||||
refDir = m_viewport->property("previousLineDirection").value<QVector3D>();
|
||||
} else {
|
||||
const auto& xDir = plane.XDirection();
|
||||
refDir = QVector3D(xDir.X(), xDir.Y(), xDir.Z());
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY || m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) refDir = QVector3D(1, 0, 0);
|
||||
else refDir = QVector3D(0, 1, 0);
|
||||
}
|
||||
|
||||
QVector3D currentMouseWorldPosForText = m_viewport->unproject(m_viewport->currentMousePos(), plane);
|
||||
QVector3D currentMouseWorldPosForText = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane());
|
||||
QVector3D mouseVecForText = currentMouseWorldPosForText - startPos;
|
||||
|
||||
if (angleFromInput) {
|
||||
if (mouseVecForText.length() > 1e-6) {
|
||||
gp_Pnt startPnt(startPos.x(), startPos.y(), startPos.z());
|
||||
gp_Pnt mousePnt(currentMouseWorldPosForText.x(), currentMouseWorldPosForText.y(), currentMouseWorldPosForText.z());
|
||||
gp_Dir refDirGp(refDir.x(), refDir.y(), refDir.z());
|
||||
double mouseAngle;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) mouseAngle = qRadiansToDegrees(atan2(mouseVecForText.y(), mouseVecForText.x()));
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) mouseAngle = qRadiansToDegrees(atan2(mouseVecForText.z(), mouseVecForText.x()));
|
||||
else mouseAngle = qRadiansToDegrees(atan2(mouseVecForText.z(), mouseVecForText.y()));
|
||||
|
||||
gp_Pnt2d startPnt2d(gp_Vec(plane.Location(), startPnt).Dot(plane.XDirection()), gp_Vec(plane.Location(), startPnt).Dot(plane.YDirection()));
|
||||
gp_Pnt2d mousePnt2d(gp_Vec(plane.Location(), mousePnt).Dot(plane.XDirection()), gp_Vec(plane.Location(), mousePnt).Dot(plane.YDirection()));
|
||||
gp_Dir2d refDir2d(refDirGp.Dot(plane.XDirection()), refDirGp.Dot(plane.YDirection()));
|
||||
|
||||
gp_Vec2d mouseVec2d(startPnt2d, mousePnt2d);
|
||||
double mouseAngle = qRadiansToDegrees(atan2(mouseVec2d.Y(), mouseVec2d.X()));
|
||||
double refAngleForQuadrant = qRadiansToDegrees(atan2(refDir2d.Y(), refDir2d.X()));
|
||||
double refAngleForQuadrant;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) refAngleForQuadrant = qRadiansToDegrees(atan2(refDir.y(), refDir.x()));
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) refAngleForQuadrant = qRadiansToDegrees(atan2(refDir.z(), refDir.x()));
|
||||
else refAngleForQuadrant = qRadiansToDegrees(atan2(refDir.z(), refDir.y()));
|
||||
|
||||
double relativeMouseAngle = mouseAngle - refAngleForQuadrant;
|
||||
while (relativeMouseAngle <= -180.0) relativeMouseAngle += 360.0;
|
||||
@@ -782,23 +772,30 @@ void LineTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMa
|
||||
}
|
||||
}
|
||||
|
||||
gp_Dir refDirGp(refDir.x(), refDir.y(), refDir.z());
|
||||
gp_Dir lineDirGp(lineVec.x(), lineVec.y(), lineVec.z());
|
||||
|
||||
gp_Dir2d refDir2d(refDirGp.Dot(plane.XDirection()), refDirGp.Dot(plane.YDirection()));
|
||||
gp_Dir2d lineDir2d(lineDirGp.Dot(plane.XDirection()), lineDirGp.Dot(plane.YDirection()));
|
||||
|
||||
refAngle = atan2(refDir2d.Y(), refDir2d.X());
|
||||
lineAngle = atan2(lineDir2d.Y(), lineDir2d.X());
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||
refAngle = atan2(refDir.y(), refDir.x());
|
||||
lineAngle = atan2(lineVec.y(), lineVec.x());
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
refAngle = atan2(refDir.z(), refDir.x());
|
||||
lineAngle = atan2(lineVec.z(), lineVec.x());
|
||||
} else { // YZ
|
||||
refAngle = atan2(refDir.z(), refDir.y());
|
||||
lineAngle = atan2(lineVec.z(), lineVec.y());
|
||||
}
|
||||
|
||||
double angleDiff = lineAngle - refAngle;
|
||||
while (angleDiff <= -M_PI) angleDiff += 2 * M_PI;
|
||||
while (angleDiff > M_PI) angleDiff -= 2 * M_PI;
|
||||
lineAngle = refAngle + angleDiff;
|
||||
|
||||
gp_Dir2d perpDir2d(-lineDir2d.Y(), lineDir2d.X());
|
||||
gp_Dir perpDir3d = ElCLib::To3d(plane, perpDir2d);
|
||||
QVector3D perpVec(perpDir3d.X(), perpDir3d.Y(), perpDir3d.Z());
|
||||
QVector3D perpVec;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||
perpVec = QVector3D(-lineVec.y(), lineVec.x(), 0).normalized();
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
perpVec = QVector3D(-lineVec.z(), 0, lineVec.x()).normalized();
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) {
|
||||
perpVec = QVector3D(0, -lineVec.z(), lineVec.y()).normalized();
|
||||
}
|
||||
|
||||
if (angleDiff < 0) {
|
||||
perpVec = -perpVec;
|
||||
@@ -841,11 +838,9 @@ void LineTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMa
|
||||
QVector3D textPos3DAngle;
|
||||
float textOffset = 0.035f * -m_viewport->camera()->zoom();
|
||||
|
||||
const auto& xDir = plane.XDirection();
|
||||
const auto& yDir = plane.YDirection();
|
||||
QVector3D u_axis(xDir.X(), xDir.Y(), xDir.Z());
|
||||
QVector3D v_axis(yDir.X(), yDir.Y(), yDir.Z());
|
||||
textPos3DAngle = startPos + (radius + textOffset) * (cos(midAngle) * u_axis + sin(midAngle) * v_axis);
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) textPos3DAngle = startPos + (radius + textOffset) * QVector3D(cos(midAngle), sin(midAngle), 0);
|
||||
else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) textPos3DAngle = startPos + (radius + textOffset) * QVector3D(cos(midAngle), 0, sin(midAngle));
|
||||
else textPos3DAngle = startPos + (radius + textOffset) * QVector3D(0, cos(midAngle), sin(midAngle));
|
||||
|
||||
QVector3D screenPosAngle = m_viewport->project(textPos3DAngle, modelView, projection, m_viewport->rect());
|
||||
if (screenPosAngle.z() < 1.0f) {
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#ifndef LINETOOL_H
|
||||
#define LINETOOL_H
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include "ViewportWidget.h"
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#ifndef MAINWINDOW_H
|
||||
#define MAINWINDOW_H
|
||||
|
||||
+180
-144
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#include "RectangleTool.h"
|
||||
#include "ViewportWidget.h"
|
||||
@@ -15,11 +15,6 @@
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <cmath>
|
||||
#include <QtMath>
|
||||
#include <optional>
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <ElCLib.hxx>
|
||||
|
||||
RectangleTool::RectangleTool(ViewportWidget* viewport)
|
||||
: SketchTool(viewport)
|
||||
@@ -40,18 +35,14 @@ void RectangleTool::activate()
|
||||
|
||||
void RectangleTool::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
auto currentPlaneOpt = m_viewport->currentPlane();
|
||||
if (!currentPlaneOpt) return;
|
||||
const auto& plane = currentPlaneOpt.value();
|
||||
|
||||
gp_Pnt p;
|
||||
if (!m_isDefining) {
|
||||
if (m_viewport->isSnappingOrigin()) {
|
||||
p = plane.Location();
|
||||
p.SetCoord(0, 0, 0);
|
||||
} else if (m_viewport->isSnappingVertex()) {
|
||||
p = m_viewport->snapVertex();
|
||||
} else {
|
||||
QVector3D worldPos = m_viewport->unproject(event->pos(), plane);
|
||||
QVector3D worldPos = m_viewport->unproject(event->pos(), m_viewport->currentPlane());
|
||||
p.SetCoord(worldPos.x(), worldPos.y(), worldPos.z());
|
||||
}
|
||||
m_firstRectanglePoint = p;
|
||||
@@ -60,8 +51,8 @@ void RectangleTool::mousePressEvent(QMouseEvent *event)
|
||||
m_viewport->setProperty("heightInput", "");
|
||||
m_viewport->setProperty("dimensionEditMode", "height");
|
||||
} else {
|
||||
QVector3D worldPosQ;
|
||||
gp_Pnt startPos = m_firstRectanglePoint;
|
||||
QVector3D worldPos;
|
||||
QVector3D startPos(m_firstRectanglePoint.X(), m_firstRectanglePoint.Y(), m_firstRectanglePoint.Z());
|
||||
|
||||
QString widthInput = m_viewport->property("widthInput").toString();
|
||||
QString heightInput = m_viewport->property("heightInput").toString();
|
||||
@@ -80,35 +71,45 @@ void RectangleTool::mousePressEvent(QMouseEvent *event)
|
||||
}
|
||||
|
||||
if (widthFromInput || heightFromInput) {
|
||||
QVector3D mousePosQ = m_viewport->unproject(event->pos(), plane);
|
||||
gp_Pnt mousePos(mousePosQ.x(), mousePosQ.y(), mousePosQ.z());
|
||||
|
||||
gp_Pnt2d startPos2d(gp_Vec(plane.Location(), startPos).Dot(plane.XDirection()), gp_Vec(plane.Location(), startPos).Dot(plane.YDirection()));
|
||||
gp_Pnt2d mousePos2d(gp_Vec(plane.Location(), mousePos).Dot(plane.XDirection()), gp_Vec(plane.Location(), mousePos).Dot(plane.YDirection()));
|
||||
|
||||
double current_w = qAbs(mousePos2d.X() - startPos2d.X());
|
||||
double current_h = qAbs(mousePos2d.Y() - startPos2d.Y());
|
||||
|
||||
QVector3D mousePos = m_viewport->unproject(event->pos(), m_viewport->currentPlane());
|
||||
QVector3D mouseDir = mousePos - startPos;
|
||||
double current_w, current_h;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||
current_w = qAbs(mouseDir.x());
|
||||
current_h = qAbs(mouseDir.y());
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
current_w = qAbs(mouseDir.x());
|
||||
current_h = qAbs(mouseDir.z());
|
||||
} else { // YZ
|
||||
current_w = qAbs(mouseDir.y());
|
||||
current_h = qAbs(mouseDir.z());
|
||||
}
|
||||
double rect_w = widthFromInput ? inputWidth : current_w;
|
||||
double rect_h = heightFromInput ? inputHeight : current_h;
|
||||
|
||||
int signX = (mousePos2d.X() >= startPos2d.X()) ? 1 : -1;
|
||||
int signY = (mousePos2d.Y() >= startPos2d.Y()) ? 1 : -1;
|
||||
|
||||
gp_Pnt2d endPos2d(startPos2d.X() + signX * rect_w, startPos2d.Y() + signY * rect_h);
|
||||
gp_Pnt endPos3d = ElCLib::To3d(plane, endPos2d);
|
||||
worldPosQ = QVector3D(endPos3d.X(), endPos3d.Y(), endPos3d.Z());
|
||||
int signX = (mouseDir.x() >= 0) ? 1 : -1;
|
||||
int signY = (mouseDir.y() >= 0) ? 1 : -1;
|
||||
int signZ = (mouseDir.z() >= 0) ? 1 : -1;
|
||||
worldPos = startPos;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||
worldPos.setX(startPos.x() + signX * rect_w);
|
||||
worldPos.setY(startPos.y() + signY * rect_h);
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
worldPos.setX(startPos.x() + signX * rect_w);
|
||||
worldPos.setZ(startPos.z() + signZ * rect_h);
|
||||
} else { // YZ
|
||||
worldPos.setY(startPos.y() + signY * rect_w);
|
||||
worldPos.setZ(startPos.z() + signZ * rect_h);
|
||||
}
|
||||
} else {
|
||||
if (m_viewport->isSnappingOrigin()) {
|
||||
const auto& origin = plane.Location();
|
||||
worldPosQ.setX(origin.X()); worldPosQ.setY(origin.Y()); worldPosQ.setZ(origin.Z());
|
||||
worldPos.setX(0); worldPos.setY(0); worldPos.setZ(0);
|
||||
} else if (m_viewport->isSnappingVertex()) {
|
||||
worldPosQ = QVector3D(m_viewport->snapVertex().X(), m_viewport->snapVertex().Y(), m_viewport->snapVertex().Z());
|
||||
worldPos = QVector3D(m_viewport->snapVertex().X(), m_viewport->snapVertex().Y(), m_viewport->snapVertex().Z());
|
||||
} else {
|
||||
worldPosQ = m_viewport->unproject(event->pos(), plane);
|
||||
worldPos = m_viewport->unproject(event->pos(), m_viewport->currentPlane());
|
||||
}
|
||||
}
|
||||
p.SetCoord(worldPosQ.x(), worldPosQ.y(), worldPosQ.z());
|
||||
p.SetCoord(worldPos.x(), worldPos.y(), worldPos.z());
|
||||
emit m_viewport->rectangleAdded(m_firstRectanglePoint, p);
|
||||
deactivate();
|
||||
}
|
||||
@@ -121,12 +122,8 @@ void RectangleTool::mouseMoveEvent(QMouseEvent *event)
|
||||
|
||||
void RectangleTool::finalizeCreation()
|
||||
{
|
||||
auto currentPlaneOpt = m_viewport->currentPlane();
|
||||
if (!currentPlaneOpt) return;
|
||||
const auto& plane = currentPlaneOpt.value();
|
||||
|
||||
QVector3D worldPosQ;
|
||||
gp_Pnt startPos = m_firstRectanglePoint;
|
||||
QVector3D worldPos;
|
||||
QVector3D startPos(m_firstRectanglePoint.X(), m_firstRectanglePoint.Y(), m_firstRectanglePoint.Z());
|
||||
|
||||
QString widthInput = m_viewport->property("widthInput").toString();
|
||||
QString heightInput = m_viewport->property("heightInput").toString();
|
||||
@@ -145,30 +142,41 @@ void RectangleTool::finalizeCreation()
|
||||
}
|
||||
|
||||
if (widthFromInput || heightFromInput) {
|
||||
QVector3D mousePosQ = m_viewport->unproject(m_viewport->currentMousePos(), plane);
|
||||
gp_Pnt mousePos(mousePosQ.x(), mousePosQ.y(), mousePosQ.z());
|
||||
|
||||
gp_Pnt2d startPos2d(gp_Vec(plane.Location(), startPos).Dot(plane.XDirection()), gp_Vec(plane.Location(), startPos).Dot(plane.YDirection()));
|
||||
gp_Pnt2d mousePos2d(gp_Vec(plane.Location(), mousePos).Dot(plane.XDirection()), gp_Vec(plane.Location(), mousePos).Dot(plane.YDirection()));
|
||||
|
||||
double current_w = qAbs(mousePos2d.X() - startPos2d.X());
|
||||
double current_h = qAbs(mousePos2d.Y() - startPos2d.Y());
|
||||
|
||||
QVector3D mousePos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane());
|
||||
QVector3D mouseDir = mousePos - startPos;
|
||||
double current_w, current_h;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||
current_w = qAbs(mouseDir.x());
|
||||
current_h = qAbs(mouseDir.y());
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
current_w = qAbs(mouseDir.x());
|
||||
current_h = qAbs(mouseDir.z());
|
||||
} else { // YZ
|
||||
current_w = qAbs(mouseDir.y());
|
||||
current_h = qAbs(mouseDir.z());
|
||||
}
|
||||
double rect_w = widthFromInput ? inputWidth : current_w;
|
||||
double rect_h = heightFromInput ? inputHeight : current_h;
|
||||
|
||||
int signX = (mousePos2d.X() >= startPos2d.X()) ? 1 : -1;
|
||||
int signY = (mousePos2d.Y() >= startPos2d.Y()) ? 1 : -1;
|
||||
|
||||
gp_Pnt2d endPos2d(startPos2d.X() + signX * rect_w, startPos2d.Y() + signY * rect_h);
|
||||
gp_Pnt endPos3d = ElCLib::To3d(plane, endPos2d);
|
||||
worldPosQ = QVector3D(endPos3d.X(), endPos3d.Y(), endPos3d.Z());
|
||||
int signX = (mouseDir.x() >= 0) ? 1 : -1;
|
||||
int signY = (mouseDir.y() >= 0) ? 1 : -1;
|
||||
int signZ = (mouseDir.z() >= 0) ? 1 : -1;
|
||||
worldPos = startPos;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||
worldPos.setX(startPos.x() + signX * rect_w);
|
||||
worldPos.setY(startPos.y() + signY * rect_h);
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
worldPos.setX(startPos.x() + signX * rect_w);
|
||||
worldPos.setZ(startPos.z() + signZ * rect_h);
|
||||
} else { // YZ
|
||||
worldPos.setY(startPos.y() + signY * rect_w);
|
||||
worldPos.setZ(startPos.z() + signZ * rect_h);
|
||||
}
|
||||
} else {
|
||||
worldPosQ = m_viewport->unproject(m_viewport->currentMousePos(), plane);
|
||||
worldPos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane());
|
||||
}
|
||||
|
||||
gp_Pnt p;
|
||||
p.SetCoord(worldPosQ.x(), worldPosQ.y(), worldPosQ.z());
|
||||
p.SetCoord(worldPos.x(), worldPos.y(), worldPos.z());
|
||||
|
||||
emit m_viewport->rectangleAdded(m_firstRectanglePoint, p);
|
||||
deactivate();
|
||||
@@ -176,14 +184,10 @@ void RectangleTool::finalizeCreation()
|
||||
|
||||
void RectangleTool::paintGL()
|
||||
{
|
||||
if (!m_isDefining) return;
|
||||
auto currentPlaneOpt = m_viewport->currentPlane();
|
||||
if (!currentPlaneOpt) return;
|
||||
const auto& plane = currentPlaneOpt.value();
|
||||
|
||||
if (m_isDefining) {
|
||||
QVector<GLfloat> vertices;
|
||||
QVector3D worldPosQ;
|
||||
gp_Pnt startPos = m_firstRectanglePoint;
|
||||
QVector3D worldPos;
|
||||
QVector3D startPos(m_firstRectanglePoint.X(), m_firstRectanglePoint.Y(), m_firstRectanglePoint.Z());
|
||||
|
||||
QString widthInput = m_viewport->property("widthInput").toString();
|
||||
QString heightInput = m_viewport->property("heightInput").toString();
|
||||
@@ -202,70 +206,82 @@ void RectangleTool::paintGL()
|
||||
if (ok) heightFromInput = true;
|
||||
}
|
||||
|
||||
QVector3D mousePosQ = m_viewport->unproject(m_viewport->currentMousePos(), plane);
|
||||
gp_Pnt mousePos(mousePosQ.x(), mousePosQ.y(), mousePosQ.z());
|
||||
QVector3D mousePos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane());
|
||||
|
||||
if (widthFromInput || heightFromInput) {
|
||||
gp_Pnt2d startPos2d(gp_Vec(plane.Location(), startPos).Dot(plane.XDirection()), gp_Vec(plane.Location(), startPos).Dot(plane.YDirection()));
|
||||
gp_Pnt2d mousePos2d(gp_Vec(plane.Location(), mousePos).Dot(plane.XDirection()), gp_Vec(plane.Location(), mousePos).Dot(plane.YDirection()));
|
||||
|
||||
double current_w = qAbs(mousePos2d.X() - startPos2d.X());
|
||||
double current_h = qAbs(mousePos2d.Y() - startPos2d.Y());
|
||||
|
||||
QVector3D mouseDir = mousePos - startPos;
|
||||
double current_w, current_h;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||
current_w = qAbs(mouseDir.x());
|
||||
current_h = qAbs(mouseDir.y());
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
current_w = qAbs(mouseDir.x());
|
||||
current_h = qAbs(mouseDir.z());
|
||||
} else { // YZ
|
||||
current_w = qAbs(mouseDir.y());
|
||||
current_h = qAbs(mouseDir.z());
|
||||
}
|
||||
double rect_w = widthFromInput ? inputWidth : current_w;
|
||||
double rect_h = heightFromInput ? inputHeight : current_h;
|
||||
|
||||
int signX = (mousePos2d.X() >= startPos2d.X()) ? 1 : -1;
|
||||
int signY = (mousePos2d.Y() >= startPos2d.Y()) ? 1 : -1;
|
||||
|
||||
gp_Pnt2d endPos2d(startPos2d.X() + signX * rect_w, startPos2d.Y() + signY * rect_h);
|
||||
gp_Pnt endPos3d = ElCLib::To3d(plane, endPos2d);
|
||||
worldPosQ = QVector3D(endPos3d.X(), endPos3d.Y(), endPos3d.Z());
|
||||
int signX = (mouseDir.x() >= 0) ? 1 : -1;
|
||||
int signY = (mouseDir.y() >= 0) ? 1 : -1;
|
||||
int signZ = (mouseDir.z() >= 0) ? 1 : -1;
|
||||
worldPos = startPos;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||
worldPos.setX(startPos.x() + signX * rect_w);
|
||||
worldPos.setY(startPos.y() + signY * rect_h);
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
worldPos.setX(startPos.x() + signX * rect_w);
|
||||
worldPos.setZ(startPos.z() + signZ * rect_h);
|
||||
} else { // YZ
|
||||
worldPos.setY(startPos.y() + signY * rect_w);
|
||||
worldPos.setZ(startPos.z() + signZ * rect_h);
|
||||
}
|
||||
} else {
|
||||
worldPosQ = mousePosQ;
|
||||
worldPos = mousePos;
|
||||
if (m_viewport->isSnappingOrigin()) {
|
||||
const auto& origin = plane.Location();
|
||||
worldPosQ.setX(origin.X()); worldPosQ.setY(origin.Y()); worldPosQ.setZ(origin.Z());
|
||||
worldPos.setX(0); worldPos.setY(0); worldPos.setZ(0);
|
||||
} else if (m_viewport->isSnappingVertex()) {
|
||||
worldPosQ.setX(m_viewport->snapVertex().X()); worldPosQ.setY(m_viewport->snapVertex().Y()); worldPosQ.setZ(m_viewport->snapVertex().Z());
|
||||
worldPos.setX(m_viewport->snapVertex().X()); worldPos.setY(m_viewport->snapVertex().Y()); worldPos.setZ(m_viewport->snapVertex().Z());
|
||||
}
|
||||
}
|
||||
|
||||
gp_Pnt p1_3d = startPos;
|
||||
gp_Pnt p3_3d(worldPosQ.x(), worldPosQ.y(), worldPosQ.z());
|
||||
gp_Pnt2d p1_2d(gp_Vec(plane.Location(), p1_3d).Dot(plane.XDirection()), gp_Vec(plane.Location(), p1_3d).Dot(plane.YDirection()));
|
||||
gp_Pnt2d p3_2d(gp_Vec(plane.Location(), p3_3d).Dot(plane.XDirection()), gp_Vec(plane.Location(), p3_3d).Dot(plane.YDirection()));
|
||||
QVector3D p1 = startPos;
|
||||
QVector3D p2, p3, p4;
|
||||
p3 = worldPos;
|
||||
|
||||
gp_Pnt2d p2_2d(p3_2d.X(), p1_2d.Y());
|
||||
gp_Pnt2d p4_2d(p1_2d.X(), p3_2d.Y());
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||
p2.setX(p3.x()); p2.setY(p1.y()); p2.setZ(p1.z());
|
||||
p4.setX(p1.x()); p4.setY(p3.y()); p4.setZ(p1.z());
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
p2.setX(p3.x()); p2.setY(p1.y()); p2.setZ(p1.z());
|
||||
p4.setX(p1.x()); p4.setY(p1.y()); p4.setZ(p3.z());
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::YZ) {
|
||||
p2.setX(p1.x()); p2.setY(p3.y()); p2.setZ(p1.z());
|
||||
p4.setX(p1.x()); p4.setY(p1.y()); p4.setZ(p3.z());
|
||||
}
|
||||
|
||||
gp_Pnt p2_3d = ElCLib::To3d(plane, p2_2d);
|
||||
gp_Pnt p4_3d = ElCLib::To3d(plane, p4_2d);
|
||||
|
||||
vertices << p1_3d.X() << p1_3d.Y() << p1_3d.Z();
|
||||
vertices << p2_3d.X() << p2_3d.Y() << p2_3d.Z();
|
||||
vertices << p2_3d.X() << p2_3d.Y() << p2_3d.Z();
|
||||
vertices << p3_3d.X() << p3_3d.Y() << p3_3d.Z();
|
||||
vertices << p3_3d.X() << p3_3d.Y() << p3_3d.Z();
|
||||
vertices << p4_3d.X() << p4_3d.Y() << p4_3d.Z();
|
||||
vertices << p4_3d.X() << p4_3d.Y() << p4_3d.Z();
|
||||
vertices << p1_3d.X() << p1_3d.Y() << p1_3d.Z();
|
||||
vertices << p1.x() << p1.y() << p1.z();
|
||||
vertices << p2.x() << p2.y() << p2.z();
|
||||
vertices << p2.x() << p2.y() << p2.z();
|
||||
vertices << p3.x() << p3.y() << p3.z();
|
||||
vertices << p3.x() << p3.y() << p3.z();
|
||||
vertices << p4.x() << p4.y() << p4.z();
|
||||
vertices << p4.x() << p4.y() << p4.z();
|
||||
vertices << p1.x() << p1.y() << p1.z();
|
||||
|
||||
m_viewport->shaderProgram()->setUniformValue(m_viewport->colorLoc(), QVector4D(1.0f, 1.0f, 0.0f, 1.0f));
|
||||
m_viewport->vbo().bind();
|
||||
m_viewport->vbo().allocate(vertices.constData(), vertices.size() * sizeof(GLfloat));
|
||||
glDrawArrays(GL_LINES, 0, 8);
|
||||
}
|
||||
}
|
||||
|
||||
void RectangleTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, const QMatrix4x4& projection)
|
||||
{
|
||||
if (!m_isDefining) return;
|
||||
auto currentPlaneOpt = m_viewport->currentPlane();
|
||||
if (!currentPlaneOpt) return;
|
||||
const auto& plane = currentPlaneOpt.value();
|
||||
|
||||
QVector3D worldPosQ;
|
||||
gp_Pnt p1_3d = m_firstRectanglePoint;
|
||||
if (m_isDefining) {
|
||||
QVector3D worldPos;
|
||||
QVector3D p1_3d(m_firstRectanglePoint.X(), m_firstRectanglePoint.Y(), m_firstRectanglePoint.Z());
|
||||
|
||||
QString widthInput = m_viewport->property("widthInput").toString();
|
||||
QString heightInput = m_viewport->property("heightInput").toString();
|
||||
@@ -284,58 +300,77 @@ void RectangleTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, cons
|
||||
if (ok) heightFromInput = true;
|
||||
}
|
||||
|
||||
QVector3D mousePosQ = m_viewport->unproject(m_viewport->currentMousePos(), plane);
|
||||
gp_Pnt mousePos(mousePosQ.x(), mousePosQ.y(), mousePosQ.z());
|
||||
QVector3D mousePos = m_viewport->unproject(m_viewport->currentMousePos(), m_viewport->currentPlane());
|
||||
|
||||
if (widthFromInput || heightFromInput) {
|
||||
gp_Pnt2d startPos2d(gp_Vec(plane.Location(), p1_3d).Dot(plane.XDirection()), gp_Vec(plane.Location(), p1_3d).Dot(plane.YDirection()));
|
||||
gp_Pnt2d mousePos2d(gp_Vec(plane.Location(), mousePos).Dot(plane.XDirection()), gp_Vec(plane.Location(), mousePos).Dot(plane.YDirection()));
|
||||
|
||||
double current_w = qAbs(mousePos2d.X() - startPos2d.X());
|
||||
double current_h = qAbs(mousePos2d.Y() - startPos2d.Y());
|
||||
|
||||
QVector3D mouseDir = mousePos - p1_3d;
|
||||
double current_w, current_h;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||
current_w = qAbs(mouseDir.x());
|
||||
current_h = qAbs(mouseDir.y());
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
current_w = qAbs(mouseDir.x());
|
||||
current_h = qAbs(mouseDir.z());
|
||||
} else { // YZ
|
||||
current_w = qAbs(mouseDir.y());
|
||||
current_h = qAbs(mouseDir.z());
|
||||
}
|
||||
double rect_w = widthFromInput ? inputWidth : current_w;
|
||||
double rect_h = heightFromInput ? inputHeight : current_h;
|
||||
int signX = (mousePos2d.X() >= startPos2d.X()) ? 1 : -1;
|
||||
int signY = (mousePos2d.Y() >= startPos2d.Y()) ? 1 : -1;
|
||||
|
||||
gp_Pnt2d endPos2d(startPos2d.X() + signX * rect_w, startPos2d.Y() + signY * rect_h);
|
||||
gp_Pnt endPos3d = ElCLib::To3d(plane, endPos2d);
|
||||
worldPosQ = QVector3D(endPos3d.X(), endPos3d.Y(), endPos3d.Z());
|
||||
int signX = (mouseDir.x() >= 0) ? 1 : -1;
|
||||
int signY = (mouseDir.y() >= 0) ? 1 : -1;
|
||||
int signZ = (mouseDir.z() >= 0) ? 1 : -1;
|
||||
worldPos = p1_3d;
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||
worldPos.setX(p1_3d.x() + signX * rect_w);
|
||||
worldPos.setY(p1_3d.y() + signY * rect_h);
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
worldPos.setX(p1_3d.x() + signX * rect_w);
|
||||
worldPos.setZ(p1_3d.z() + signZ * rect_h);
|
||||
} else { // YZ
|
||||
worldPos.setY(p1_3d.y() + signY * rect_w);
|
||||
worldPos.setZ(p1_3d.z() + signZ * rect_h);
|
||||
}
|
||||
} else {
|
||||
worldPosQ = mousePosQ;
|
||||
worldPos = mousePos;
|
||||
if (m_viewport->isSnappingOrigin()) {
|
||||
const auto& origin = plane.Location();
|
||||
worldPosQ.setX(origin.X()); worldPosQ.setY(origin.Y()); worldPosQ.setZ(origin.Z());
|
||||
worldPos.setX(0); worldPos.setY(0); worldPos.setZ(0);
|
||||
} else if (m_viewport->isSnappingVertex()) {
|
||||
worldPosQ.setX(m_viewport->snapVertex().X()); worldPosQ.setY(m_viewport->snapVertex().Y()); worldPosQ.setZ(m_viewport->snapVertex().Z());
|
||||
worldPos.setX(m_viewport->snapVertex().X()); worldPos.setY(m_viewport->snapVertex().Y()); worldPos.setZ(m_viewport->snapVertex().Z());
|
||||
}
|
||||
}
|
||||
gp_Pnt p3_3d(worldPosQ.x(), worldPosQ.y(), worldPosQ.z());
|
||||
gp_Pnt p2_3d, p4_3d;
|
||||
QVector3D p3_3d = worldPos;
|
||||
QVector3D p2_3d, p4_3d;
|
||||
|
||||
gp_Pnt2d p1_2d(gp_Vec(plane.Location(), p1_3d).Dot(plane.XDirection()), gp_Vec(plane.Location(), p1_3d).Dot(plane.YDirection()));
|
||||
gp_Pnt2d p3_2d(gp_Vec(plane.Location(), p3_3d).Dot(plane.XDirection()), gp_Vec(plane.Location(), p3_3d).Dot(plane.YDirection()));
|
||||
gp_Pnt2d p2_2d(p3_2d.X(), p1_2d.Y());
|
||||
p2_3d = ElCLib::To3d(plane, p2_2d);
|
||||
double w, h;
|
||||
|
||||
double w = qAbs(p3_2d.X() - p1_2d.X());
|
||||
double h = qAbs(p3_2d.Y() - p1_2d.Y());
|
||||
if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XY) {
|
||||
p2_3d.setX(p3_3d.x()); p2_3d.setY(p1_3d.y()); p2_3d.setZ(p1_3d.z());
|
||||
p4_3d.setX(p1_3d.x()); p4_3d.setY(p3_3d.y()); p4_3d.setZ(p1_3d.z());
|
||||
w = qAbs(p3_3d.x() - p1_3d.x());
|
||||
h = qAbs(p3_3d.y() - p1_3d.y());
|
||||
} else if (m_viewport->currentPlane() == ViewportWidget::SketchPlane::XZ) {
|
||||
p2_3d.setX(p3_3d.x()); p2_3d.setY(p1_3d.y()); p2_3d.setZ(p1_3d.z());
|
||||
p4_3d.setX(p1_3d.x()); p4_3d.setY(p1_3d.y()); p4_3d.setZ(p3_3d.z());
|
||||
w = qAbs(p3_3d.x() - p1_3d.x());
|
||||
h = qAbs(p3_3d.z() - p1_3d.z());
|
||||
} else { // YZ
|
||||
p2_3d.setX(p1_3d.x()); p2_3d.setY(p3_3d.y()); p2_3d.setZ(p1_3d.z());
|
||||
p4_3d.setX(p1_3d.x()); p4_3d.setY(p1_3d.y()); p4_3d.setZ(p3_3d.z());
|
||||
w = qAbs(p3_3d.y() - p1_3d.y());
|
||||
h = qAbs(p3_3d.z() - p1_3d.z());
|
||||
}
|
||||
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
QFontMetrics fm(painter.font());
|
||||
|
||||
QVector3D p1_q(p1_3d.X(), p1_3d.Y(), p1_3d.Z());
|
||||
QVector3D p2_q(p2_3d.X(), p2_3d.Y(), p2_3d.Z());
|
||||
QVector3D p3_q(p3_3d.X(), p3_3d.Y(), p3_3d.Z());
|
||||
|
||||
// Width dimension
|
||||
QVector3D widthTextPos3D = (p1_q + p2_q) / 2.0f;
|
||||
QVector3D widthTextPos3D = (p1_3d + p2_3d) / 2.0f;
|
||||
QVector3D screenPosW = m_viewport->project(widthTextPos3D, modelView, projection, m_viewport->rect());
|
||||
if (screenPosW.z() < 1.0f) {
|
||||
QString widthText = widthFromInput ? widthInput : QString::number(w, 'f', 2);
|
||||
QRect textRect = fm.boundingRect(widthText + "__");
|
||||
textRect.moveCenter(screenPosW.toPoint() + QPoint(0, (p3_2d.Y() > p1_2d.Y()) ? -15 : 15));
|
||||
textRect.moveCenter(screenPosW.toPoint() + QPoint(0, (p3_3d.z() > p1_3d.z() || p3_3d.y() > p1_3d.y()) ? -15 : 15));
|
||||
if (m_viewport->property("dimensionEditMode").toString() == "width") {
|
||||
painter.fillRect(textRect.adjusted(-4, -2, 4, 2), QColor(64, 128, 255));
|
||||
} else {
|
||||
@@ -346,12 +381,12 @@ void RectangleTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, cons
|
||||
}
|
||||
|
||||
// Height dimension
|
||||
QVector3D heightTextPos3D = (p2_q + p3_q) / 2.0f;
|
||||
QVector3D heightTextPos3D = (p2_3d + p3_3d) / 2.0f;
|
||||
QVector3D screenPosH = m_viewport->project(heightTextPos3D, modelView, projection, m_viewport->rect());
|
||||
if (screenPosH.z() < 1.0f) {
|
||||
QString heightText = heightFromInput ? heightInput : QString::number(h, 'f', 2);
|
||||
QRect textRect = fm.boundingRect(heightText + "__");
|
||||
textRect.moveCenter(screenPosH.toPoint() + QPoint((p3_2d.X() > p1_2d.X()) ? 15 : -15, 0));
|
||||
textRect.moveCenter(screenPosH.toPoint() + QPoint((p3_3d.x() > p1_3d.x()) ? 15 : -15, 0));
|
||||
if (m_viewport->property("dimensionEditMode").toString() == "height") {
|
||||
painter.fillRect(textRect.adjusted(-4, -2, 4, 2), QColor(64, 128, 255));
|
||||
} else {
|
||||
@@ -360,4 +395,5 @@ void RectangleTool::paint2D(QPainter& painter, const QMatrix4x4& modelView, cons
|
||||
painter.setPen(Qt::white);
|
||||
painter.drawText(textRect, Qt::AlignCenter, heightText);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#ifndef RECTANGLETOOL_H
|
||||
#define RECTANGLETOOL_H
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#include "SketchCircle.h"
|
||||
#include <QJsonArray>
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#ifndef SKETCHCIRCLE_H
|
||||
#define SKETCHCIRCLE_H
|
||||
|
||||
+17
-68
@@ -1,53 +1,20 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#include "SketchFeature.h"
|
||||
#include "SketchObject.h"
|
||||
#include "SketchLine.h"
|
||||
#include "SketchRectangle.h"
|
||||
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <TopoDS_Compound.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
|
||||
namespace
|
||||
{
|
||||
void gpPntToJson(const gp_Pnt& p, QJsonObject& json) {
|
||||
json["x"] = p.X();
|
||||
json["y"] = p.Y();
|
||||
json["z"] = p.Z();
|
||||
}
|
||||
|
||||
gp_Pnt jsonToGpPnt(const QJsonObject& json) {
|
||||
return gp_Pnt(json["x"].toDouble(), json["y"].toDouble(), json["z"].toDouble());
|
||||
}
|
||||
|
||||
void gpDirToJson(const gp_Dir& d, QJsonObject& json) {
|
||||
json["x"] = d.X();
|
||||
json["y"] = d.Y();
|
||||
json["z"] = d.Z();
|
||||
}
|
||||
|
||||
gp_Dir jsonToGpDir(const QJsonObject& json) {
|
||||
return gp_Dir(json["x"].toDouble(), json["y"].toDouble(), json["z"].toDouble());
|
||||
}
|
||||
}
|
||||
|
||||
SketchFeature::SketchFeature(const QString& name)
|
||||
: Feature(name), m_plane(gp_Pnt(0, 0, 0), gp::DZ())
|
||||
: Feature(name)
|
||||
{
|
||||
BRep_Builder builder;
|
||||
TopoDS_Compound compound;
|
||||
builder.MakeCompound(compound);
|
||||
m_shape = compound;
|
||||
}
|
||||
|
||||
SketchFeature::~SketchFeature()
|
||||
@@ -60,12 +27,12 @@ QString SketchFeature::type() const
|
||||
return "Sketch";
|
||||
}
|
||||
|
||||
void SketchFeature::setPlane(const gp_Ax2& plane)
|
||||
void SketchFeature::setPlane(SketchPlane plane)
|
||||
{
|
||||
m_plane = plane;
|
||||
}
|
||||
|
||||
const gp_Ax2& SketchFeature::plane() const
|
||||
SketchFeature::SketchPlane SketchFeature::plane() const
|
||||
{
|
||||
return m_plane;
|
||||
}
|
||||
@@ -75,12 +42,6 @@ const TopoDS_Shape& SketchFeature::shape() const
|
||||
return m_shape;
|
||||
}
|
||||
|
||||
void SketchFeature::addShape(const TopoDS_Shape& shape)
|
||||
{
|
||||
BRep_Builder builder;
|
||||
builder.Add(m_shape, shape);
|
||||
}
|
||||
|
||||
void SketchFeature::addObject(SketchObject* object)
|
||||
{
|
||||
m_objects.append(object);
|
||||
@@ -94,14 +55,11 @@ const QList<SketchObject*>& SketchFeature::objects() const
|
||||
void SketchFeature::read(const QJsonObject& json)
|
||||
{
|
||||
Feature::read(json);
|
||||
if (json.contains("plane") && json["plane"].isObject()) {
|
||||
QJsonObject planeJson = json["plane"].toObject();
|
||||
if (planeJson.contains("origin") && planeJson.contains("normal") && planeJson.contains("x_direction")) {
|
||||
gp_Pnt origin = jsonToGpPnt(planeJson["origin"].toObject());
|
||||
gp_Dir normal = jsonToGpDir(planeJson["normal"].toObject());
|
||||
gp_Dir x_dir = jsonToGpDir(planeJson["x_direction"].toObject());
|
||||
m_plane = gp_Ax2(origin, normal, x_dir);
|
||||
}
|
||||
if (json.contains("plane") && json["plane"].isString()) {
|
||||
QString planeStr = json["plane"].toString();
|
||||
if (planeStr == "XY") m_plane = SketchPlane::XY;
|
||||
else if (planeStr == "XZ") m_plane = SketchPlane::XZ;
|
||||
else if (planeStr == "YZ") m_plane = SketchPlane::YZ;
|
||||
}
|
||||
|
||||
if (json.contains("objects") && json["objects"].isArray()) {
|
||||
@@ -129,22 +87,13 @@ void SketchFeature::read(const QJsonObject& json)
|
||||
void SketchFeature::write(QJsonObject& json) const
|
||||
{
|
||||
Feature::write(json);
|
||||
|
||||
QJsonObject planeJson;
|
||||
|
||||
QJsonObject originJson;
|
||||
gpPntToJson(m_plane.Location(), originJson);
|
||||
planeJson["origin"] = originJson;
|
||||
|
||||
QJsonObject normalJson;
|
||||
gpDirToJson(m_plane.Direction(), normalJson);
|
||||
planeJson["normal"] = normalJson;
|
||||
|
||||
QJsonObject xDirJson;
|
||||
gpDirToJson(m_plane.XDirection(), xDirJson);
|
||||
planeJson["x_direction"] = xDirJson;
|
||||
|
||||
json["plane"] = planeJson;
|
||||
QString planeStr;
|
||||
switch (m_plane) {
|
||||
case SketchPlane::XY: planeStr = "XY"; break;
|
||||
case SketchPlane::XZ: planeStr = "XZ"; break;
|
||||
case SketchPlane::YZ: planeStr = "YZ"; break;
|
||||
}
|
||||
json["plane"] = planeStr;
|
||||
|
||||
QJsonArray objectsArray;
|
||||
for (const auto& object : m_objects) {
|
||||
|
||||
+11
-7
@@ -1,15 +1,14 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#ifndef SKETCHFEATURE_H
|
||||
#define SKETCHFEATURE_H
|
||||
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <QList>
|
||||
#include "Feature.h"
|
||||
|
||||
@@ -18,16 +17,21 @@ class SketchObject;
|
||||
class SketchFeature : public Feature
|
||||
{
|
||||
public:
|
||||
enum class SketchPlane {
|
||||
XY,
|
||||
XZ,
|
||||
YZ
|
||||
};
|
||||
|
||||
SketchFeature(const QString& name);
|
||||
~SketchFeature();
|
||||
|
||||
QString type() const override;
|
||||
|
||||
void setPlane(const gp_Ax2& plane);
|
||||
const gp_Ax2& plane() const;
|
||||
void setPlane(SketchPlane plane);
|
||||
SketchPlane plane() const;
|
||||
|
||||
const TopoDS_Shape& shape() const;
|
||||
void addShape(const TopoDS_Shape& shape);
|
||||
|
||||
void addObject(SketchObject* object);
|
||||
const QList<SketchObject*>& objects() const;
|
||||
@@ -36,7 +40,7 @@ public:
|
||||
void write(QJsonObject &json) const override;
|
||||
|
||||
private:
|
||||
gp_Ax2 m_plane;
|
||||
SketchPlane m_plane;
|
||||
TopoDS_Shape m_shape;
|
||||
QList<SketchObject*> m_objects;
|
||||
};
|
||||
|
||||
+44
-49
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#include "SketchGrid.h"
|
||||
#include "ViewportWidget.h"
|
||||
@@ -13,7 +13,6 @@
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QPainter>
|
||||
#include <QVector>
|
||||
#include <gp_Ax2.hxx>
|
||||
|
||||
namespace {
|
||||
struct GridParams {
|
||||
@@ -63,7 +62,7 @@ void SketchGrid::initializeGL()
|
||||
m_vbo.release();
|
||||
}
|
||||
|
||||
void SketchGrid::paintGL(const gp_Ax2& plane, QOpenGLShaderProgram* shaderProgram, int colorLoc)
|
||||
void SketchGrid::paintGL(SketchPlane plane, QOpenGLShaderProgram* shaderProgram, int colorLoc)
|
||||
{
|
||||
GLint previous_vao = 0;
|
||||
glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &previous_vao);
|
||||
@@ -78,19 +77,12 @@ void SketchGrid::paintGL(const gp_Ax2& plane, QOpenGLShaderProgram* shaderProgra
|
||||
QOpenGLContext::currentContext()->extraFunctions()->glBindVertexArray(previous_vao);
|
||||
}
|
||||
|
||||
void SketchGrid::drawGridLines(const gp_Ax2& plane, QOpenGLShaderProgram* shaderProgram, int colorLoc)
|
||||
void SketchGrid::drawGridLines(SketchPlane plane, QOpenGLShaderProgram* shaderProgram, int colorLoc)
|
||||
{
|
||||
auto params = getGridParams(-m_viewport->camera()->uiCameraDistance());
|
||||
const float minorIncrement = params.minorIncrement;
|
||||
const int gridSize = params.gridSize;
|
||||
|
||||
const auto& origin = plane.Location();
|
||||
const auto& xDir = plane.XDirection();
|
||||
const auto& yDir = plane.YDirection();
|
||||
QVector3D originVec(origin.X(), origin.Y(), origin.Z());
|
||||
QVector3D xDirVec(xDir.X(), xDir.Y(), xDir.Z());
|
||||
QVector3D yDirVec(yDir.X(), yDir.Y(), yDir.Z());
|
||||
|
||||
QVector<GLfloat> minorLines;
|
||||
QVector<GLfloat> majorLines;
|
||||
|
||||
@@ -101,14 +93,16 @@ void SketchGrid::drawGridLines(const gp_Ax2& plane, QOpenGLShaderProgram* shader
|
||||
|
||||
float pos = i * minorIncrement;
|
||||
QVector<GLfloat>& current_vector = (i % 5 == 0) ? majorLines : minorLines;
|
||||
|
||||
QVector3D p1 = originVec + pos * xDirVec - gridSize * yDirVec;
|
||||
QVector3D p2 = originVec + pos * xDirVec + gridSize * yDirVec;
|
||||
current_vector << p1.x() << p1.y() << p1.z() << p2.x() << p2.y() << p2.z();
|
||||
|
||||
QVector3D p3 = originVec - gridSize * xDirVec + pos * yDirVec;
|
||||
QVector3D p4 = originVec + gridSize * xDirVec + pos * yDirVec;
|
||||
current_vector << p3.x() << p3.y() << p3.z() << p4.x() << p4.y() << p4.z();
|
||||
if (plane == XY) {
|
||||
current_vector << pos << -gridSize << 0 << pos << gridSize << 0;
|
||||
current_vector << -gridSize << pos << 0 << gridSize << pos << 0;
|
||||
} else if (plane == XZ) {
|
||||
current_vector << pos << 0 << -gridSize << pos << 0 << gridSize;
|
||||
current_vector << -gridSize << 0 << pos << gridSize << 0 << pos;
|
||||
} else { // YZ
|
||||
current_vector << 0 << pos << -gridSize << 0 << pos << gridSize;
|
||||
current_vector << 0 << -gridSize << pos << 0 << gridSize << pos;
|
||||
}
|
||||
}
|
||||
|
||||
m_vbo.bind();
|
||||
@@ -126,51 +120,50 @@ void SketchGrid::drawGridLines(const gp_Ax2& plane, QOpenGLShaderProgram* shader
|
||||
glDrawArrays(GL_LINES, 0, majorLines.size() / 3);
|
||||
}
|
||||
|
||||
void SketchGrid::drawAxes(const gp_Ax2& plane, QOpenGLShaderProgram* shaderProgram, int colorLoc)
|
||||
void SketchGrid::drawAxes(SketchPlane plane, QOpenGLShaderProgram* shaderProgram, int colorLoc)
|
||||
{
|
||||
auto params = getGridParams(-m_viewport->camera()->uiCameraDistance());
|
||||
const int axisLength = params.gridSize;
|
||||
|
||||
const auto& origin = plane.Location();
|
||||
const auto& xDir = plane.XDirection();
|
||||
const auto& yDir = plane.YDirection();
|
||||
QVector3D originVec(origin.X(), origin.Y(), origin.Z());
|
||||
QVector3D xDirVec(xDir.X(), xDir.Y(), xDir.Z());
|
||||
QVector3D yDirVec(yDir.X(), yDir.Y(), yDir.Z());
|
||||
|
||||
QVector<GLfloat> vertices;
|
||||
|
||||
glLineWidth(2.0f);
|
||||
m_vbo.bind();
|
||||
|
||||
// X Axis (Red)
|
||||
if (plane == XY || plane == XZ) {
|
||||
vertices.clear();
|
||||
QVector3D p1 = originVec - axisLength * xDirVec;
|
||||
QVector3D p2 = originVec + axisLength * xDirVec;
|
||||
vertices << p1.x() << p1.y() << p1.z() << p2.x() << p2.y() << p2.z();
|
||||
vertices << -axisLength << 0 << 0 << axisLength << 0 << 0;
|
||||
shaderProgram->setUniformValue(colorLoc, QVector4D(1.0f, 0.0f, 0.0f, 1.0f));
|
||||
m_vbo.allocate(vertices.constData(), vertices.size() * sizeof(GLfloat));
|
||||
glDrawArrays(GL_LINES, 0, 2);
|
||||
|
||||
}
|
||||
// Y Axis (Green)
|
||||
if (plane == XY || plane == YZ) {
|
||||
vertices.clear();
|
||||
QVector3D p3 = originVec - axisLength * yDirVec;
|
||||
QVector3D p4 = originVec + axisLength * yDirVec;
|
||||
vertices << p3.x() << p3.y() << p3.z() << p4.x() << p4.y() << p4.z();
|
||||
vertices << 0 << -axisLength << 0 << 0 << axisLength << 0;
|
||||
shaderProgram->setUniformValue(colorLoc, QVector4D(0.0f, 1.0f, 0.0f, 1.0f));
|
||||
m_vbo.allocate(vertices.constData(), vertices.size() * sizeof(GLfloat));
|
||||
glDrawArrays(GL_LINES, 0, 2);
|
||||
}
|
||||
// Z Axis (Blue)
|
||||
if (plane == XZ || plane == YZ) {
|
||||
vertices.clear();
|
||||
vertices << 0 << 0 << -axisLength << 0 << 0 << axisLength;
|
||||
shaderProgram->setUniformValue(colorLoc, QVector4D(0.0f, 0.0f, 1.0f, 1.0f));
|
||||
m_vbo.allocate(vertices.constData(), vertices.size() * sizeof(GLfloat));
|
||||
glDrawArrays(GL_LINES, 0, 2);
|
||||
}
|
||||
|
||||
// Origin dot
|
||||
glPointSize(5.0f);
|
||||
vertices.clear();
|
||||
vertices << originVec.x() << originVec.y() << originVec.z();
|
||||
vertices << 0.0f << 0.0f << 0.0f;
|
||||
shaderProgram->setUniformValue(colorLoc, QVector4D(1.0f, 1.0f, 1.0f, 1.0f)); // White
|
||||
m_vbo.allocate(vertices.constData(), vertices.size() * sizeof(GLfloat));
|
||||
glDrawArrays(GL_POINTS, 0, 1);
|
||||
}
|
||||
|
||||
void SketchGrid::paintAxisLabels(QPainter& painter, const gp_Ax2& plane, const QMatrix4x4& modelView, const QMatrix4x4& projection)
|
||||
void SketchGrid::paintAxisLabels(QPainter& painter, SketchGrid::SketchPlane plane, const QMatrix4x4& modelView, const QMatrix4x4& projection)
|
||||
{
|
||||
painter.setPen(Qt::white);
|
||||
painter.setFont(QFont("Arial", 10));
|
||||
@@ -179,21 +172,15 @@ void SketchGrid::paintAxisLabels(QPainter& painter, const gp_Ax2& plane, const Q
|
||||
const float majorIncrement = params.majorIncrement;
|
||||
const int range = params.gridSize;
|
||||
|
||||
const auto& origin = plane.Location();
|
||||
const auto& xDir = plane.XDirection();
|
||||
const auto& yDir = plane.YDirection();
|
||||
QVector3D originVec(origin.X(), origin.Y(), origin.Z());
|
||||
QVector3D xDirVec(xDir.X(), xDir.Y(), xDir.Z());
|
||||
QVector3D yDirVec(yDir.X(), yDir.Y(), yDir.Z());
|
||||
|
||||
auto drawLabelsForAxis = [&](const QVector3D& axisDir) {
|
||||
auto drawLabelsForAxis = [&](int axis_idx) {
|
||||
int numLabels = range / majorIncrement;
|
||||
for (int i = -numLabels; i <= numLabels; ++i) {
|
||||
if (i == 0)
|
||||
continue;
|
||||
|
||||
float val = i * majorIncrement;
|
||||
QVector3D worldCoord = originVec + val * axisDir;
|
||||
QVector3D worldCoord;
|
||||
worldCoord[axis_idx] = val;
|
||||
|
||||
QVector3D screenPos = m_viewport->project(worldCoord, modelView, projection, m_viewport->rect());
|
||||
if (screenPos.z() < 1.0f) { // Not clipped
|
||||
@@ -202,6 +189,14 @@ void SketchGrid::paintAxisLabels(QPainter& painter, const gp_Ax2& plane, const Q
|
||||
}
|
||||
};
|
||||
|
||||
drawLabelsForAxis(xDirVec);
|
||||
drawLabelsForAxis(yDirVec);
|
||||
if (plane == SketchGrid::XY) {
|
||||
drawLabelsForAxis(0); // X
|
||||
drawLabelsForAxis(1); // Y
|
||||
} else if (plane == SketchGrid::XZ) {
|
||||
drawLabelsForAxis(0); // X
|
||||
drawLabelsForAxis(2); // Z
|
||||
} else if (plane == SketchGrid::YZ) {
|
||||
drawLabelsForAxis(1); // Y
|
||||
drawLabelsForAxis(2); // Z
|
||||
}
|
||||
}
|
||||
|
||||
+12
-7
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#ifndef SKETCHGRID_H
|
||||
#define SKETCHGRID_H
|
||||
@@ -12,7 +12,6 @@
|
||||
#include <QMatrix4x4>
|
||||
#include <QOpenGLVertexArrayObject>
|
||||
#include <QOpenGLBuffer>
|
||||
#include <gp_Ax2.hxx>
|
||||
|
||||
class QOpenGLShaderProgram;
|
||||
class QPainter;
|
||||
@@ -21,16 +20,22 @@ class ViewportWidget;
|
||||
class SketchGrid : protected QOpenGLFunctions
|
||||
{
|
||||
public:
|
||||
enum SketchPlane {
|
||||
XY = 1,
|
||||
XZ = 2,
|
||||
YZ = 3
|
||||
};
|
||||
|
||||
explicit SketchGrid(ViewportWidget* viewport);
|
||||
~SketchGrid();
|
||||
|
||||
void initializeGL();
|
||||
void paintGL(const gp_Ax2& plane, QOpenGLShaderProgram* shaderProgram, int colorLoc);
|
||||
void paintAxisLabels(QPainter& painter, const gp_Ax2& plane, const QMatrix4x4& modelView, const QMatrix4x4& projection);
|
||||
void paintGL(SketchPlane plane, QOpenGLShaderProgram* shaderProgram, int colorLoc);
|
||||
void paintAxisLabels(QPainter& painter, SketchPlane plane, const QMatrix4x4& modelView, const QMatrix4x4& projection);
|
||||
|
||||
private:
|
||||
void drawGridLines(const gp_Ax2& plane, QOpenGLShaderProgram* shaderProgram, int colorLoc);
|
||||
void drawAxes(const gp_Ax2& plane, QOpenGLShaderProgram* shaderProgram, int colorLoc);
|
||||
void drawGridLines(SketchPlane plane, QOpenGLShaderProgram* shaderProgram, int colorLoc);
|
||||
void drawAxes(SketchPlane plane, QOpenGLShaderProgram* shaderProgram, int colorLoc);
|
||||
|
||||
QOpenGLVertexArrayObject m_vao;
|
||||
QOpenGLBuffer m_vbo;
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#include "SketchLine.h"
|
||||
#include <QJsonObject>
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#ifndef SKETCHLINE_H
|
||||
#define SKETCHLINE_H
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#ifndef SKETCHOBJECT_H
|
||||
#define SKETCHOBJECT_H
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#include "SketchRectangle.h"
|
||||
#include <QJsonArray>
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#ifndef SKETCHRECTANGLE_H
|
||||
#define SKETCHRECTANGLE_H
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#include "SketchTool.h"
|
||||
#include "ViewportWidget.h"
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#ifndef SKETCHTOOL_H
|
||||
#define SKETCHTOOL_H
|
||||
|
||||
+92
-64
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#include "Snapping.h"
|
||||
|
||||
@@ -19,11 +19,6 @@
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QVector>
|
||||
#include <QtMath>
|
||||
#include <optional>
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <ElCLib.hxx>
|
||||
|
||||
Snapping::Snapping(ViewportWidget* viewport) : m_viewport(viewport)
|
||||
{
|
||||
@@ -35,15 +30,23 @@ bool Snapping::update(const QPoint& mousePos)
|
||||
bool oldIsSnappingVertex = m_isSnappingVertex;
|
||||
|
||||
bool shouldSnap = false;
|
||||
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());
|
||||
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();
|
||||
|
||||
gp_Pnt2d worldPos2d(gp_Vec(plane.Location(), worldPos).Dot(plane.XDirection()), gp_Vec(plane.Location(), worldPos).Dot(plane.YDirection()));
|
||||
shouldSnap = qAbs(worldPos2d.X()) < snapRectHalfSize && qAbs(worldPos2d.Y()) < snapRectHalfSize;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
m_isSnappingOrigin = shouldSnap;
|
||||
@@ -52,11 +55,8 @@ bool Snapping::update(const QPoint& mousePos)
|
||||
}
|
||||
|
||||
m_isSnappingVertex = false;
|
||||
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(gp_Vec(plane.Location(), worldPos).Dot(plane.XDirection()), gp_Vec(plane.Location(), worldPos).Dot(plane.YDirection()));
|
||||
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()) {
|
||||
@@ -66,8 +66,20 @@ 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) {
|
||||
gp_Pnt2d vertex2d(gp_Vec(plane.Location(), vertex).Dot(plane.XDirection()), gp_Vec(plane.Location(), vertex).Dot(plane.YDirection()));
|
||||
bool isClose = qAbs(worldPos2d.X() - vertex2d.X()) < snapRectHalfSize && qAbs(worldPos2d.Y() - vertex2d.Y()) < snapRectHalfSize;
|
||||
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;
|
||||
}
|
||||
|
||||
if (isClose) {
|
||||
m_isSnappingVertex = true;
|
||||
@@ -77,23 +89,37 @@ 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;
|
||||
|
||||
gp_Pnt2d p1_2d(gp_Vec(rectPlane.Location(), p1).Dot(rectPlane.XDirection()), gp_Vec(rectPlane.Location(), p1).Dot(rectPlane.YDirection()));
|
||||
gp_Pnt2d p3_2d(gp_Vec(rectPlane.Location(), p3).Dot(rectPlane.XDirection()), gp_Vec(rectPlane.Location(), p3).Dot(rectPlane.YDirection()));
|
||||
|
||||
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(rectPlane, p2_2d);
|
||||
gp_Pnt p4 = ElCLib::To3d(rectPlane, p4_2d);
|
||||
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());
|
||||
}
|
||||
|
||||
const gp_Pnt vertices[] = {p1, p2, p3, p4};
|
||||
for (const auto& vertex : vertices) {
|
||||
gp_Pnt2d vertex2d(gp_Vec(plane.Location(), vertex).Dot(plane.XDirection()), gp_Vec(plane.Location(), vertex).Dot(plane.YDirection()));
|
||||
bool isClose = qAbs(worldPos2d.X() - vertex2d.X()) < snapRectHalfSize && qAbs(worldPos2d.Y() - vertex2d.Y()) < snapRectHalfSize;
|
||||
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;
|
||||
}
|
||||
|
||||
if (isClose) {
|
||||
m_isSnappingVertex = true;
|
||||
@@ -118,41 +144,43 @@ 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 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();
|
||||
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;
|
||||
}
|
||||
} else if (m_isSnappingVertex) {
|
||||
const float rectSize = 0.0075f * -m_viewport->camera()->zoom();
|
||||
const auto& v = m_snapVertex;
|
||||
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();
|
||||
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;
|
||||
}
|
||||
}
|
||||
m_viewport->shaderProgram()->setUniformValue(m_viewport->colorLoc(), QVector4D(1.0f, 1.0f, 0.0f, 0.5f));
|
||||
m_viewport->vbo().bind();
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#ifndef SNAPPING_H
|
||||
#define SNAPPING_H
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#include "ViewCube.h"
|
||||
#include <QGuiApplication>
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#ifndef VIEWCUBE_H
|
||||
#define VIEWCUBE_H
|
||||
|
||||
+82
-90
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#include "ViewportWidget.h"
|
||||
#include "Snapping.h"
|
||||
@@ -33,15 +33,9 @@
|
||||
#include <QApplication>
|
||||
#include <cmath>
|
||||
#include <QtMath>
|
||||
#include <ElCLib.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QVector>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
|
||||
struct PntComparator {
|
||||
bool operator()(const gp_Pnt& a, const gp_Pnt& b) const {
|
||||
@@ -66,7 +60,7 @@ ViewportWidget::ViewportWidget(QWidget *parent)
|
||||
setMouseTracking(true);
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
|
||||
m_currentPlane = gp_Ax2(gp::Origin(), gp::DZ());
|
||||
m_currentPlane = SketchPlane::XY;
|
||||
|
||||
m_toolIcons.insert(static_cast<int>(ApplicationController::ToolType::Line), new QSvgRenderer(QString(":/icons/line.svg"), this));
|
||||
m_toolIcons.insert(static_cast<int>(ApplicationController::ToolType::Rectangle), new QSvgRenderer(QString(":/icons/rectangle.svg"), this));
|
||||
@@ -149,12 +143,12 @@ void ViewportWidget::paintGL()
|
||||
|
||||
// Sketch grid rendering
|
||||
if (m_isSelectingPlane) {
|
||||
if (m_highlightedPlane) {
|
||||
m_sketchGrid->paintGL(m_highlightedPlane.value(), m_shaderProgram, m_colorLoc);
|
||||
if (m_highlightedPlane != SketchPlane::NONE) {
|
||||
m_sketchGrid->paintGL(static_cast<SketchGrid::SketchPlane>(m_highlightedPlane), m_shaderProgram, m_colorLoc);
|
||||
}
|
||||
}
|
||||
if (m_currentPlane) {
|
||||
m_sketchGrid->paintGL(m_currentPlane.value(), m_shaderProgram, m_colorLoc);
|
||||
if (m_currentPlane != SketchPlane::NONE) {
|
||||
m_sketchGrid->paintGL(static_cast<SketchGrid::SketchPlane>(m_currentPlane), m_shaderProgram, m_colorLoc);
|
||||
}
|
||||
|
||||
if (m_isSelectingPlane) {
|
||||
@@ -211,8 +205,8 @@ void ViewportWidget::paintGL()
|
||||
glDisable(GL_CULL_FACE);
|
||||
|
||||
QPainter painter(this);
|
||||
if (m_currentPlane) {
|
||||
m_sketchGrid->paintAxisLabels(painter, m_currentPlane.value(), model, projection);
|
||||
if (m_currentPlane != SketchPlane::NONE) {
|
||||
m_sketchGrid->paintAxisLabels(painter, static_cast<SketchGrid::SketchPlane>(m_currentPlane), model, projection);
|
||||
}
|
||||
m_featureBrowser->paint(painter, width(), height());
|
||||
m_viewCube->paint2D(painter, width(), height());
|
||||
@@ -239,11 +233,9 @@ void ViewportWidget::mousePressEvent(QMouseEvent *event)
|
||||
m_camera->mousePressEvent(event);
|
||||
|
||||
if (event->button() == Qt::MiddleButton && !(QApplication::keyboardModifiers() & Qt::ShiftModifier)) {
|
||||
if (m_currentPlane) {
|
||||
m_camera->startRotation(unproject(event->pos(), m_currentPlane.value()));
|
||||
m_camera->startRotation(unproject(event->pos(), m_currentPlane));
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
if (m_viewCube->handleMousePress(event->pos(), width(), height())) {
|
||||
@@ -253,10 +245,10 @@ void ViewportWidget::mousePressEvent(QMouseEvent *event)
|
||||
}
|
||||
|
||||
if (m_isSelectingPlane) {
|
||||
if (m_highlightedPlane) {
|
||||
emit planeSelected(m_highlightedPlane.value());
|
||||
if (m_highlightedPlane != SketchPlane::NONE) {
|
||||
emit planeSelected(m_highlightedPlane);
|
||||
m_isSelectingPlane = false;
|
||||
m_highlightedPlane.reset();
|
||||
m_highlightedPlane = SketchPlane::NONE;
|
||||
update();
|
||||
}
|
||||
return;
|
||||
@@ -276,17 +268,8 @@ void ViewportWidget::mouseMoveEvent(QMouseEvent *event)
|
||||
m_currentMousePos = event->pos();
|
||||
|
||||
if (m_isSelectingPlane) {
|
||||
auto newHighlight = checkPlaneSelection(m_currentMousePos);
|
||||
bool needsUpdate = newHighlight.has_value() != m_highlightedPlane.has_value();
|
||||
if (!needsUpdate && newHighlight) {
|
||||
// Very basic check, assumes planes are one of the 3 cardinal ones
|
||||
// and checkPlaneSelection returns them consistently.
|
||||
if (!newHighlight->Direction().IsEqual(m_highlightedPlane->Direction(), 1e-9)) {
|
||||
needsUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (needsUpdate) {
|
||||
SketchPlane newHighlight = checkPlaneSelection(m_currentMousePos);
|
||||
if (newHighlight != m_highlightedPlane) {
|
||||
m_highlightedPlane = newHighlight;
|
||||
update();
|
||||
}
|
||||
@@ -306,10 +289,8 @@ void ViewportWidget::mouseMoveEvent(QMouseEvent *event)
|
||||
|
||||
void ViewportWidget::wheelEvent(QWheelEvent *event)
|
||||
{
|
||||
if (m_currentPlane) {
|
||||
QVector3D worldPos = unproject(event->position().toPoint(), m_currentPlane.value());
|
||||
QVector3D worldPos = unproject(event->position().toPoint(), m_currentPlane);
|
||||
m_camera->wheelEvent(event, worldPos);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewportWidget::keyPressEvent(QKeyEvent *event)
|
||||
@@ -322,8 +303,8 @@ void ViewportWidget::keyPressEvent(QKeyEvent *event)
|
||||
if (event->key() == Qt::Key_Escape) {
|
||||
if (m_isSelectingPlane) {
|
||||
m_isSelectingPlane = false;
|
||||
m_highlightedPlane.reset();
|
||||
m_currentPlane = gp_Ax2(gp::Origin(), gp::DZ());
|
||||
m_highlightedPlane = SketchPlane::NONE;
|
||||
m_currentPlane = SketchPlane::XY;
|
||||
update();
|
||||
return;
|
||||
}
|
||||
@@ -388,19 +369,19 @@ bool ViewportWidget::focusNextPrevChild(bool next)
|
||||
return QOpenGLWidget::focusNextPrevChild(next);
|
||||
}
|
||||
|
||||
void ViewportWidget::onSketchModeStarted(const gp_Ax2& plane)
|
||||
void ViewportWidget::onSketchModeStarted(SketchPlane plane)
|
||||
{
|
||||
m_currentPlane = plane;
|
||||
|
||||
m_camera->saveState();
|
||||
m_camera->animateToPlaneView(plane);
|
||||
m_camera->animateToPlaneView(static_cast<int>(plane));
|
||||
}
|
||||
|
||||
void ViewportWidget::onPlaneSelectionModeStarted()
|
||||
{
|
||||
m_isSelectingPlane = true;
|
||||
m_highlightedPlane.reset();
|
||||
m_currentPlane.reset();
|
||||
m_highlightedPlane = SketchPlane::NONE;
|
||||
m_currentPlane = SketchPlane::NONE;
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -412,7 +393,7 @@ void ViewportWidget::onSketchModeEnded()
|
||||
void ViewportWidget::onRestoreStateAnimationFinished()
|
||||
{
|
||||
// Return to showing the base XY grid when not in a sketch
|
||||
m_currentPlane = gp_Ax2(gp::Origin(), gp::DZ());
|
||||
m_currentPlane = SketchPlane::XY;
|
||||
update();
|
||||
}
|
||||
|
||||
@@ -484,7 +465,7 @@ void ViewportWidget::onActiveToolChanged(int tool)
|
||||
}
|
||||
}
|
||||
|
||||
QVector3D ViewportWidget::unproject(const QPoint& screenPos, const gp_Ax2& plane)
|
||||
QVector3D ViewportWidget::unproject(const QPoint& screenPos, SketchPlane plane)
|
||||
{
|
||||
QMatrix4x4 model = m_camera->modelViewMatrix();
|
||||
|
||||
@@ -513,13 +494,17 @@ QVector3D ViewportWidget::unproject(const QPoint& screenPos, const gp_Ax2& plane
|
||||
QVector3D rayOrigin(nearPoint_world);
|
||||
QVector3D rayDir = (QVector3D(farPoint_world) - rayOrigin).normalized();
|
||||
|
||||
const auto& planeNormalDir = plane.Direction();
|
||||
QVector3D planeNormal(planeNormalDir.X(), planeNormalDir.Y(), planeNormalDir.Z());
|
||||
QVector3D planeNormal;
|
||||
switch (plane) {
|
||||
case SketchPlane::XY: planeNormal = QVector3D(0, 0, 1); break;
|
||||
case SketchPlane::XZ: planeNormal = QVector3D(0, 1, 0); break;
|
||||
case SketchPlane::YZ: planeNormal = QVector3D(1, 0, 0); break;
|
||||
case SketchPlane::NONE: return QVector3D();
|
||||
}
|
||||
|
||||
float denom = QVector3D::dotProduct(planeNormal, rayDir);
|
||||
if (qAbs(denom) > 1e-6) {
|
||||
const auto& planeOriginPnt = plane.Location();
|
||||
QVector3D p0(planeOriginPnt.X(), planeOriginPnt.Y(), planeOriginPnt.Z());
|
||||
QVector3D p0(0,0,0);
|
||||
float t = QVector3D::dotProduct(p0 - rayOrigin, planeNormal) / denom;
|
||||
return rayOrigin + t * rayDir;
|
||||
}
|
||||
@@ -553,11 +538,20 @@ void ViewportWidget::drawSketch(const SketchFeature* sketch)
|
||||
|
||||
const int numSegments = 64;
|
||||
QVector3D u_axis, v_axis;
|
||||
const auto& plane = sketch->plane();
|
||||
const auto& xDir = plane.XDirection();
|
||||
const auto& yDir = plane.YDirection();
|
||||
u_axis = QVector3D(xDir.X(), xDir.Y(), xDir.Z());
|
||||
v_axis = QVector3D(yDir.X(), yDir.Y(), yDir.Z());
|
||||
switch (sketch->plane()) {
|
||||
case SketchFeature::SketchPlane::XY: // Top
|
||||
u_axis = QVector3D(1, 0, 0);
|
||||
v_axis = QVector3D(0, 1, 0);
|
||||
break;
|
||||
case SketchFeature::SketchPlane::XZ: // Front
|
||||
u_axis = QVector3D(1, 0, 0);
|
||||
v_axis = QVector3D(0, 0, 1);
|
||||
break;
|
||||
case SketchFeature::SketchPlane::YZ: // Right
|
||||
u_axis = QVector3D(0, 1, 0);
|
||||
v_axis = QVector3D(0, 0, 1);
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < numSegments; ++i) {
|
||||
double angle1 = 2.0 * M_PI * double(i) / double(numSegments);
|
||||
@@ -571,32 +565,34 @@ void ViewportWidget::drawSketch(const SketchFeature* sketch)
|
||||
}
|
||||
} else if (obj->type() == SketchObject::ObjectType::Rectangle) {
|
||||
auto rect = static_cast<const SketchRectangle*>(obj);
|
||||
const auto& plane = sketch->plane();
|
||||
const auto& p1_3d = rect->corner1();
|
||||
const auto& p3_3d = rect->corner2();
|
||||
const auto& p1 = rect->corner1();
|
||||
const auto& p3 = rect->corner2();
|
||||
|
||||
gp_Pnt2d p1_2d(gp_Vec(plane.Location(), p1_3d).Dot(plane.XDirection()), gp_Vec(plane.Location(), p1_3d).Dot(plane.YDirection()));
|
||||
gp_Pnt2d p3_2d(gp_Vec(plane.Location(), p3_3d).Dot(plane.XDirection()), gp_Vec(plane.Location(), p3_3d).Dot(plane.YDirection()));
|
||||
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 p2_2d(p3_2d.X(), p1_2d.Y());
|
||||
gp_Pnt2d p4_2d(p1_2d.X(), p3_2d.Y());
|
||||
lineVertices << p1.X() << p1.Y() << p1.Z();
|
||||
lineVertices << p2.X() << p2.Y() << p2.Z();
|
||||
lineVertices << p2.X() << p2.Y() << p2.Z();
|
||||
lineVertices << p3.X() << p3.Y() << p3.Z();
|
||||
lineVertices << p3.X() << p3.Y() << p3.Z();
|
||||
lineVertices << p4.X() << p4.Y() << p4.Z();
|
||||
lineVertices << p4.X() << p4.Y() << p4.Z();
|
||||
lineVertices << p1.X() << p1.Y() << p1.Z();
|
||||
|
||||
gp_Pnt p2_3d = ElCLib::To3d(plane, p2_2d);
|
||||
gp_Pnt p4_3d = ElCLib::To3d(plane, p4_2d);
|
||||
|
||||
lineVertices << p1_3d.X() << p1_3d.Y() << p1_3d.Z();
|
||||
lineVertices << p2_3d.X() << p2_3d.Y() << p2_3d.Z();
|
||||
lineVertices << p2_3d.X() << p2_3d.Y() << p2_3d.Z();
|
||||
lineVertices << p3_3d.X() << p3_3d.Y() << p3_3d.Z();
|
||||
lineVertices << p3_3d.X() << p3_3d.Y() << p3_3d.Z();
|
||||
lineVertices << p4_3d.X() << p4_3d.Y() << p4_3d.Z();
|
||||
lineVertices << p4_3d.X() << p4_3d.Y() << p4_3d.Z();
|
||||
lineVertices << p1_3d.X() << p1_3d.Y() << p1_3d.Z();
|
||||
|
||||
vertexCounts[p1_3d] += 2;
|
||||
vertexCounts[p2_3d] += 2;
|
||||
vertexCounts[p3_3d] += 2;
|
||||
vertexCounts[p4_3d] += 2;
|
||||
vertexCounts[p1] += 2;
|
||||
vertexCounts[p2] += 2;
|
||||
vertexCounts[p3] += 2;
|
||||
vertexCounts[p4] += 2;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -715,56 +711,52 @@ void ViewportWidget::drawSelectionPlanes()
|
||||
// XY Plane (Top)
|
||||
QVector<GLfloat> xyQuad = { planeOffset, -planeOffset, 0, planeOffset + planeSize, -planeOffset, 0,
|
||||
planeOffset + planeSize, -planeOffset - planeSize, 0, planeOffset, -planeOffset - planeSize, 0 };
|
||||
drawPlane(xyQuad, m_highlightedPlane && m_highlightedPlane->Direction().IsEqual(gp::DZ(), 1e-9));
|
||||
drawPlane(xyQuad, m_highlightedPlane == SketchPlane::XY);
|
||||
|
||||
// XZ Plane (Front)
|
||||
QVector<GLfloat> xzQuad = { planeOffset, 0, planeOffset, planeOffset + planeSize, 0, planeOffset,
|
||||
planeOffset + planeSize, 0, planeOffset + planeSize, planeOffset, 0, planeOffset + planeSize };
|
||||
drawPlane(xzQuad, m_highlightedPlane && m_highlightedPlane->Direction().IsEqual(gp::DY(), 1e-9));
|
||||
drawPlane(xzQuad, m_highlightedPlane == SketchPlane::XZ);
|
||||
|
||||
// YZ Plane (Right)
|
||||
QVector<GLfloat> yzQuad = { 0, -planeOffset, planeOffset, 0, -planeOffset, planeOffset + planeSize,
|
||||
0, -planeOffset - planeSize, planeOffset + planeSize, 0, -planeOffset - planeSize, planeOffset };
|
||||
drawPlane(yzQuad, m_highlightedPlane && m_highlightedPlane->Direction().IsEqual(gp::DX(), 1e-9));
|
||||
drawPlane(yzQuad, m_highlightedPlane == SketchPlane::YZ);
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
std::optional<gp_Ax2> ViewportWidget::checkPlaneSelection(const QPoint& screenPos)
|
||||
ViewportWidget::SketchPlane ViewportWidget::checkPlaneSelection(const QPoint& screenPos)
|
||||
{
|
||||
const float planeSize = 5.0f;
|
||||
const float planeOffset = 1.0f;
|
||||
|
||||
gp_Ax2 yzPlane(gp_Pnt(0, 0, 0), gp::DX());
|
||||
gp_Ax2 xzPlane(gp_Pnt(0, 0, 0), gp::DY());
|
||||
gp_Ax2 xyPlane(gp_Pnt(0, 0, 0), gp::DZ());
|
||||
|
||||
QVector3D intersection;
|
||||
|
||||
// Check front to back to handle overlaps
|
||||
// YZ plane (Right)
|
||||
intersection = unproject(screenPos, yzPlane);
|
||||
intersection = unproject(screenPos, SketchPlane::YZ);
|
||||
if (intersection.y() >= -planeOffset - planeSize && intersection.y() <= -planeOffset &&
|
||||
intersection.z() >= planeOffset && intersection.z() <= planeOffset + planeSize) {
|
||||
return gp_Ax2(gp_Pnt(0, -planeOffset, planeOffset), gp::DX());
|
||||
return SketchPlane::YZ;
|
||||
}
|
||||
|
||||
// XZ plane (Front)
|
||||
intersection = unproject(screenPos, xzPlane);
|
||||
intersection = unproject(screenPos, SketchPlane::XZ);
|
||||
if (intersection.x() >= planeOffset && intersection.x() <= planeOffset + planeSize &&
|
||||
intersection.z() >= planeOffset && intersection.z() <= planeOffset + planeSize) {
|
||||
return gp_Ax2(gp_Pnt(planeOffset, 0, planeOffset), gp::DY());
|
||||
return SketchPlane::XZ;
|
||||
}
|
||||
|
||||
// XY plane (Top)
|
||||
intersection = unproject(screenPos, xyPlane);
|
||||
intersection = unproject(screenPos, SketchPlane::XY);
|
||||
if (intersection.x() >= planeOffset && intersection.x() <= planeOffset + planeSize &&
|
||||
intersection.y() >= -planeOffset - planeSize && intersection.y() <= -planeOffset) {
|
||||
return gp_Ax2(gp_Pnt(planeOffset, -planeOffset, 0), gp::DZ());
|
||||
return SketchPlane::XY;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
return SketchPlane::NONE;
|
||||
}
|
||||
|
||||
|
||||
+16
-11
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#ifndef VIEWPORTWIDGET_H
|
||||
#define VIEWPORTWIDGET_H
|
||||
@@ -15,8 +15,6 @@
|
||||
#include <QVector3D>
|
||||
#include <QRect>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Ax2.hxx>
|
||||
#include <optional>
|
||||
#include <QMap>
|
||||
#include <QOpenGLShaderProgram>
|
||||
#include <QOpenGLVertexArrayObject>
|
||||
@@ -37,19 +35,26 @@ class ViewportWidget : public QOpenGLWidget, protected QOpenGLFunctions
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum class SketchPlane {
|
||||
NONE,
|
||||
XY,
|
||||
XZ,
|
||||
YZ
|
||||
};
|
||||
|
||||
explicit ViewportWidget(QWidget *parent = nullptr);
|
||||
~ViewportWidget();
|
||||
|
||||
void setDocument(Document* document);
|
||||
|
||||
QVector3D project(const QVector3D& worldCoord, const QMatrix4x4& modelView, const QMatrix4x4& projection, const QRect& viewport);
|
||||
QVector3D unproject(const QPoint& screenPos, const gp_Ax2& plane);
|
||||
QVector3D unproject(const QPoint& screenPos, SketchPlane plane);
|
||||
QOpenGLShaderProgram* shaderProgram() { return m_shaderProgram; }
|
||||
QOpenGLBuffer& vbo() { return m_vbo; }
|
||||
int colorLoc() const { return m_colorLoc; }
|
||||
Camera* camera() const { return m_camera; }
|
||||
Document* document() const { return m_document; }
|
||||
std::optional<gp_Ax2> currentPlane() const { return m_currentPlane; }
|
||||
SketchPlane currentPlane() const { return m_currentPlane; }
|
||||
const QPoint& currentMousePos() const { return m_currentMousePos; }
|
||||
bool isSnappingOrigin() const;
|
||||
bool isSnappingVertex() const;
|
||||
@@ -64,7 +69,7 @@ public:
|
||||
void deactivateActiveTool();
|
||||
|
||||
public slots:
|
||||
void onSketchModeStarted(const gp_Ax2& plane);
|
||||
void onSketchModeStarted(SketchPlane plane);
|
||||
void onSketchModeEnded();
|
||||
void onPlaneSelectionModeStarted();
|
||||
void onActiveToolChanged(int tool);
|
||||
@@ -73,7 +78,7 @@ signals:
|
||||
void lineAdded(const gp_Pnt& start, const gp_Pnt& end);
|
||||
void rectangleAdded(const gp_Pnt& corner1, const gp_Pnt& corner2);
|
||||
void circleAdded(const gp_Pnt& center, double radius);
|
||||
void planeSelected(const gp_Ax2& plane);
|
||||
void planeSelected(SketchPlane plane);
|
||||
void toolDeactivated();
|
||||
|
||||
private slots:
|
||||
@@ -95,7 +100,7 @@ private:
|
||||
void initShaders();
|
||||
void drawSketch(const SketchFeature* sketch);
|
||||
void drawSelectionPlanes();
|
||||
std::optional<gp_Ax2> checkPlaneSelection(const QPoint& screenPos);
|
||||
ViewportWidget::SketchPlane checkPlaneSelection(const QPoint& screenPos);
|
||||
|
||||
QMatrix4x4 projection;
|
||||
QOpenGLShaderProgram* m_shaderProgram = nullptr;
|
||||
@@ -111,10 +116,10 @@ private:
|
||||
SketchGrid* m_sketchGrid = nullptr;
|
||||
FeatureBrowser* m_featureBrowser = nullptr;
|
||||
Document* m_document = nullptr;
|
||||
std::optional<gp_Ax2> m_currentPlane;
|
||||
SketchPlane m_currentPlane = SketchPlane::NONE;
|
||||
|
||||
bool m_isSelectingPlane = false;
|
||||
std::optional<gp_Ax2> m_highlightedPlane;
|
||||
SketchPlane m_highlightedPlane = SketchPlane::NONE;
|
||||
|
||||
int m_activeTool = 0;
|
||||
SketchTool* m_activeSketchTool = nullptr;
|
||||
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
// Unnamed CAD Software
|
||||
//
|
||||
// License: GPLv3 (or later)
|
||||
// License: GPLv3, see LICENSE.txt
|
||||
// Language: C++17
|
||||
// Notes:
|
||||
// - use a right-handed, Z-up coordinate system to match Open CASCADE
|
||||
// - use a right-handed, Z-up coordinate system to match OpenCASCADE
|
||||
|
||||
#include <QApplication>
|
||||
#include "MainWindow.h"
|
||||
|
||||
Reference in New Issue
Block a user