Skip to content
On this page

加折断线

下面我们将介绍如何利用 mxcad 插件实现在CAD图纸中加折断线的功能,该功能中用户可设置折断数,点击画布可确定折断线起始位置。

功能实现

  1. 实现自定义折断线类

为了方便后期管理与修改折断线设置,我们可以通过继承 McDbCustomEntity 自定义实体类来扩展实现自定义折断线类。

ts
// 折断线类
class McDbTestFractureLine extends McDbCustomEntity {
    // 定义McDbTestFractureLine内部的点对象 
    // 折断线开始点
    private startPoint: McGePoint3d = new McGePoint3d();
    // 折断线结束点
    private endPoint: McGePoint3d = new McGePoint3d();
    // 折断宽度
    private _breakWidth: number = 0;
    // 折断数目
    private _breakCount: number = 1;

    // 构造函数
    constructor(imp?: any) {
        super(imp);
    }
    // 创建函数
    public create(imp: any) {
        return new McDbTestFractureLine(imp)
    }
    // 获取类名
    public getTypeName(): string {
        return "McDbTestFractureLine";
    }
    //设置或获取折断线宽度
    public set breakWidth(val: number) {
        this._breakWidth = val;
    }
    public get breakWidth(): number {
        return this._breakWidth;
    }
    //设置或获取折断数量
    public set breakCount(val: number) {
        this._breakCount = val;
    }
    public get breakCount(): number {
        return this._breakCount;
    }
    // 读取自定义实体数据
    public dwgInFields(filter: IMcDbDwgFiler): boolean {
        this.startPoint = filter.readPoint("startPoint").val;
        this.endPoint = filter.readPoint("endPoint").val;
        this._breakWidth = filter.readDouble("breakWidth").val;
        this._breakCount = filter.readLong("breakCount").val;
        return true;
    }
    // 写入自定义实体数据
    public dwgOutFields(filter: IMcDbDwgFiler): boolean {
        filter.writePoint("startPoint", this.startPoint);
        filter.writePoint("endPoint", this.endPoint);
        filter.writeDouble("breakWidth", this._breakWidth);
        filter.writeLong("breakCount", this._breakCount);
        return true;
    }

    // 移动自定义对象的夹点
    public moveGripPointsAt(iIndex: number, dXOffset: number, dYOffset: number, dZOffset: number) {
        this.assertWrite();
        if (iIndex === 0) {
            this.startPoint.x += dXOffset;
            this.startPoint.y += dYOffset;
            this.startPoint.z += dZOffset;
        } else if (iIndex === 1) {
            this.endPoint.x += dXOffset;
            this.endPoint.y += dYOffset;
            this.endPoint.z += dZOffset;
        }
    };
    // 获取自定义对象的夹点
    public getGripPoints(): McGePoint3dArray {
        let ret = new McGePoint3dArray()
        ret.append(this.startPoint);
        ret.append(this.endPoint);
        return ret;
    };

    // 绘制实体 
    public worldDraw(draw: MxCADWorldDraw): void {
        if (!this._breakWidth) this.breakWidth = MxFun.screenCoordLong2Doc(30);
        const pointArr = this.getBreakPoint();
        const pl = new McDbPolyline();
        pl.addVertexAt(this.startPoint);
        if (pointArr.length > 0) {
            pointArr.forEach(pt => {
                pl.addVertexAt(pt)
            })
        }
        pl.addVertexAt(this.endPoint);
        draw.drawEntity(pl);
    }

    // 设置折断线开始点
    public setStartPoint(pt: McGePoint3d) {
        this.startPoint = pt.clone()
    }
    // 获取折断线开始点
    public getStartPoint() {
        return this.startPoint;
    }
    // 设置折断线结束点
    public setEndPoint(pt: McGePoint3d) {
        this.endPoint = pt.clone()
    }
    // 获取折断线结束点
    public getEndPoint() {
        return this.endPoint;
    }
    private getBreakPoint(): McGePoint3d[] {
        let pointArr: McGePoint3d[] = [];
        const vec = this.endPoint.sub(this.startPoint).normalize();
        const length = this.endPoint.distanceTo(this.startPoint);
        /**
         * 动态计算折断数, 向下取整
         * n个折断就是将直线分为n段
         */
        const num = Math.floor(length / this._breakWidth);
        let count = this._breakCount;
        if (num < 1) return [];
        if (num < this._breakCount) count = num;
        const dist = length / count;
        for (let i = 1; i <= count; i++) {
            const midPt = this.startPoint.clone().addvec(vec.clone().mult(length / count * i - dist / 2));
            const pt1 = midPt.clone().subvec(vec.clone().mult(this._breakWidth / 2));
            const pt2 = pt1.clone().addvec(vec.clone().mult(this._breakWidth / 4)).addvec(vec.clone().perpVector().mult(this._breakWidth * (2 / 3)));
            const pt4 = midPt.clone().addvec(vec.clone().mult(this._breakWidth / 2));
            const pt3 = pt4.clone().subvec(vec.clone().mult(this._breakWidth / 4)).subvec(vec.clone().perpVector().mult(this._breakWidth * (2 / 3)));
            pointArr.push(pt1, pt2, pt3, pt4)
        }
        return pointArr
    }
};
  1. 注册自定义类信息
ts
new McDbTestFractureLine().rxInit();
  1. 编写方法,调用 McDbTestFractureLine 自定义折断线类实现引出标注功能
  • 设置折断数

我们可以利用 MxCADUiPrInt() 获取用户输入整数值。

ts
// 设置折断数
const getBreakCount = new MxCADUiPrInt();
getBreakCount.setMessage('请设置折断数:');
let breakCount = await getBreakCount.go();
// 默认设置折断数为1
if (!breakCount || breakCount < 1) breakCount = 1;
fl.breakCount = breakCount;
  • 设置折断线位置

调用 MxCADUiPrPoint 取点对象设置折断线的起始点位置。

ts
// 新建折断线对象
const fl = new McDbTestFractureLine();
const getPoint1 = new MxCADUiPrPoint();
getPoint1.setMessage('请设置折断线起点:');
const pt1 = await getPoint1.go();
if (!pt1) return;
fl.setStartPoint(pt1);

const getPoint2 = new MxCADUiPrPoint();
getPoint2.setMessage('请设置折断线结束点:');
getPoint2.setUserDraw((pt, pw) => {
    const _fl = fl.clone() as McDbTestFractureLine;
    _fl.setEndPoint(pt);
    pw.drawMcDbEntity(_fl)
});
const pt2 = await getPoint2.go();
if (!pt2) return;
fl.setEndPoint(pt2);
MxCpp.getCurrentMxCAD().drawEntity(fl);

功能实践

实践效果如下:

  • 点击加折断线按钮,执行加折断线方法
  • 根据命令行提示设置折断数
  • 点击鼠标左键设置折断线起始点
  • 成功绘制折断线