diff --git a/src/ApplicationController.cpp b/src/ApplicationController.cpp index df5d95a..43ae3d9 100644 --- a/src/ApplicationController.cpp +++ b/src/ApplicationController.cpp @@ -3,6 +3,7 @@ #include "SketchFeature.h" #include "SketchLine.h" #include "SketchRectangle.h" +#include "SketchCircle.h" #include "MainWindow.h" #include @@ -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; diff --git a/src/ApplicationController.h b/src/ApplicationController.h index 5ede770..cc9ca80 100644 --- a/src/ApplicationController.h +++ b/src/ApplicationController.h @@ -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(); diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index a2d09b0..b835cb6 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -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); }); diff --git a/src/SketchCircle.cpp b/src/SketchCircle.cpp new file mode 100644 index 0000000..4e94f7b --- /dev/null +++ b/src/SketchCircle.cpp @@ -0,0 +1,56 @@ +#include "SketchCircle.h" +#include + +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; +} diff --git a/src/SketchCircle.h b/src/SketchCircle.h new file mode 100644 index 0000000..04089fe --- /dev/null +++ b/src/SketchCircle.h @@ -0,0 +1,26 @@ +#ifndef SKETCHCIRCLE_H +#define SKETCHCIRCLE_H + +#include "SketchObject.h" +#include + +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 diff --git a/src/SketchObject.h b/src/SketchObject.h index c7a356c..d2346e5 100644 --- a/src/SketchObject.h +++ b/src/SketchObject.h @@ -8,7 +8,8 @@ class SketchObject public: enum class ObjectType { Line, - Rectangle + Rectangle, + Circle }; SketchObject() = default; diff --git a/src/ViewportWidget.cpp b/src/ViewportWidget.cpp index 2170beb..734289e 100644 --- a/src/ViewportWidget.cpp +++ b/src/ViewportWidget.cpp @@ -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 #include #include @@ -61,6 +63,7 @@ ViewportWidget::ViewportWidget(QWidget *parent) m_sketchTools.insert(static_cast(ApplicationController::ToolType::Line), new LineTool(this)); m_sketchTools.insert(static_cast(ApplicationController::ToolType::Rectangle), new RectangleTool(this)); + m_sketchTools.insert(static_cast(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(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(obj); const auto& p1 = rect->corner1(); diff --git a/src/ViewportWidget.h b/src/ViewportWidget.h index e67c0c8..2b2420d 100644 --- a/src/ViewportWidget.h +++ b/src/ViewportWidget.h @@ -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();