Skip to content
On this page

Add break line

In the following, we will introduce how to use mxcad plug-in to achieve the function of adding broken lines in CAD drawings. In this function, users can set the number of broken lines and click on the canvas to determine the starting position of broken lines.

Function implementation

  1. Implement a custom break line class

In order to facilitate later management and modification of break line Settings, We can through inheritance McDbCustomEntity Custom entity classes to extend the implementation of custom snap line classes.

ts
// Fracture line
class McDbTestFractureLine extends McDbCustomEntity {
    // Define a point object inside McDbTestFractureLine
    // Start point of break line
    private startPoint: McGePoint3d = new McGePoint3d();
    // Break line end point
    private endPoint: McGePoint3d = new McGePoint3d();
    // Break width
    private _breakWidth: number = 0;
    // Number of breaks
    private _breakCount: number = 1;

    // constructor
    constructor(imp?: any) {
        super(imp);
    }
    // Create function
    public create(imp: any) {
        return new McDbTestFractureLine(imp)
    }
    // Get class name
    public getTypeName(): string {
        return "McDbTestFractureLine";
    }
    //Set or get the break line width
    public set breakWidth(val: number) {
        this._breakWidth = val;
    }
    public get breakWidth(): number {
        return this._breakWidth;
    }
    //Set or get the number of breaks
    public set breakCount(val: number) {
        this._breakCount = val;
    }
    public get breakCount(): number {
        return this._breakCount;
    }
    // Read from defined entity data
    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;
    }
    // Writes custom entity data
    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;
    }

    // Moves the pinch point of a custom object
    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;
        }
    };
    // Gets the pinch point of a custom object
    public getGripPoints(): McGePoint3dArray {
        let ret = new McGePoint3dArray()
        ret.append(this.startPoint);
        ret.append(this.endPoint);
        return ret;
    };

    // Draw entity 
    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);
    }

    // Set the start point of the break line
    public setStartPoint(pt: McGePoint3d) {
        this.startPoint = pt.clone()
    }
    // Get the break line start point
    public getStartPoint() {
        return this.startPoint;
    }
    // Set the break line end point
    public setEndPoint(pt: McGePoint3d) {
        this.endPoint = pt.clone()
    }
    // Gets the end point of the break line
    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);
        /**
         * Dynamic calculation of broken number, rounded down
         * n breaks are dividing the line into n segments
         */
        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. Register custom class information
ts
new McDbTestFractureLine().rxInit();
  1. Write a method, call McDbTestFractureLine custom fracture line class to achieve the extraction annotation function
  • Set break number

We can use MxCADUiPrInt() for the user to enter the integer value.

ts
// Set break number
const getBreakCount = new MxCADUiPrInt();
getBreakCount.setMessage('Please set the number of breaks:');
let breakCount = await getBreakCount.go();
// The default number of breaks is 1
if (!breakCount || breakCount < 1) breakCount = 1;
fl.breakCount = breakCount;
  • Set the break line position

Call MxCADUiPrPoint take break line position, the starting point of the object.

ts
// Create a new snap line object
const fl = new McDbTestFractureLine();
const getPoint1 = new MxCADUiPrPoint();
getPoint1.setMessage('Please set the start of the break line:');
const pt1 = await getPoint1.go();
if (!pt1) return;
fl.setStartPoint(pt1);

const getPoint2 = new MxCADUiPrPoint();
getPoint2.setMessage('Please set the break line end point:');
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);

Functional practice

Practical effects are as follows:

  • Click the Add break line button to perform the add break line method
  • Follow the command line prompts to set the number of breaks
  • Click the left mouse button to set the starting point of the break line
  • The break line was successfully drawn