Skip to content
On this page

Measurement circle

Here we will introduce how to use mxcad plug-in to measure arc length in CAD drawings. In this function, users click on the target arc object to automatically mark the arc length of this arc, and users can customize the location of the marked text. The arc length measurement function can help users grasp the data information of the target arc object quickly, and it is convenient to count the engineering quantity.

Function implementation

  1. Implement custom arc length annotation classes

In order to facilitate later management and annotation modification, We can through inheritance McDbCustomEntity custom entity class to extend the arc length with class. Among them, the circular object in mxcad corresponding entity class for McDbArc, This class provides properties or methods to get or set information about the arc, which we can choose to call according to our functional requirements. In the arc length measurement function, We can call McDbArc.getLength() method to get the arc length.

Then, we can use McDbText measurement information text object, the circular arc of the label information on the page.

ts
// Custom arc length annotation class
class McDbTestArcComment extends McDbCustomEntity {
    /** Arc center */
    private center: McGePoint3d = new McGePoint3d();
    /** Arc radius */
    private radius: number;
    /** Starting Angle of arc */
    private startAngle: number;
    /** End Angle of arc */
    private endAngle: number;
    /** Arc mark points */
    private position: McGePoint3d = new McGePoint3d();
    /** Arc marks text height */
    private height: number = 50;
    constructor(imp?: any) {
        super(imp);
    }
    public create(imp: any) {
        return new McDbTestArcComment(imp)
    }
    /** Get class name */
    public getTypeName(): string {
        return "McDbTestArcComment";
    }
    //Set or get the center of the annotated arc
    public set arcCenter(val: McGePoint3d) {
        this.center = val.clone();
    }
    public get arcCenter(): McGePoint3d {
        return this.center;
    }
    //Set or get the annotated arc radius
    public set arcRadius(val: number) {
        this.radius = val;
    }
    public get arcRadius(): number {
        return this.radius;
    }
    //Sets or gets the annotated text height
    public set textHeight(val: number) {
        this.height = val;
    }
    public get textHeight(): number {
        return this.height;
    }
    //Set or get the starting Angle of the annotated arc
    public set arcStartAngle(val: number) {
        this.startAngle = val;
    }
    public get arcStartAngle(): number {
        return this.startAngle;
    }
    public set arcEndAngle(val: number) {
        this.endAngle = val;
    }
    public get arcEndAngle(): number {
        return this.endAngle;
    }
    /** Read data */
    public dwgInFields(filter: IMcDbDwgFiler): boolean {
        this.position = filter.readPoint('position').val;
        this.center = filter.readPoint('center').val;
        this.startAngle = filter.readDouble('startAngle').val;
        this.endAngle = filter.readDouble('endAngle').val;
        this.radius = filter.readDouble('radius').val;
        this.height = filter.readDouble('textHeight').val;
        return true;
    }
    /** Write data */
    public dwgOutFields(filter: IMcDbDwgFiler): boolean {
        filter.writePoint("position", this.position);
        filter.writePoint("center", this.center);
        filter.writeDouble("startAngle", this.startAngle);
        filter.writeDouble("endAngle", this.endAngle);
        filter.writeDouble("radius", this.radius);
        filter.writeDouble("textHeight", this.height);
        return true;
    }
    /** Moving pinch */
    public moveGripPointsAt(iIndex: number, dXOffset: number, dYOffset: number, dZOffset: number) {
        this.assertWrite();
        this.position.x += dXOffset;
        this.position.y += dYOffset;
        this.position.z += dZOffset;
    };
    /** Grab pinch */
    public getGripPoints(): McGePoint3dArray {
        let ret = new McGePoint3dArray();
        ret.append(this.position);
        return ret;
    };
    // Draws annotated style line segments
    private drawLine(pt1:McGePoint3d, pt2:McGePoint3d):any{
        const vec = pt2.sub(pt1).normalize().mult(MxFun.screenCoordLong2Doc(this.height*0.4));
        const _pt = pt2.clone().addvec(vec);
        const _ptClone = pt2.clone().subvec(vec);
        const line = new McDbLine(_pt, _ptClone)
        line.rotate(pt2,Math.PI/4);
        return {line, pt:_pt};
    }
    private pt1:McGePoint3d
    private pt2:McGePoint3d
    private dbulge:number
    /** Dynamic rendering */
    public worldDraw(draw: MxCADWorldDraw): void {
        // Obtain the basic information of the arc of the measurement target
        const arc = new McDbArc();
        arc.center  = this.center;
        arc.startAngle = this.startAngle;
        arc.endAngle = this.endAngle;
        arc.radius = this.radius;
        const length = arc.getLength().val;
        const startPt = arc.getPointAtDist(0).val;
        const endPt = arc.getPointAtDist(length).val;
        
        // Construct annotated arc length text information
        const lText = new McDbText();
        lText.textString = `${length.toFixed(2)}`;
        lText.height = MxFun.screenCoordLong2Doc(this.height);
        lText.horizontalMode = McDb.TextHorzMode.kTextCenter;
        lText.position = lText.alignmentPoint = this.position;
        // Arc deviation
        const closePt = arc.getClosestPointTo(this.position, true).val;
        const dist = closePt.distanceTo(this.position);
        arc.offsetCurves(dist, this.position).forEach(obj => {
            const offsetEnt = obj.clone() as McDbArc;
            const length = offsetEnt.getLength().val;
            this.pt1 = offsetEnt.getPointAtDist(0).val;
            this.pt2 = offsetEnt.getPointAtDist(length).val;
            const midPt = offsetEnt.getPointAtDist(length / 2).val;
            this.dbulge = MxCADUtility.calcBulge(this.pt1, midPt, this.pt2).val;
        })
        // Draw annotation style
        const pl = new McDbPolyline();
        pl.addVertexAt(this.pt1, this.dbulge);
        pl.addVertexAt(this.pt2);
        // Angle text
        const angle = this.pt1.sub(this.pt2).angleTo2(McGeVector3d.kXAxis, McGeVector3d.kNegateZAxis);
        lText.rotation = angle === Math.PI ? 0 : angle;

        const { line:line1, pt:_pt1 } = this.drawLine(startPt, this.pt1);
        const { line:line2, pt:_pt2 } = this.drawLine(endPt, this.pt2);
        pl.trueColor = lText.trueColor = line1.trueColor = line2.trueColor = this.trueColor;
        draw.drawEntity(pl);
        draw.drawEntity(lText);
        draw.drawEntity(line1);
        draw.drawEntity(line2);
        draw.drawEntity(new McDbLine(startPt, _pt1))
        draw.drawEntity(new McDbLine(endPt, _pt2))
    }
    /** Set tag point */
    public setPosition(pt: McGePoint3d) {
        this.assertWrite();
        this.position = pt.clone();
    }
    /** Get tag point */
    public getPoint() {
        return this.position;
    }

}
  1. Register custom class information
