实体系统详解
第十三章 实体系统详解
13.1 实体系统概述
13.1.1 实体的概念
在LibreCAD中,实体(Entity)是图形对象的基本单元。所有可以绘制、编辑和显示的图形元素都是实体的子类。
实体的特征:
- 具有几何属性(位置、尺寸)
- 具有显示属性(颜色、线型、线宽)
- 可以被选择和操作
- 属于某个图层
- 可以包含在容器中
13.1.2 实体分类
实体类型
├── 基本实体
│ ├── 点 (RS_Point)
│ ├── 直线 (RS_Line)
│ ├── 圆 (RS_Circle)
│ ├── 圆弧 (RS_Arc)
│ ├── 椭圆 (RS_Ellipse)
│ └── 样条曲线 (RS_Spline)
├── 复合实体
│ ├── 折线 (RS_Polyline)
│ ├── 填充 (RS_Hatch)
│ └── 尺寸标注 (RS_Dimension)
├── 注释实体
│ ├── 单行文字 (RS_Text)
│ └── 多行文字 (RS_MText)
├── 特殊实体
│ ├── 图像 (RS_Image)
│ └── 块引用 (RS_Insert)
└── 容器实体
├── 块定义 (RS_Block)
└── 图形 (RS_Graphic)
13.2 RS_Entity基类详解
13.2.1 类定义
class RS_Entity {
public:
// 构造函数
RS_Entity(RS_EntityContainer* parent = nullptr);
virtual ~RS_Entity();
// 实体类型识别
virtual RS2::EntityType rtti() const = 0;
virtual QString typeName() const;
virtual bool isOfType(RS2::EntityType type) const;
// 克隆
virtual RS_Entity* clone() const = 0;
// 父容器
RS_EntityContainer* getParent() const;
void setParent(RS_EntityContainer* parent);
// 图层
RS_Layer* getLayer() const;
void setLayer(RS_Layer* layer);
void setLayer(const QString& name);
// 画笔属性
RS_Pen getPen(bool resolve = true) const;
void setPen(const RS_Pen& pen);
RS_Color getColor(bool resolve = true) const;
RS2::LineType getLineType(bool resolve = true) const;
RS2::LineWidth getLineWidth(bool resolve = true) const;
// 可见性
bool isVisible() const;
void setVisible(bool v);
// 选择状态
bool isSelected() const;
void setSelected(bool s);
virtual void selectWindow(RS_Vector v1, RS_Vector v2, bool select);
// 几何属性(纯虚函数,子类实现)
virtual RS_Vector getCenter() const;
virtual RS_Vector getStartpoint() const;
virtual RS_Vector getEndpoint() const;
virtual RS_Vector getMiddlePoint() const;
virtual double getLength() const;
// 边界盒
virtual RS_Vector getMin() const;
virtual RS_Vector getMax() const;
RS_Vector getSize() const;
// 变换操作
virtual void move(const RS_Vector& offset);
virtual void rotate(const RS_Vector& center, double angle);
virtual void rotate(const RS_Vector& center, const RS_Vector& angleVector);
virtual void scale(const RS_Vector& center, const RS_Vector& factor);
virtual void mirror(const RS_Vector& axisPoint1,
const RS_Vector& axisPoint2);
virtual void stretch(const RS_Vector& firstCorner,
const RS_Vector& secondCorner,
const RS_Vector& offset);
// 绘制
virtual void draw(RS_Painter* painter,
RS_GraphicView* view,
double& patternOffset) = 0;
// 距离计算
virtual double getDistanceToPoint(
const RS_Vector& coord,
RS_Entity** entity = nullptr,
RS2::ResolveLevel level = RS2::ResolveNone,
double solidDist = RS_MAXDOUBLE) const;
virtual RS_Vector getNearestPointOnEntity(
const RS_Vector& coord,
bool onEntity = true,
double* dist = nullptr,
RS_Entity** entity = nullptr) const;
// 捕捉点
virtual RS_Vector getNearestEndpoint(const RS_Vector& coord,
double* dist = nullptr) const;
virtual RS_Vector getNearestCenter(const RS_Vector& coord,
double* dist = nullptr) const;
virtual RS_Vector getNearestMiddle(const RS_Vector& coord,
double* dist = nullptr,
int middlePoints = 1) const;
protected:
RS_EntityContainer* parent;
RS_Layer* layer;
RS_Pen pen;
bool visible;
bool selected;
unsigned long id;
};
13.2.2 实体ID系统
每个实体都有唯一的ID:
class RS_Entity {
public:
unsigned long getId() const { return id; }
static unsigned long getNextId();
private:
unsigned long id;
static unsigned long nextId;
};
// ID生成
unsigned long RS_Entity::nextId = 0;
unsigned long RS_Entity::getNextId() {
return ++nextId;
}
13.3 基本实体实现
13.3.1 RS_Point - 点
class RS_Point : public RS_AtomicEntity {
public:
RS_Point(RS_EntityContainer* parent,
const RS_PointData& d);
RS2::EntityType rtti() const override {
return RS2::EntityPoint;
}
RS_Entity* clone() const override;
RS_Vector getPos() const { return data.pos; }
void setPos(const RS_Vector& pos) { data.pos = pos; }
RS_Vector getCenter() const override { return data.pos; }
RS_Vector getStartpoint() const override { return data.pos; }
RS_Vector getEndpoint() const override { return data.pos; }
void move(const RS_Vector& offset) override {
data.pos += offset;
}
void rotate(const RS_Vector& center, double angle) override {
data.pos.rotate(center, angle);
}
void scale(const RS_Vector& center, const RS_Vector& factor) override {
data.pos.scale(center, factor);
}
void draw(RS_Painter* painter, RS_GraphicView* view,
double& patternOffset) override;
private:
RS_PointData data;
};
// 点数据结构
struct RS_PointData {
RS_Vector pos;
RS_PointData() : pos(0.0, 0.0) {}
RS_PointData(const RS_Vector& pos) : pos(pos) {}
};
13.3.2 RS_Line - 直线
class RS_Line : public RS_AtomicEntity {
public:
RS_Line(RS_EntityContainer* parent,
const RS_LineData& d);
RS2::EntityType rtti() const override {
return RS2::EntityLine;
}
RS_Entity* clone() const override;
// 几何属性
RS_Vector getStartpoint() const override { return data.startpoint; }
RS_Vector getEndpoint() const override { return data.endpoint; }
void setStartpoint(const RS_Vector& s) {
data.startpoint = s;
calculateBorders();
}
void setEndpoint(const RS_Vector& e) {
data.endpoint = e;
calculateBorders();
}
RS_Vector getMiddlePoint() const override {
return (data.startpoint + data.endpoint) / 2.0;
}
double getLength() const override {
return data.startpoint.distanceTo(data.endpoint);
}
double getAngle1() const {
return data.startpoint.angleTo(data.endpoint);
}
double getAngle2() const {
return data.endpoint.angleTo(data.startpoint);
}
// 变换
void move(const RS_Vector& offset) override {
data.startpoint += offset;
data.endpoint += offset;
calculateBorders();
}
void rotate(const RS_Vector& center, double angle) override {
data.startpoint.rotate(center, angle);
data.endpoint.rotate(center, angle);
calculateBorders();
}
void scale(const RS_Vector& center, const RS_Vector& factor) override {
data.startpoint.scale(center, factor);
data.endpoint.scale(center, factor);
calculateBorders();
}
void mirror(const RS_Vector& axisPoint1,
const RS_Vector& axisPoint2) override {
data.startpoint.mirror(axisPoint1, axisPoint2);
data.endpoint.mirror(axisPoint1, axisPoint2);
calculateBorders();
}
// 计算与点的距离
double getDistanceToPoint(const RS_Vector& coord,
RS_Entity** entity = nullptr,
RS2::ResolveLevel level = RS2::ResolveNone,
double solidDist = RS_MAXDOUBLE) const override;
RS_Vector getNearestPointOnEntity(const RS_Vector& coord,
bool onEntity = true,
double* dist = nullptr,
RS_Entity** entity = nullptr) const override;
void draw(RS_Painter* painter, RS_GraphicView* view,
double& patternOffset) override;
private:
RS_LineData data;
void calculateBorders();
};
// 直线数据结构
struct RS_LineData {
RS_Vector startpoint;
RS_Vector endpoint;
RS_LineData() {}
RS_LineData(const RS_Vector& startpoint, const RS_Vector& endpoint)
: startpoint(startpoint), endpoint(endpoint) {}
};
13.3.3 RS_Circle - 圆
class RS_Circle : public RS_AtomicEntity {
public:
RS_Circle(RS_EntityContainer* parent,
const RS_CircleData& d);
RS2::EntityType rtti() const override {
return RS2::EntityCircle;
}
RS_Entity* clone() const override;
// 几何属性
RS_Vector getCenter() const override { return data.center; }
double getRadius() const { return data.radius; }
void setCenter(const RS_Vector& c) { data.center = c; }
void setRadius(double r) { data.radius = r; }
double getLength() const override {
return 2.0 * M_PI * data.radius;
}
double getArea() const {
return M_PI * data.radius * data.radius;
}
// 边界
RS_Vector getMin() const override {
return RS_Vector(data.center.x - data.radius,
data.center.y - data.radius);
}
RS_Vector getMax() const override {
return RS_Vector(data.center.x + data.radius,
data.center.y + data.radius);
}
// 变换
void move(const RS_Vector& offset) override {
data.center += offset;
}
void rotate(const RS_Vector& center, double angle) override {
data.center.rotate(center, angle);
}
void scale(const RS_Vector& center, const RS_Vector& factor) override {
data.center.scale(center, factor);
data.radius *= (factor.x + factor.y) / 2.0;
}
// 创建方法
static RS_Circle* createFrom2Points(RS_EntityContainer* container,
const RS_Vector& p1,
const RS_Vector& p2);
static RS_Circle* createFrom3Points(RS_EntityContainer* container,
const RS_Vector& p1,
const RS_Vector& p2,
const RS_Vector& p3);
void draw(RS_Painter* painter, RS_GraphicView* view,
double& patternOffset) override;
private:
RS_CircleData data;
};
// 圆数据结构
struct RS_CircleData {
RS_Vector center;
double radius;
RS_CircleData() : radius(0.0) {}
RS_CircleData(const RS_Vector& center, double radius)
: center(center), radius(radius) {}
};
13.3.4 RS_Arc - 圆弧
class RS_Arc : public RS_AtomicEntity {
public:
RS_Arc(RS_EntityContainer* parent,
const RS_ArcData& d);
RS2::EntityType rtti() const override {
return RS2::EntityArc;
}
RS_Entity* clone() const override;
// 几何属性
RS_Vector getCenter() const override { return data.center; }
double getRadius() const { return data.radius; }
double getAngle1() const { return data.angle1; } // 起始角度
double getAngle2() const { return data.angle2; } // 终止角度
bool isReversed() const { return data.reversed; }
RS_Vector getStartpoint() const override {
return data.center + RS_Vector(data.angle1) * data.radius;
}
RS_Vector getEndpoint() const override {
return data.center + RS_Vector(data.angle2) * data.radius;
}
RS_Vector getMiddlePoint() const override {
double a = (data.angle1 + data.angle2) / 2.0;
if (data.reversed) {
a = RS_Math::correctAngle(a + M_PI);
}
return data.center + RS_Vector(a) * data.radius;
}
double getLength() const override {
return fabs(getAngleLength()) * data.radius;
}
double getAngleLength() const {
double ret = data.angle2 - data.angle1;
if (data.reversed) {
ret = -(2.0 * M_PI - ret);
}
return ret;
}
double getBulge() const; // 弧度系数
void draw(RS_Painter* painter, RS_GraphicView* view,
double& patternOffset) override;
private:
RS_ArcData data;
};
// 圆弧数据结构
struct RS_ArcData {
RS_Vector center;
double radius;
double angle1; // 起始角度(弧度)
double angle2; // 终止角度(弧度)
bool reversed; // 是否反向
RS_ArcData() : radius(0.0), angle1(0.0), angle2(0.0), reversed(false) {}
RS_ArcData(const RS_Vector& center, double radius,
double angle1, double angle2, bool reversed = false)
: center(center), radius(radius),
angle1(angle1), angle2(angle2), reversed(reversed) {}
};
13.4 复合实体
13.4.1 RS_Polyline - 折线
class RS_Polyline : public RS_EntityContainer {
public:
RS_Polyline(RS_EntityContainer* parent,
const RS_PolylineData& d);
RS2::EntityType rtti() const override {
return RS2::EntityPolyline;
}
RS_Entity* clone() const override;
// 闭合状态
bool isClosed() const { return data.closed; }
void setClosed(bool cl);
// 添加顶点
RS_Entity* addVertex(const RS_Vector& v,
double bulge = 0.0,
bool prepend = false);
// 获取顶点
RS_Vector getStartpoint() const override;
RS_Vector getEndpoint() const override;
// 遍历顶点
int countVertices() const;
RS_Vector getVertex(int index) const;
// 长度
double getLength() const override;
// 面积(闭合折线)
double getArea() const;
void draw(RS_Painter* painter, RS_GraphicView* view,
double& patternOffset) override;
private:
RS_PolylineData data;
};
// 折线数据结构
struct RS_PolylineData {
RS_Vector startpoint;
RS_Vector endpoint;
bool closed;
RS_PolylineData() : closed(false) {}
RS_PolylineData(const RS_Vector& startpoint,
const RS_Vector& endpoint,
bool closed)
: startpoint(startpoint), endpoint(endpoint), closed(closed) {}
};
13.4.2 RS_Hatch - 填充
class RS_Hatch : public RS_EntityContainer {
public:
RS_Hatch(RS_EntityContainer* parent,
const RS_HatchData& d);
RS2::EntityType rtti() const override {
return RS2::EntityHatch;
}
// 填充图案
bool isSolid() const { return data.solid; }
QString getPattern() const { return data.pattern; }
double getScale() const { return data.scale; }
double getAngle() const { return data.angle; }
// 更新填充
void update();
void draw(RS_Painter* painter, RS_GraphicView* view,
double& patternOffset) override;
private:
RS_HatchData data;
void calculateBorders();
};
// 填充数据结构
struct RS_HatchData {
bool solid; // 是否实心填充
double scale; // 图案比例
double angle; // 图案角度
QString pattern; // 图案名称
RS_HatchData() : solid(false), scale(1.0), angle(0.0) {}
RS_HatchData(bool solid, double scale, double angle, const QString& pattern)
: solid(solid), scale(scale), angle(angle), pattern(pattern) {}
};
13.5 实体容器
13.5.1 RS_EntityContainer
class RS_EntityContainer : public RS_Entity {
public:
RS_EntityContainer(RS_EntityContainer* parent = nullptr,
bool owner = true);
virtual ~RS_EntityContainer();
RS2::EntityType rtti() const override {
return RS2::EntityContainer;
}
// 实体管理
void addEntity(RS_Entity* entity);
void insertEntity(int index, RS_Entity* entity);
void removeEntity(RS_Entity* entity);
void clear();
// 查询
unsigned count() const { return entities.size(); }
RS_Entity* entityAt(unsigned index) const;
RS_Entity* first() const;
RS_Entity* last() const;
RS_Entity* next() const;
RS_Entity* prev() const;
// 查找
RS_Entity* findEntity(unsigned long id) const;
RS_Entity* findEntity(const RS_Vector& coord) const;
// 迭代器
typedef QList<RS_Entity*>::iterator iterator;
typedef QList<RS_Entity*>::const_iterator const_iterator;
iterator begin() { return entities.begin(); }
iterator end() { return entities.end(); }
const_iterator begin() const { return entities.begin(); }
const_iterator end() const { return entities.end(); }
// 边界计算
void calculateBorders();
RS_Vector getMin() const override;
RS_Vector getMax() const override;
// 变换
void move(const RS_Vector& offset) override;
void rotate(const RS_Vector& center, double angle) override;
void scale(const RS_Vector& center, const RS_Vector& factor) override;
void mirror(const RS_Vector& axisPoint1,
const RS_Vector& axisPoint2) override;
// 选择
void selectAll(bool select = true);
void selectWindow(RS_Vector v1, RS_Vector v2, bool select);
QList<RS_Entity*> getSelectedEntities() const;
void draw(RS_Painter* painter, RS_GraphicView* view,
double& patternOffset) override;
protected:
QList<RS_Entity*> entities;
bool autoDelete;
RS_Vector minV, maxV;
mutable int entityIteratorIndex;
};
13.5.2 RS_Graphic - 图形文档
class RS_Graphic : public RS_EntityContainer {
public:
RS_Graphic();
virtual ~RS_Graphic();
RS2::EntityType rtti() const override {
return RS2::EntityGraphic;
}
// 图层管理
RS_LayerList* getLayerList() { return &layerList; }
void addLayer(RS_Layer* layer);
RS_Layer* findLayer(const QString& name);
RS_Layer* getActiveLayer() { return layerList.getActive(); }
void activateLayer(RS_Layer* layer);
// 块管理
RS_BlockList* getBlockList() { return &blockList; }
void addBlock(RS_Block* block);
RS_Block* findBlock(const QString& name);
// 变量
void addVariable(const QString& key, const QString& value);
QString getVariableString(const QString& key) const;
int getVariableInt(const QString& key) const;
double getVariableDouble(const QString& key) const;
// 文件操作
bool save(const QString& filename = QString());
bool open(const QString& filename);
QString getFilename() const { return filename; }
// 修改标志
bool isModified() const { return modified; }
void setModified(bool m);
// 单位
RS2::Unit getUnit() const;
void setUnit(RS2::Unit u);
// 纸张
RS_Vector getPaperSize() const;
void setPaperSize(const RS_Vector& s);
private:
RS_LayerList layerList;
RS_BlockList blockList;
QHash<QString, RS_Variable> variables;
QString filename;
bool modified;
};
13.6 创建实体
13.6.1 使用RS_Creation
class RS_Creation {
public:
RS_Creation(RS_EntityContainer* container,
RS_GraphicView* graphicView = nullptr);
// 创建直线
RS_Line* createLine(const RS_Vector& p1, const RS_Vector& p2);
RS_Line* createParallelLine(RS_Entity* ref, double distance);
RS_Line* createBisector(const RS_Vector& p1,
const RS_Vector& p2,
const RS_Vector& p3);
// 创建圆
RS_Circle* createCircle(const RS_Vector& center, double radius);
RS_Circle* createCircle2Points(const RS_Vector& p1, const RS_Vector& p2);
RS_Circle* createCircle3Points(const RS_Vector& p1,
const RS_Vector& p2,
const RS_Vector& p3);
// 创建圆弧
RS_Arc* createArc(const RS_Vector& center,
double radius,
double angle1,
double angle2,
bool reversed = false);
RS_Arc* createArc3Points(const RS_Vector& p1,
const RS_Vector& p2,
const RS_Vector& p3);
// 创建椭圆
RS_Ellipse* createEllipse(const RS_Vector& center,
const RS_Vector& majorP,
double ratio);
private:
RS_EntityContainer* container;
RS_GraphicView* graphicView;
RS_Document* document;
};
// 使用示例
void createEntities(RS_Graphic* graphic) {
RS_Creation creation(graphic);
// 创建直线
RS_Line* line = creation.createLine(
RS_Vector(0, 0),
RS_Vector(100, 100)
);
// 创建圆
RS_Circle* circle = creation.createCircle(
RS_Vector(50, 50),
25.0
);
// 创建三点圆弧
RS_Arc* arc = creation.createArc3Points(
RS_Vector(0, 0),
RS_Vector(50, 25),
RS_Vector(100, 0)
);
}
13.6.2 直接创建
// 直接创建实体
void createEntityDirectly(RS_EntityContainer* container) {
// 创建直线
RS_Line* line = new RS_Line(container,
RS_LineData(RS_Vector(0, 0), RS_Vector(100, 100)));
container->addEntity(line);
// 创建圆
RS_Circle* circle = new RS_Circle(container,
RS_CircleData(RS_Vector(50, 50), 25.0));
container->addEntity(circle);
}
13.7 修改实体
13.7.1 使用RS_Modification
class RS_Modification {
public:
RS_Modification(RS_EntityContainer& container,
RS_GraphicView* graphicView = nullptr);
// 移动
bool move(RS_MoveData& data);
// 复制
bool copy(RS_CopyData& data);
// 旋转
bool rotate(RS_RotateData& data);
// 缩放
bool scale(RS_ScaleData& data);
// 镜像
bool mirror(RS_MirrorData& data);
// 修剪
bool trim(const RS_Vector& trimPoint,
RS_Entity* limitEntity,
bool trimBoth = false);
// 延伸
bool extend(const RS_Vector& trimPoint,
RS_Entity* limitEntity);
// 偏移
bool offset(RS_Entity* entity, double distance, bool copy);
// 圆角
bool fillet(RS_Entity* entity1, RS_Entity* entity2, double radius);
// 倒角
bool chamfer(RS_Entity* entity1, RS_Entity* entity2,
double distance1, double distance2);
// 炸开
bool explode(RS_Entity* entity);
private:
RS_EntityContainer* container;
RS_GraphicView* graphicView;
RS_Document* document;
};
13.7.2 数据结构
// 移动数据
struct RS_MoveData {
int number; // 复制数量(0=移动)
bool useCurrentAttr; // 使用当前属性
bool useCurrentLayer; // 使用当前图层
RS_Vector offset; // 偏移量
};
// 旋转数据
struct RS_RotateData {
int number;
bool useCurrentAttr;
bool useCurrentLayer;
RS_Vector center; // 旋转中心
double angle; // 旋转角度
};
// 缩放数据
struct RS_ScaleData {
int number;
bool useCurrentAttr;
bool useCurrentLayer;
RS_Vector referencePoint; // 缩放中心
RS_Vector factor; // 缩放因子
};
// 镜像数据
struct RS_MirrorData {
bool copy; // 是否保留原对象
bool useCurrentAttr;
bool useCurrentLayer;
RS_Vector axisPoint1; // 镜像轴点1
RS_Vector axisPoint2; // 镜像轴点2
};
13.8 本章小结
本章详细介绍了LibreCAD的实体系统:
- 实体概述:概念、分类、层次结构
- RS_Entity基类:属性、方法、ID系统
- 基本实体:点、线、圆、弧、椭圆
- 复合实体:折线、填充
- 实体容器:RS_EntityContainer、RS_Graphic
- 创建实体:RS_Creation类、直接创建
- 修改实体:RS_Modification类
理解实体系统是进行LibreCAD二次开发的核心。
上一章:源码编译与开发环境搭建 | 下一章:Action系统与命令开发

浙公网安备 33010602011771号