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
- 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
}
};
- Register custom class information
ts
new McDbTestFractureLine().rxInit();
- 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