From a1cfbc2e3f3f5a9e334f5a410a3e3a410124edd6 Mon Sep 17 00:00:00 2001 From: Tanner Collin Date: Sat, 14 Feb 2026 19:12:59 -0700 Subject: [PATCH] feat: Implement sketch object base class and line geometry Co-authored-by: aider (gemini/gemini-2.5-pro) --- CMakeLists.txt | 1 + src/SketchFeature.cpp | 44 ++++++++++++++++++++++++++++++++ src/SketchFeature.h | 8 ++++++ src/SketchLine.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++ src/SketchLine.h | 26 +++++++++++++++++++ src/SketchObject.h | 22 ++++++++++++++++ 6 files changed, 159 insertions(+) create mode 100644 src/SketchLine.cpp create mode 100644 src/SketchLine.h create mode 100644 src/SketchObject.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4376185..4534856 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,6 +37,7 @@ add_executable(OpenCAD src/Document.cpp src/Feature.cpp src/SketchFeature.cpp + src/SketchLine.cpp src/FeatureBrowser.cpp src/ApplicationController.cpp resources.qrc diff --git a/src/SketchFeature.cpp b/src/SketchFeature.cpp index c664988..51d2c96 100644 --- a/src/SketchFeature.cpp +++ b/src/SketchFeature.cpp @@ -1,10 +1,19 @@ #include "SketchFeature.h" +#include "SketchObject.h" +#include "SketchLine.h" + +#include SketchFeature::SketchFeature(const QString& name) : Feature(name) { } +SketchFeature::~SketchFeature() +{ + qDeleteAll(m_objects); +} + QString SketchFeature::type() const { return "Sketch"; @@ -25,6 +34,16 @@ const TopoDS_Shape& SketchFeature::shape() const return m_shape; } +void SketchFeature::addObject(SketchObject* object) +{ + m_objects.append(object); +} + +const QList& SketchFeature::objects() const +{ + return m_objects; +} + void SketchFeature::read(const QJsonObject& json) { Feature::read(json); @@ -34,6 +53,23 @@ void SketchFeature::read(const QJsonObject& json) else if (planeStr == "XZ") m_plane = SketchPlane::XZ; else if (planeStr == "YZ") m_plane = SketchPlane::YZ; } + + if (json.contains("objects") && json["objects"].isArray()) { + QJsonArray objectsArray = json["objects"].toArray(); + qDeleteAll(m_objects); + m_objects.clear(); + for (const QJsonValue& value : objectsArray) { + QJsonObject objectJson = value.toObject(); + if (objectJson.contains("type") && objectJson["type"].isString()) { + QString type = objectJson["type"].toString(); + if (type == "Line") { + auto line = new SketchLine(); + line->read(objectJson); + m_objects.append(line); + } + } + } + } } void SketchFeature::write(QJsonObject& json) const @@ -46,4 +82,12 @@ void SketchFeature::write(QJsonObject& json) const case SketchPlane::YZ: planeStr = "YZ"; break; } json["plane"] = planeStr; + + QJsonArray objectsArray; + for (const auto& object : m_objects) { + QJsonObject objectJson; + object->write(objectJson); + objectsArray.append(objectJson); + } + json["objects"] = objectsArray; } diff --git a/src/SketchFeature.h b/src/SketchFeature.h index 4e32f79..7af7e29 100644 --- a/src/SketchFeature.h +++ b/src/SketchFeature.h @@ -2,8 +2,11 @@ #define SKETCHFEATURE_H #include +#include #include "Feature.h" +class SketchObject; + class SketchFeature : public Feature { public: @@ -14,6 +17,7 @@ public: }; SketchFeature(const QString& name); + ~SketchFeature(); QString type() const override; @@ -22,12 +26,16 @@ public: const TopoDS_Shape& shape() const; + void addObject(SketchObject* object); + const QList& objects() const; + void read(const QJsonObject &json) override; void write(QJsonObject &json) const override; private: SketchPlane m_plane; TopoDS_Shape m_shape; + QList m_objects; }; #endif // SKETCHFEATURE_H diff --git a/src/SketchLine.cpp b/src/SketchLine.cpp new file mode 100644 index 0000000..70f982e --- /dev/null +++ b/src/SketchLine.cpp @@ -0,0 +1,58 @@ +#include "SketchLine.h" +#include + +SketchLine::SketchLine() +{ +} + +SketchLine::SketchLine(const gp_Pnt& start, const gp_Pnt& end) + : m_start(start), m_end(end) +{ +} + +SketchObject::ObjectType SketchLine::type() const +{ + return ObjectType::Line; +} + +void SketchLine::read(const QJsonObject& json) +{ + if (json.contains("start") && json["start"].isObject() && + json.contains("end") && json["end"].isObject()) { + QJsonObject startObj = json["start"].toObject(); + QJsonObject endObj = json["end"].toObject(); + m_start.SetX(startObj["x"].toDouble()); + m_start.SetY(startObj["y"].toDouble()); + m_start.SetZ(startObj["z"].toDouble()); + m_end.SetX(endObj["x"].toDouble()); + m_end.SetY(endObj["y"].toDouble()); + m_end.SetZ(endObj["z"].toDouble()); + } +} + +void SketchLine::write(QJsonObject& json) const +{ + QJsonObject startObj; + startObj["x"] = m_start.X(); + startObj["y"] = m_start.Y(); + startObj["z"] = m_start.Z(); + + QJsonObject endObj; + endObj["x"] = m_end.X(); + endObj["y"] = m_end.Y(); + endObj["z"] = m_end.Z(); + + json["type"] = "Line"; + json["start"] = startObj; + json["end"] = endObj; +} + +const gp_Pnt& SketchLine::startPoint() const +{ + return m_start; +} + +const gp_Pnt& SketchLine::endPoint() const +{ + return m_end; +} diff --git a/src/SketchLine.h b/src/SketchLine.h new file mode 100644 index 0000000..dab72aa --- /dev/null +++ b/src/SketchLine.h @@ -0,0 +1,26 @@ +#ifndef SKETCHLINE_H +#define SKETCHLINE_H + +#include "SketchObject.h" +#include + +class SketchLine : public SketchObject +{ +public: + SketchLine(); + SketchLine(const gp_Pnt& start, const gp_Pnt& end); + + ObjectType type() const override; + + void read(const QJsonObject& json) override; + void write(QJsonObject& json) const override; + + const gp_Pnt& startPoint() const; + const gp_Pnt& endPoint() const; + +private: + gp_Pnt m_start; + gp_Pnt m_end; +}; + +#endif // SKETCHLINE_H diff --git a/src/SketchObject.h b/src/SketchObject.h new file mode 100644 index 0000000..363c070 --- /dev/null +++ b/src/SketchObject.h @@ -0,0 +1,22 @@ +#ifndef SKETCHOBJECT_H +#define SKETCHOBJECT_H + +#include + +class SketchObject +{ +public: + enum class ObjectType { + Line + }; + + SketchObject() = default; + virtual ~SketchObject() = default; + + virtual ObjectType type() const = 0; + + virtual void read(const QJsonObject& json) = 0; + virtual void write(QJsonObject& json) const = 0; +}; + +#endif // SKETCHOBJECT_H