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 "SketchLine.h"
|
||||
#include "SketchRectangle.h"
|
||||
#include "SketchCircle.h"
|
||||
#include "MainWindow.h"
|
||||
|
||||
#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()
|
||||
{
|
||||
m_activeSketch = nullptr;
|
||||
|
||||
@@ -33,6 +33,7 @@ public slots:
|
||||
void setActiveTool(ToolType tool);
|
||||
void addLine(const gp_Pnt& start, const gp_Pnt& end);
|
||||
void addRectangle(const gp_Pnt& corner1, const gp_Pnt& corner2);
|
||||
void addCircle(const gp_Pnt& center, double radius);
|
||||
void newDocument();
|
||||
bool openDocument();
|
||||
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::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::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:
|
||||
enum class ObjectType {
|
||||
Line,
|
||||
Rectangle
|
||||
Rectangle,
|
||||
Circle
|
||||
};
|
||||
|
||||
SketchObject() = default;
|
||||
|
||||
@@ -8,10 +8,12 @@
|
||||
#include "SketchFeature.h"
|
||||
#include "SketchLine.h"
|
||||
#include "SketchRectangle.h"
|
||||
#include "SketchCircle.h"
|
||||
#include "SketchObject.h"
|
||||
#include "ApplicationController.h"
|
||||
#include "RectangleTool.h"
|
||||
#include "LineTool.h"
|
||||
#include "CircleTool.h"
|
||||
#include <QMouseEvent>
|
||||
#include <QKeyEvent>
|
||||
#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::Rectangle), new RectangleTool(this));
|
||||
m_sketchTools.insert(static_cast<int>(ApplicationController::ToolType::Circle), new CircleTool(this));
|
||||
|
||||
m_snapping = new Snapping(this);
|
||||
}
|
||||
@@ -511,6 +514,39 @@ void ViewportWidget::drawSketch(const SketchFeature* sketch)
|
||||
|
||||
vertexCounts[start]++;
|
||||
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) {
|
||||
auto rect = static_cast<const SketchRectangle*>(obj);
|
||||
const auto& p1 = rect->corner1();
|
||||
|
||||
@@ -70,6 +70,7 @@ public slots:
|
||||
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(SketchPlane plane);
|
||||
void toolDeactivated();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user