Skip to content
On this page

保温棉

下面我们将介绍如何利用 mxcad 插件实现在CAD图纸中绘制保温棉的功能,该功能中用户自主设定保温棉的宽高、大小以及绘制位置。

功能实现

  1. 设置保温棉的宽度与高度

我们可以调用 MxCADUiPrDist 分别动态设置保温棉的宽度与高度,在设置过程中我们也可以为其设置默认值。

ts
// 设置保温棉宽度默认设置为5
let width = 5;
const getWidth = new MxCADUiPrDist();
getWidth.setMessage("\n请输入保温棉宽度<5>");
const widthVal = await getWidth.go();
if (widthVal) {
    width = getWidth.value()
}

// 设置保温棉高度默认设置为10
let height = 10;
const getHeight = new MxCADUiPrDist();
getHeight.setMessage("\n请输入保温棉高度<10>");
const heightVal = await getHeight.go();
if (heightVal) {
    height = getHeight.value()
}
  1. 设置保温棉的起始点

我们通过调用 MxCADUiPrPoint 取点对象来分别获取保温棉的起始点。

ts
const getFristPoint = new MxCADUiPrPoint();
getFristPoint.setMessage("请点击确定起点");
const fristPt = await getFristPoint.go();
if (!fristPt) return
const getNextPoint = new MxCADUiPrPoint();
getNextPoint.setMessage('请点击下一个点');
// 动态绘制起始位置
getNextPoint.setUserDraw((pt, pw) => {
    const line = new McDbLine(fristPt.x, fristPt.y, fristPt.z, pt.x, pt.y, pt.z);
    pw.drawMcDbEntity(line)
})
const nextPt = await getNextPoint.go();
if (!nextPt) return
  1. 绘制保温棉对象

我们根据上述步骤中获得的保温棉起始点得到起始线段后调用 McDbLine.offsetCurves() 得到该起始线段所在位置的偏移曲线,然后调用 McDbLine.getPointAtDist() 方法在偏移后的曲线上根据保温棉的宽高去截取端点和保温棉中圆弧部分对应的圆心,最后以 McDbPolyline 多段线对象连接所有端点和 McDbArc 绘制圆弧,最终成功绘制保温棉对象。

ts
const line = new McDbLine(fristPt.x, fristPt.y, fristPt.z, nextPt.x, nextPt.y, nextPt.z);
if (fristPt.y < nextPt.y) {
    line.startPoint = new McGePoint3d(nextPt.x, nextPt.y, nextPt.z);
    line.endPoint = new McGePoint3d(fristPt.x, fristPt.y, fristPt.z);;
}
const midPt = line.getPointAtDist(line.getLength().val / 2).val;
const line_clone = line.clone() as McDbLine;
line_clone.rotate(midPt, Math.PI / 2);
const pt1 = line_clone.getPointAtDist(line.getLength().val / 2 + height / 2).val;
const pt2 = line_clone.getPointAtDist(line.getLength().val / 2 - height / 2).val;
// 偏移曲线
let line1: any;
let line2: any;
line.offsetCurves(height / 2, pt1).forEach(e => {
    line1 = e;
})
line.offsetCurves(height / 2, pt2).forEach(e => {
    line2 = e;
});
// 根据保温棉的宽高在偏移曲线上取点
let num = line.getLength().val / width * 2;
let ptArr: McGePoint3d[] = [];
let center1: McGePoint3d[] = [];
let center2: McGePoint3d[] = [];
for (let i = 0; i < num; i++) {
    if (i % 2 == 0) {
        let pt = line2.getPointAtDist(i * (width / 2)).val;
        let center = line1.getPointAtDist(i * (width / 2)).val;
        center1.push(center);
        ptArr.push(pt);
    } else {
        let pt = line1.getPointAtDist(i * (width / 2)).val;
        let center = line2.getPointAtDist(i * (width / 2)).val;
        center2.push(center);
        ptArr.push(pt);
    }
};
// 利用多段线连接保温棉端点
const pl = new McDbPolyline();
ptArr.forEach(pt => {
    pl.addVertexAt(pt)
})
const mxcad = MxCpp.App.getCurrentMxCAD();
mxcad.drawEntity(pl);
// 绘制保温棉中的圆弧
center1.forEach(pt => {
    const arc = new McDbArc();
    arc.center = pt;
    arc.radius = width / 2;
    arc.startAngle = -(new McGeVector3d(line.endPoint.x - line.startPoint.x, line.endPoint.y - line.startPoint.y)).angleTo1(McGeVector3d.kXAxis);
    arc.endAngle = (new McGeVector3d(line.startPoint.x - line.endPoint.x, line.startPoint.y - line.endPoint.y)).angleTo1(McGeVector3d.kXAxis);
    mxcad.drawEntity(arc);
})
center2.forEach(pt => {
    const arc = new McDbArc();
    arc.center = pt;
    arc.radius = width / 2;
    arc.startAngle = (new McGeVector3d(line.startPoint.x - line.endPoint.x, line.startPoint.y - line.endPoint.y)).angleTo1(McGeVector3d.kXAxis);
    arc.endAngle = -(new McGeVector3d(line.endPoint.x - line.startPoint.x, line.endPoint.y - line.startPoint.y)).angleTo1(McGeVector3d.kXAxis);
    mxcad.drawEntity(arc)
})