ts
new McDbTestArcComment().rxInit();
  1. Write a method and call McDbTestArcComment custom arc length annotation class to measure arc length
  • Get the target arc object, get the relevant data information

We can choose using entity object MxCADUiPrEntity() According to the coordinates of the user's mouse click, the corresponding entity is obtained, where we need to select only the arc object, so, We'll call MxCADResbuf() to select entity object set filter to filter out the target entity.

ts
// Select the entity object
const getEnt = new MxCADUiPrEntity();
// Set prompt information
getEnt.setMessage(' Please select an arc ');
// Set the filter
const filter = new MxCADResbuf([DxfCode.kEntityType, "ARC"]);
getEnt.setFilter(filter);
// entId Filters the ID of the selected round entity
const entId = await getEnt.go();
if (! entId.id) return;
// Obtain information about the arc
const arc = entId.getMcDbEntity() as McDbArc;
const mArc = new McDbTestArcComment();
mArc.arcCenter = arc.center;
mArc.arcStartAngle = arc.startAngle;
mArc.arcEndAngle = arc.endAngle;
mArc.arcRadius = arc.radius;
  • Specify annotation points and draw arc length annotation objects

We can use MxCADUiPrPoint take the object interaction take in the page. In the process of taking points, We can go through MxCADUiPrPoint.setUserDraw() Method Dynamically drawing annotation objects, so that users can observe the position changes of annotation objects more intuitively.

ts
// Set the fetch object
const getPos = new MxCADUiPrPoint();
// Set prompt information
getPos.setMessage(" Please specify dimension line position ");
// Dynamic rendering
getPos.setUserDraw((pt, pw) => {
    pw.setColor(0xFF0000);
    mArc.setPosition(pt);
    pw.drawMcDbEntity(mArc)
});
const position = await getPos.go();
if (!position) return;
// Set the annotated text position
mArc.setPosition(position);
// Set the arc length annotation object color
mArc.trueColor = new McCmColor(0xFF000000);
// Draw an arc-circle annotation object
const mxcad = MxCpp.getCurrentMxCAD();
mxcad.drawEntity(mArc);

Functional practice

Practical effects are as follows:

  • Click the arc length button to perform the arc length measurement method
  • Select the target arc object
  • Set the point location
  • The contents of the measurement annotations were successfully drawn