核心架构解析
第十一章 核心架构解析
11.1 架构概述
11.1.1 整体架构
LibreCAD采用模块化的面向对象架构,基于Qt框架构建。其架构遵循类似MVC(Model-View-Controller)的设计模式。
┌──────────────────────────────────────────────────────────────┐
│ 用户界面层 (UI Layer) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ QC_Application │ │ Dialogs │ │ Dock Widgets │ │
│ │ Window │ │ │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
├──────────────────────────────────────────────────────────────┤
│ 动作层 (Action Layer) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │RS_ActionInterface│ │ Drawing │ │ Modification │ │
│ │ │ │ Actions │ │ Actions │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
├──────────────────────────────────────────────────────────────┤
│ 核心库层 (Core Library) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ RS_Entity │ │ RS_Graphic │ │ RS_GraphicView │ │
│ │ System │ │ │ │ │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
├──────────────────────────────────────────────────────────────┤
│ 数据层 (Data Layer) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ libdxfrw │ │ File I/O │ │ Filters │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
11.1.2 主要模块
| 模块 | 路径 | 功能 |
|---|---|---|
| main | librecad/src/main | 程序入口 |
| lib/engine | librecad/src/lib/engine | 图形引擎核心 |
| lib/gui | librecad/src/lib/gui | GUI组件 |
| lib/actions | librecad/src/lib/actions | 动作基类 |
| lib/creation | librecad/src/lib/creation | 图形创建 |
| lib/modification | librecad/src/lib/modification | 图形修改 |
| lib/information | librecad/src/lib/information | 信息查询 |
| lib/math | librecad/src/lib/math | 数学计算 |
| lib/filters | librecad/src/lib/filters | 文件过滤器 |
| actions | librecad/src/actions | 具体动作实现 |
| ui | librecad/src/ui | 用户界面 |
| plugins | librecad/src/plugins | 插件接口 |
11.1.3 技术栈
技术栈
├── 编程语言:C++17
├── GUI框架:Qt 6.x
├── 构建系统:CMake / qmake
├── 数学库:Boost
├── 文件I/O:libdxfrw
├── 表达式解析:muParser
└── 字体渲染:FreeType
11.2 实体系统
11.2.1 RS_Entity基类
所有图形实体的基类:
class RS_Entity {
public:
// 构造和析构
RS_Entity(RS_EntityContainer* parent = nullptr);
virtual ~RS_Entity();
// 实体类型
virtual RS2::EntityType rtti() const = 0;
// 绘制
virtual void draw(RS_Painter* painter,
RS_GraphicView* view,
double& patternOffset) = 0;
// 几何操作
virtual RS_Vector getNearestPointOnEntity(
const RS_Vector& coord,
bool onEntity = true,
double* dist = nullptr,
RS_Entity** entity = nullptr
) const;
virtual double getDistanceToPoint(
const RS_Vector& coord,
RS_Entity** entity = nullptr,
RS2::ResolveLevel level = RS2::ResolveNone,
double solidDist = RS_MAXDOUBLE
) const;
// 边界
virtual RS_Vector getMin() const;
virtual RS_Vector getMax() const;
// 变换
virtual void move(const RS_Vector& offset);
virtual void rotate(const RS_Vector& center, double angle);
virtual void scale(const RS_Vector& center, const RS_Vector& factor);
virtual void mirror(const RS_Vector& axisPoint1,
const RS_Vector& axisPoint2);
// 属性
RS_Layer* getLayer() const;
void setLayer(RS_Layer* layer);
RS_Pen getPen() const;
void setPen(const RS_Pen& pen);
protected:
RS_EntityContainer* parent;
RS_Pen pen;
RS_Layer* layer;
bool visible;
bool selected;
};
11.2.2 实体类型枚举
namespace RS2 {
enum EntityType {
EntityUnknown,
EntityContainer,
EntityBlock,
EntityFontChar,
EntityInsert,
EntityGraphic,
EntityPoint,
EntityLine,
EntityPolyline,
EntityVertex,
EntityArc,
EntityCircle,
EntityEllipse,
EntityHyperbola,
EntitySolid,
EntityImage,
EntitySpline,
EntitySplinePoints,
EntityHatch,
EntityText,
EntityMText,
EntityDimLinear,
EntityDimAligned,
EntityDimRadial,
EntityDimDiametric,
EntityDimAngular,
EntityDimLeader,
EntityOverlay
};
}
11.2.3 实体继承层次
RS_Entity
├── RS_Point # 点
├── RS_Line # 直线
├── RS_Circle # 圆
├── RS_Arc # 圆弧
├── RS_Ellipse # 椭圆
├── RS_Spline # 样条曲线
├── RS_Text # 单行文字
├── RS_MText # 多行文字
├── RS_Hatch # 填充
├── RS_Image # 图像
├── RS_Dimension # 尺寸标注基类
│ ├── RS_DimLinear # 线性标注
│ ├── RS_DimAligned # 对齐标注
│ ├── RS_DimRadial # 半径标注
│ ├── RS_DimDiametric# 直径标注
│ ├── RS_DimAngular # 角度标注
│ └── RS_DimLeader # 引线标注
└── RS_EntityContainer # 实体容器
├── RS_Polyline # 折线
├── RS_Block # 块定义
├── RS_Insert # 块引用
└── RS_Graphic # 图形文档
11.3 图形视图系统
11.3.1 RS_GraphicView
负责图形的渲染和用户交互:
class RS_GraphicView : public QWidget {
public:
RS_GraphicView(QWidget* parent = nullptr);
virtual ~RS_GraphicView();
// 设置图形数据
void setContainer(RS_EntityContainer* container);
RS_EntityContainer* getContainer() const;
// 视图变换
void zoomIn(double f = 1.5, const RS_Vector& center = RS_Vector(false));
void zoomOut(double f = 1.5, const RS_Vector& center = RS_Vector(false));
void zoomWindow(const RS_Vector& v1, const RS_Vector& v2);
void zoomAuto(bool axis = true, bool keepAspectRatio = true);
void zoomPan(int dx, int dy);
// 坐标转换
RS_Vector toGui(const RS_Vector& v) const;
RS_Vector toGraph(const RS_Vector& v) const;
double toGuiX(double x) const;
double toGuiY(double y) const;
double toGraphX(double x) const;
double toGraphY(double y) const;
// 绘制
virtual void drawEntity(RS_Entity* e);
virtual void drawLayer(RS_Layer* layer);
void redraw(RS2::RedrawMethod method = RS2::RedrawAll);
// 事件处理器
void setEventHandler(RS_EventHandler* handler);
protected:
void paintEvent(QPaintEvent* e) override;
void mousePressEvent(QMouseEvent* e) override;
void mouseReleaseEvent(QMouseEvent* e) override;
void mouseMoveEvent(QMouseEvent* e) override;
void wheelEvent(QWheelEvent* e) override;
void keyPressEvent(QKeyEvent* e) override;
private:
RS_EntityContainer* container;
RS_EventHandler* eventHandler;
double factor; // 缩放因子
int offsetX, offsetY; // 视图偏移
};
11.3.2 坐标系统
图形坐标系 (Graph Coordinates)
↑ Y+
│
│
─────┼─────→ X+
│
│
界面坐标系 (GUI Coordinates)
─────┬─────→ X+
│
│
↓ Y+
转换公式:
guiX = (graphX + offsetX) * factor
guiY = -(graphY + offsetY) * factor + height
11.3.3 视图变换矩阵
// 图形坐标到屏幕坐标
RS_Vector RS_GraphicView::toGui(const RS_Vector& v) const {
return RS_Vector(
toGuiX(v.x),
toGuiY(v.y)
);
}
double RS_GraphicView::toGuiX(double x) const {
return (x + offsetX) * factor;
}
double RS_GraphicView::toGuiY(double y) const {
return -(y + offsetY) * factor + getHeight();
}
// 屏幕坐标到图形坐标
RS_Vector RS_GraphicView::toGraph(const RS_Vector& v) const {
return RS_Vector(
toGraphX(v.x),
toGraphY(v.y)
);
}
11.4 动作系统
11.4.1 RS_ActionInterface
所有动作的基类:
class RS_ActionInterface : public QObject {
Q_OBJECT
public:
RS_ActionInterface(const char* name,
RS_EntityContainer& container,
RS_GraphicView& graphicView);
virtual ~RS_ActionInterface();
// 动作生命周期
virtual void init(int status = 0);
virtual void finish(bool updateTB = true);
virtual void suspend();
virtual void resume();
// 事件处理
virtual void mouseReleaseEvent(QMouseEvent* e);
virtual void mouseMoveEvent(QMouseEvent* e);
virtual void mousePressEvent(QMouseEvent* e);
virtual void keyPressEvent(QKeyEvent* e);
virtual void coordinateEvent(RS_CoordinateEvent* e);
virtual void commandEvent(RS_CommandEvent* e);
// 状态管理
int getStatus() const;
void setStatus(int status);
// 工具提示
virtual void updateMouseButtonHints();
virtual void updateToolBar();
protected:
RS_EntityContainer* container;
RS_GraphicView* graphicView;
RS_Document* document;
int status;
};
11.4.2 动作状态机
动作使用状态机模式管理用户交互:
// 画线动作的状态定义
enum Status {
SetStartPoint, // 等待起点
SetEndPoint, // 等待终点
SetNextPoint // 等待下一点
};
// 状态转换示例
void RS_ActionDrawLine::mouseReleaseEvent(QMouseEvent* e) {
switch (getStatus()) {
case SetStartPoint:
// 保存起点
startPoint = snapPoint(e);
setStatus(SetEndPoint);
break;
case SetEndPoint:
// 创建线段
endPoint = snapPoint(e);
createLine();
// 准备下一条线
startPoint = endPoint;
setStatus(SetNextPoint);
break;
case SetNextPoint:
// 继续画线
endPoint = snapPoint(e);
createLine();
startPoint = endPoint;
break;
}
}
11.4.3 动作分类
librecad/src/actions/
├── drawing/ # 绘图动作
│ ├── RS_ActionDrawLine
│ ├── RS_ActionDrawCircle
│ ├── RS_ActionDrawArc
│ ├── RS_ActionDrawEllipse
│ ├── RS_ActionDrawSpline
│ ├── RS_ActionDrawPolyline
│ ├── RS_ActionDrawText
│ └── RS_ActionDrawHatch
├── file/ # 文件动作
│ ├── RS_ActionFileNew
│ ├── RS_ActionFileOpen
│ └── RS_ActionFileSave
├── dock_widgets/ # 停靠窗口动作
├── options/ # 选项动作
└── print_preview/ # 打印预览动作
11.5 命令系统
11.5.1 RS_Commands
命令处理核心类:
class RS_Commands {
public:
// 注册命令
static void addCommand(const QString& cmd, RS2::ActionType action);
// 查找命令
static RS2::ActionType getAction(const QString& cmd);
// 命令别名
static void addAlias(const QString& alias, const QString& cmd);
// 命令列表
static QStringList getCommands();
private:
static QHash<QString, RS2::ActionType> commands;
static QHash<QString, QString> aliases;
};
11.5.2 命令注册
// 注册命令示例
void RS_Commands::initCommands() {
// 绘图命令
addCommand("line", RS2::ActionDrawLine);
addCommand("circle", RS2::ActionDrawCircle);
addCommand("arc", RS2::ActionDrawArc);
addCommand("ellipse", RS2::ActionDrawEllipse);
addCommand("polyline", RS2::ActionDrawPolyline);
addCommand("text", RS2::ActionDrawText);
// 修改命令
addCommand("move", RS2::ActionModifyMove);
addCommand("copy", RS2::ActionModifyCopy);
addCommand("rotate", RS2::ActionModifyRotate);
addCommand("scale", RS2::ActionModifyScale);
addCommand("mirror", RS2::ActionModifyMirror);
// 别名
addAlias("l", "line");
addAlias("c", "circle");
addAlias("a", "arc");
addAlias("pl", "polyline");
addAlias("m", "move");
addAlias("co", "copy");
}
11.6 事件处理系统
11.6.1 RS_EventHandler
事件分发器:
class RS_EventHandler {
public:
RS_EventHandler();
virtual ~RS_EventHandler();
// 设置当前动作
void setCurrentAction(RS_ActionInterface* action);
RS_ActionInterface* getCurrentAction() const;
// 默认动作
void setDefaultAction(RS_ActionInterface* action);
// 事件分发
void mouseReleaseEvent(QMouseEvent* e);
void mouseMoveEvent(QMouseEvent* e);
void mousePressEvent(QMouseEvent* e);
void keyPressEvent(QKeyEvent* e);
void coordinateEvent(RS_CoordinateEvent* e);
void commandEvent(RS_CommandEvent* e);
// 动作栈管理
void back();
bool hasAction() const;
private:
RS_ActionInterface* defaultAction;
QStack<RS_ActionInterface*> actionStack;
};
11.6.2 自定义事件
// 坐标事件
class RS_CoordinateEvent : public QEvent {
public:
RS_CoordinateEvent(const RS_Vector& pos);
RS_Vector getCoordinate() const;
private:
RS_Vector pos;
};
// 命令事件
class RS_CommandEvent : public QEvent {
public:
RS_CommandEvent(const QString& cmd);
QString getCommand() const;
void accept();
void ignore();
bool isAccepted() const;
private:
QString cmd;
bool accepted;
};
11.7 对象捕捉系统
11.7.1 RS_Snapper
对象捕捉核心类:
class RS_Snapper {
public:
RS_Snapper(RS_EntityContainer& container,
RS_GraphicView& graphicView);
// 捕捉点计算
RS_Vector snapPoint(QMouseEvent* e);
RS_Vector snapFree(QMouseEvent* e);
RS_Vector snapGrid(const RS_Vector& coord);
// 捕捉模式
void setSnapMode(RS_SnapMode mode);
RS_SnapMode getSnapMode() const;
// 具体捕捉
RS_Vector snapEndpoint(const RS_Vector& coord);
RS_Vector snapMiddle(const RS_Vector& coord);
RS_Vector snapCenter(const RS_Vector& coord);
RS_Vector snapIntersection(const RS_Vector& coord);
RS_Vector snapOnEntity(const RS_Vector& coord);
// 捕捉范围
void setSnapRange(int range);
protected:
RS_EntityContainer* container;
RS_GraphicView* graphicView;
RS_SnapMode snapMode;
int snapRange;
};
11.7.2 捕捉模式
class RS_SnapMode {
public:
bool snapEndpoint; // 端点
bool snapMiddle; // 中点
bool snapCenter; // 圆心
bool snapIntersection; // 交点
bool snapOnEntity; // 最近点
bool snapDist; // 距离
bool snapGrid; // 网格
bool snapFree; // 自由
// 限制
bool restriction; // 启用限制
RS2::SnapRestriction restrictionType;
};
11.8 图层系统
11.8.1 RS_Layer
图层类定义:
class RS_Layer {
public:
RS_Layer(const QString& name);
// 名称
QString getName() const;
void setName(const QString& name);
// 可见性
bool isFrozen() const;
void freeze(bool on);
// 锁定
bool isLocked() const;
void lock(bool on);
// 打印
bool isPrint() const;
void setPrint(bool on);
// 画笔(颜色、线型、线宽)
RS_Pen getPen() const;
void setPen(const RS_Pen& pen);
private:
QString name;
RS_Pen pen;
bool frozen;
bool locked;
bool print;
};
11.8.2 RS_LayerList
图层列表管理:
class RS_LayerList {
public:
RS_LayerList();
~RS_LayerList();
// 图层操作
void add(RS_Layer* layer);
void remove(RS_Layer* layer);
RS_Layer* find(const QString& name);
// 迭代器
int count() const;
RS_Layer* at(int i) const;
// 当前图层
void activate(RS_Layer* layer);
RS_Layer* getActive() const;
// 信号
void layerActivated(RS_Layer*);
void layerAdded(RS_Layer*);
void layerRemoved(RS_Layer*);
private:
QList<RS_Layer*> layers;
RS_Layer* activeLayer;
};
11.9 文件I/O系统
11.9.1 RS_FileIO
文件操作抽象类:
class RS_FileIO {
public:
// 导入
static bool fileImport(RS_Graphic& g,
const QString& file,
RS2::FormatType type = RS2::FormatUnknown);
// 导出
static bool fileExport(RS_Graphic& g,
const QString& file,
RS2::FormatType type = RS2::FormatUnknown);
// 格式检测
static RS2::FormatType detectFormat(const QString& file);
};
11.9.2 RS_FilterDXFRW
DXF过滤器(使用libdxfrw):
class RS_FilterDXFRW : public RS_FilterInterface,
public DRW_Interface {
public:
RS_FilterDXFRW();
// 导入
bool fileImport(RS_Graphic& g, const QString& file,
RS2::FormatType type) override;
// 导出
bool fileExport(RS_Graphic& g, const QString& file,
RS2::FormatType type) override;
// DXF回调(实现DRW_Interface)
void addLine(const DRW_Line& data) override;
void addCircle(const DRW_Circle& data) override;
void addArc(const DRW_Arc& data) override;
void addText(const DRW_Text& data) override;
// ... 更多回调
private:
RS_Graphic* graphic;
};
11.10 本章小结
本章介绍了LibreCAD的核心架构:
- 整体架构:分层设计、主要模块、技术栈
- 实体系统:RS_Entity基类、实体类型、继承层次
- 图形视图系统:RS_GraphicView、坐标转换、视图变换
- 动作系统:RS_ActionInterface、状态机模式、动作分类
- 命令系统:RS_Commands、命令注册、别名
- 事件处理:RS_EventHandler、事件分发、自定义事件
- 对象捕捉:RS_Snapper、捕捉模式
- 图层系统:RS_Layer、RS_LayerList
- 文件I/O:RS_FileIO、DXF过滤器
理解核心架构是进行LibreCAD二次开发的基础。

浙公网安备 33010602011771号