功能扩展

  1. 实现自定义保温棉类

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

ts
// 自定义保温棉类
class McDbTestCottonInsulation extends McDbCustomEntity {
    // 定义McDbTestCottonInsulation内部的点对象 
    // 保温棉开始点
    private startPt: McGePoint3d = new McGePoint3d();
    // 保温棉结束点
    private endPt: McGePoint3d = new McGePoint3d();
    // 保温棉宽
    private width: number = 10;
    // 保温棉高
    private height: number = 20;

    // 构造函数
    constructor(imp?: any) {
        super(imp);
    }
    // 创建函数
    public create(imp: any) {
        return new McDbTestCottonInsulation(imp)
    }
    // 获取类名
    public getTypeName(): string {
        return "McDbTestCottonInsulation";
    }
    //设置或获取保温棉宽
    public set cWidth(val: number) {
        this.width = val;
    }
    public get cWidth(): number {
        return this.width;
    }
    // 设置保温棉高
    public set cHeight(val: number) {
        this.height = val;
    }
    public get cHeight(): number {
        return this.height;
    }
    // 读取自定义实体数据startPt、endPt、 width、height
    public dwgInFields(filter: IMcDbDwgFiler): boolean {
        this.startPt = filter.readPoint("startPt").val;
        this.endPt = filter.readPoint("endPt").val;
        this.width = filter.readDouble("width").val;
        this.height = filter.readDouble("height").val;
        return true;
    }
    // 写入自定义实体数据startPt、endPt、 width、height
    public dwgOutFields(filter: IMcDbDwgFiler): boolean {
        filter.writePoint("startPt", this.startPt);
        filter.writePoint("endPt", this.endPt);
        filter.writeDouble("width", this.width);
        filter.writeDouble("height", this.height);
        return true;
    }

