feat: Implement circle drawing tool
Co-authored-by: aider (gemini/gemini-2.5-pro) <aider@aider.chat>
This commit is contained in:
@@ -3,6 +3,7 @@
|
|||||||
#include "SketchFeature.h"
|
#include "SketchFeature.h"
|
||||||
#include "SketchLine.h"
|
#include "SketchLine.h"
|
||||||
#include "SketchRectangle.h"
|
#include "SketchRectangle.h"
|
||||||
|
#include "SketchCircle.h"
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
|
|
||||||
#include <QInputDialog>
|
#include <QInputDialog>
|
||||||
@@ -148,6 +149,13 @@ void ApplicationController::addRectangle(const gp_Pnt& corner1, const gp_Pnt& co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApplicationController::addCircle(const gp_Pnt& center, double radius)
|
||||||
|
{
|
||||||
|
if (m_activeSketch) {
|
||||||
|
m_activeSketch->addObject(new SketchCircle(center, radius));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ApplicationController::endSketch()
|
void ApplicationController::endSketch()
|
||||||
{
|
{
|
||||||
m_activeSketch = nullptr;
|
m_activeSketch = nullptr;
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ public slots:
|
|||||||
void setActiveTool(ToolType tool);
|
void setActiveTool(ToolType tool);
|
||||||
void addLine(const gp_Pnt& start, const gp_Pnt& end);
|
void addLine(const gp_Pnt& start, const gp_Pnt& end);
|
||||||
void addRectangle(const gp_Pnt& corner1, const gp_Pnt& corner2);
|
void addRectangle(const gp_Pnt& corner1, const gp_Pnt& corner2);
|
||||||
|
void addCircle(const gp_Pnt& center, double radius);
|
||||||
void newDocument();
|
void newDocument();
|
||||||
bool openDocument();
|
bool openDocument();
|
||||||
bool saveDocument();
|
bool saveDocument();
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ MainWindow::MainWindow(ApplicationController* appController, QWidget *parent)
|
|||||||
|
|
||||||
connect(m_viewport, &ViewportWidget::lineAdded, m_appController, &ApplicationController::addLine);
|
connect(m_viewport, &ViewportWidget::lineAdded, m_appController, &ApplicationController::addLine);
|
||||||
connect(m_viewport, &ViewportWidget::rectangleAdded, m_appController, &ApplicationController::addRectangle);
|
connect(m_viewport, &ViewportWidget::rectangleAdded, m_appController, &ApplicationController::addRectangle);
|
||||||
|
connect(m_viewport, &ViewportWidget::circleAdded, m_appController, &ApplicationController::addCircle);
|
||||||
connect(m_viewport, &ViewportWidget::planeSelected, m_appController, &ApplicationController::onPlaneSelected);
|
connect(m_viewport, &ViewportWidget::planeSelected, m_appController, &ApplicationController::onPlaneSelected);
|
||||||
connect(m_viewport, &ViewportWidget::toolDeactivated, m_appController, [this]() { m_appController->setActiveTool(ApplicationController::ToolType::None); });
|
connect(m_viewport, &ViewportWidget::toolDeactivated, m_appController, [this]() { m_appController->setActiveTool(ApplicationController::ToolType::None); });
|
||||||
|
|
||||||
|
|||||||
56
src/SketchCircle.cpp
Normal file
56
src/SketchCircle.cpp
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#include "SketchCircle.h"
|
||||||
|
#include <QJsonArray>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
void pointToJson(const gp_Pnt& p, QJsonArray& arr)
|
||||||
|
{
|
||||||
|
arr.append(p.X());
|
||||||
|
arr.append(p.Y());
|
||||||
|
arr.append(p.Z());
|
||||||
|
}
|
||||||
|
|
||||||
|
gp_Pnt jsonToPoint(const QJsonArray& arr)
|
||||||
|
{
|
||||||
|
return gp_Pnt(arr[0].toDouble(), arr[1].toDouble(), arr[2].toDouble());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SketchCircle::SketchCircle() : m_radius(0.0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SketchCircle::SketchCircle(const gp_Pnt& center, double radius)
|
||||||
|
: m_center(center), m_radius(radius)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SketchObject::ObjectType SketchCircle::type() const
|
||||||
|
{
|
||||||
|
return ObjectType::Circle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SketchCircle::read(const QJsonObject& json)
|
||||||
|
{
|
||||||
|
m_center = jsonToPoint(json["center"].toArray());
|
||||||
|
m_radius = json["radius"].toDouble();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SketchCircle::write(QJsonObject& json) const
|
||||||
|
{
|
||||||
|
QJsonArray centerArr;
|
||||||
|
pointToJson(m_center, centerArr);
|
||||||
|
json["center"] = centerArr;
|
||||||
|
json["radius"] = m_radius;
|
||||||
|
json["type"] = "Circle";
|
||||||
|
}
|
||||||
|
|
||||||
|
const gp_Pnt& SketchCircle::center() const
|
||||||
|
{
|
||||||
|
return m_center;
|
||||||
|
}
|
||||||
|
|
||||||
|
double SketchCircle::radius() const
|
||||||
|
{
|
||||||
|
return m_radius;
|
||||||
|
}
|
||||||
26
src/SketchCircle.h
Normal file
26
src/SketchCircle.h
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#ifndef SKETCHCIRCLE_H
|
||||||
|
#define SKETCHCIRCLE_H
|
||||||
|
|
||||||
|
#include "SketchObject.h"
|
||||||
|
#include <gp_Pnt.hxx>
|
||||||
|
|
||||||
|
class SketchCircle : public SketchObject
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SketchCircle();
|
||||||
|
SketchCircle(const gp_Pnt& center, double radius);
|
||||||
|
|
||||||
|
ObjectType type() const override;
|
||||||
|
|
||||||
|
void read(const QJsonObject& json) override;
|
||||||
|
void write(QJsonObject& json) const override;
|
||||||
|
|
||||||
|
const gp_Pnt& center() const;
|
||||||
|
double radius() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
gp_Pnt m_center;
|
||||||
|
double m_radius;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // SKETCHCIRCLE_H
|
||||||
@@ -8,7 +8,8 @@ class SketchObject
|
|||||||
public:
|
public:
|
||||||
enum class ObjectType {
|
enum class ObjectType {
|
||||||
Line,
|
Line,
|
||||||
Rectangle
|
Rectangle,
|
||||||
|
Circle
|
||||||
};
|
};
|
||||||
|
|
||||||
SketchObject() = default;
|
SketchObject() = default;
|
||||||
|
|||||||
@@ -8,10 +8,12 @@
|
|||||||
#include "SketchFeature.h"
|
#include "SketchFeature.h"
|
||||||
#include "SketchLine.h"
|
#include "SketchLine.h"
|
||||||
#include "SketchRectangle.h"
|
#include "SketchRectangle.h"
|
||||||
|
#include "SketchCircle.h"
|
||||||
#include "SketchObject.h"
|
#include "SketchObject.h"
|
||||||
#include "ApplicationController.h"
|
#include "ApplicationController.h"
|
||||||
#include "RectangleTool.h"
|
#include "RectangleTool.h"
|
||||||
#include "LineTool.h"
|
#include "LineTool.h"
|
||||||
|
#include "CircleTool.h"
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QWheelEvent>
|
#include <QWheelEvent>
|
||||||
@@ -61,6 +63,7 @@ ViewportWidget::ViewportWidget(QWidget *parent)
|
|||||||
|
|
||||||
m_sketchTools.insert(static_cast<int>(ApplicationController::ToolType::Line), new LineTool(this));
|
m_sketchTools.insert(static_cast<int>(ApplicationController::ToolType::Line), new LineTool(this));
|
||||||
m_sketchTools.insert(static_cast<int>(ApplicationController::ToolType::Rectangle), new RectangleTool(this));
|
m_sketchTools.insert(static_cast<int>(ApplicationController::ToolType::Rectangle), new RectangleTool(this));
|
||||||
|
m_sketchTools.insert(static_cast<int>(ApplicationController::ToolType::Circle), new CircleTool(this));
|
||||||
|
|
||||||
m_snapping = new Snapping(this);
|
m_snapping = new Snapping(this);
|
||||||
}
|
}
|
||||||
@@ -511,6 +514,39 @@ void ViewportWidget::drawSketch(const SketchFeature* sketch)
|
|||||||
|
|
||||||
vertexCounts[start]++;
|
vertexCounts[start]++;
|
||||||
vertexCounts[end]++;
|
vertexCounts[end]++;
|
||||||
|
} else if (obj->type() == SketchObject::ObjectType::Circle) {
|
||||||
|
auto circle = static_cast<const SketchCircle*>(obj);
|
||||||
|
const auto& center = circle->center();
|
||||||
|
double radius = circle->radius();
|
||||||
|
QVector3D centerPos(center.X(), center.Y(), center.Z());
|
||||||
|
|
||||||
|
const int numSegments = 64;
|
||||||
|
QVector3D u_axis, v_axis;
|
||||||
|
switch (sketch->plane()) {
|
||||||
|
case SketchFeature::SketchPlane::XY:
|
||||||
|
u_axis = QVector3D(1, 0, 0);
|
||||||
|
v_axis = QVector3D(0, 1, 0);
|
||||||
|
break;
|
||||||
|
case SketchFeature::SketchPlane::XZ:
|
||||||
|
u_axis = QVector3D(1, 0, 0);
|
||||||
|
v_axis = QVector3D(0, 0, 1);
|
||||||
|
break;
|
||||||
|
case SketchFeature::SketchPlane::YZ:
|
||||||
|
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);
|
||||||
|
QVector3D p1 = centerPos + radius * (cos(angle1) * u_axis + sin(angle1) * v_axis);
|
||||||
|
|
||||||
|
double angle2 = 2.0 * M_PI * double(i + 1) / double(numSegments);
|
||||||
|
QVector3D p2 = centerPos + radius * (cos(angle2) * u_axis + sin(angle2) * v_axis);
|
||||||
|
|
||||||
|
lineVertices << p1.x() << p1.y() << p1.z();
|
||||||
|
lineVertices << p2.x() << p2.y() << p2.z();
|
||||||
|
}
|
||||||
} else if (obj->type() == SketchObject::ObjectType::Rectangle) {
|
} else if (obj->type() == SketchObject::ObjectType::Rectangle) {
|
||||||
auto rect = static_cast<const SketchRectangle*>(obj);
|
auto rect = static_cast<const SketchRectangle*>(obj);
|
||||||
const auto& p1 = rect->corner1();
|
const auto& p1 = rect->corner1();
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ public slots:
|
|||||||
signals:
|
signals:
|
||||||
void lineAdded(const gp_Pnt& start, const gp_Pnt& end);
|
void lineAdded(const gp_Pnt& start, const gp_Pnt& end);
|
||||||
void rectangleAdded(const gp_Pnt& corner1, const gp_Pnt& corner2);
|
void rectangleAdded(const gp_Pnt& corner1, const gp_Pnt& corner2);
|
||||||
|
void circleAdded(const gp_Pnt& center, double radius);
|
||||||
void planeSelected(SketchPlane plane);
|
void planeSelected(SketchPlane plane);
|
||||||
void toolDeactivated();
|
void toolDeactivated();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user