    // 移动自定义对象的夹点
    public moveGripPointsAt(iIndex: number, dXOffset: number, dYOffset: number, dZOffset: number) {
        this.assertWrite();
        if (iIndex === 0) {
            this.startPt.x += dXOffset;
            this.startPt.y += dYOffset;
            this.startPt.z += dZOffset;
        } else {
            this.endPt.x += dXOffset;
            this.endPt.y += dYOffset;
            this.endPt.z += dZOffset;
        }

    };
    // 获取自定义对象的夹点
    public getGripPoints(): McGePoint3dArray {
        let ret = new McGePoint3dArray()
        ret.append(this.startPt);
        ret.append(this.endPt);
        return ret;
    };
    // 绘制实体
    public worldDraw(draw: MxCADWorldDraw): void {
        const line = new McDbLine();
        line.startPoint = this.startPt;
        line.endPoint = this.endPt;
        if (this.startPt.y < this.endPt.y) {
            line.startPoint = new McGePoint3d(this.endPt.x, this.endPt.y, this.endPt.z);
            line.endPoint = new McGePoint3d(this.startPt.x, this.startPt.y, this.startPt.z);;
        }
        const midPt = line.getPointAtDist(line.getLength().val / 2).val;
        const line_clone = line.clone() as McDbLine;
        line_clone.rotate(midPt, Math.PI / 2);
        const pt1 = line_clone.getPointAtDist(line.getLength().val / 2 + this.height / 2).val;
        const pt2 = line_clone.getPointAtDist(line.getLength().val / 2 - this.height / 2).val;
        let line1: any;
        let line2: any;
        line.offsetCurves(this.height / 2, pt1).forEach(e => {
            line1 = e;
        })
        line.offsetCurves(this.height / 2, pt2).forEach(e => {
            line2 = e;
        })
        let num = line.getLength().val / this.width * 2;
        let ptArr: McGePoint3d[] = [];
        let center1: McGePoint3d[] = [];
        let center2: McGePoint3d[] = [];
        for (let i = 0; i < num; i++) {
            if (i % 2 == 0) {
                let pt = line2.getPointAtDist(i * (this.width / 2)).val;
                let center = line1.getPointAtDist(i * (this.width / 2)).val;
                center1.push(center);
                ptArr.push(pt);
            } else {
                let pt = line1.getPointAtDist(i * (this.width / 2)).val;
                let center = line2.getPointAtDist(i * (this.width / 2)).val;
                center2.push(center);
                ptArr.push(pt);
            }
        };
        const pl = new McDbPolyline();
        ptArr.forEach(pt => {
            pl.addVertexAt(pt)
        })
        draw.drawEntity(pl);
        center1.forEach(pt => {
            const arc = new McDbArc();
            arc.center = pt;
            arc.radius = this.width / 2;
            arc.startAngle = -(new McGeVector3d(line.endPoint.x - line.startPoint.x, line.endPoint.y - line.startPoint.y)).angleTo1(McGeVector3d.kXAxis);
            arc.endAngle = (new McGeVector3d(line.startPoint.x - line.endPoint.x, line.startPoint.y - line.endPoint.y)).angleTo1(McGeVector3d.kXAxis);
            draw.drawEntity(arc);
        })
        center2.forEach(pt => {
            const arc = new McDbArc();
            arc.center = pt;
            arc.radius = this.width / 2;
            arc.startAngle = (new McGeVector3d(line.startPoint.x - line.endPoint.x, line.startPoint.y - line.endPoint.y)).angleTo1(McGeVector3d.kXAxis);
            arc.endAngle = -(new McGeVector3d(line.endPoint.x - line.startPoint.x, line.endPoint.y - line.startPoint.y)).angleTo1(McGeVector3d.kXAxis);
            draw.drawEntity(arc)
        })
    }
    // 设置保温棉起点
    public setStartPoint(pt: McGePoint3d) {
        this.assertWrite();
        this.startPt = pt.clone();
    }
    // 获取保温棉起点
    public getStartPoint() {
        return this.startPt;
    }
    // 设置保温棉终点
    public setEndPoint(pt: McGePoint3d) {
        this.assertWrite();
        this.endPt = pt.clone();
    }
    // 获取保温棉终点
    public getEndPoint() {
        return this.startPt;
    }
}

功能实践

实践效果如下:

  • 点击保温棉按钮,执行绘制保温棉方法
  • 根据命令行提示步骤完成设置保温棉的宽高
  • 点击画布设置保温棉的起始点
  • 成功绘制保温棉