Skip to content
On this page

Local amplification

In the following, we will introduce how to use mxcad plug-in to achieve the function of local magnification in CAD drawings, in which the user can choose the area that needs to be enlarged and customize the position of the enlarged graphics. The local magnification function can help users better pay attention to the details or key parts of the drawing, and improve the speed of obtaining the drawing information quickly.

Function implementation

  1. Implement custom local amplification annotation classes

In order to facilitate later management and modification of annotation objects, We can through inheritance McDbCustomEntity custom entity class, to extend the local class. We call in the drawing according to the enlarged area selected by the user box MxCADSelectionSet.crossingSelect() method gets all the entities in the target region, recall McDbBlockTableRecord.appendAcDbEntity() method to integrate entity within the region for the block, and then call McDbSpatialFilter.setBoundary() method according to their own needs do to block outside the border of the clipping. Finally, the block is scaled according to the set scale factor.

ts
// Custom local magnification classes
class McDbTestEnlarge extends McDbCustomEntity {
    // Defines a point object inside the McDbTestReactArea
    // Magnifying center point
    private center: McGePoint3d = new McGePoint3d();
    // Amplification range
    private radius: number = 20;
    // magnification
    private scale: number = 50;
    // Insertion point
    private position: McGePoint3d = new McGePoint3d();
    // constructor
    constructor(imp?: any) {
        super(imp);
    }
    // Create function
    public create(imp: any) {
        return new McDbTestEnlarge(imp)
    }
    // Get class name
    public getTypeName(): string {
        return "McDbTestEnlarge";
    }
    //Set or get the zoom center point
    public set enlargeCenter(val: McGePoint3d) {
        this.center = val;
    }
    public get enlargeCenter(): McGePoint3d {
        return this.center;
    }
    //Set or get the zoom range
    public set enlargeRadius(val: number) {
        this.radius = val;
    }
    public get enlargeRadius(): number {
        return this.radius;
    }
    //Set or get the magnification
    public set enlargeScale(val: number) {
        this.scale = val;
    }
    public get enlargeScale(): number {
        return this.scale;
    }
    // Read from defined entity data pt1, pt2
    public dwgInFields(filter: IMcDbDwgFiler): boolean {
        this.center = filter.readPoint("center").val;
        this.position = filter.readPoint("position").val;
        this.radius = filter.readDouble("radius").val;
        this.scale = filter.readDouble("scale").val;
        return true;
    }
    // Write custom entity data pt1 and pt2
    public dwgOutFields(filter: IMcDbDwgFiler): boolean {
        filter.writePoint("center", this.center);
        filter.writePoint("position", this.position);
        filter.writeDouble("radius", this.radius);
        filter.writeDouble("scale", this.scale);
        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.center.x += dXOffset;
            this.center.y += dYOffset;
            this.center.z += dZOffset;
        }
        else if (iIndex == 1) {
            this.position.x += dXOffset;
            this.position.y += dYOffset;
            this.position.z += dZOffset;
        }
    };
    // Gets the pinch point of a custom object
    public getGripPoints(): McGePoint3dArray {
        let ret = new McGePoint3dArray()
        ret.append(this.center);
        ret.append(this.position);
        return ret;
    };
    // Draw entity
    public worldDraw(draw: MxCADWorldDraw): void {
        const circle = new McDbCircle();
        circle.center = this.center;
        circle.radius = this.radius;
        draw.drawEntity(circle);

        const { minPt, maxPt, ret } = circle.getBoundingBox();
        if (!ret) return;
        let ss = new MxCADSelectionSet();
        ss.crossingSelect(minPt.x, minPt.y, maxPt.x, maxPt.y)
        
        const mxcad = MxCpp.getCurrentMxCAD();
        let blkTable = mxcad.getDatabase().getBlockTable();
        let blkRec = new McDbBlockTableRecord();
        let blkRecId = blkTable.add(blkRec);
        let blkTableRecord: McDbBlockTableRecord = blkRecId.getMcDbBlockTableRecord() as any;
        if (blkTableRecord == null) return;

        ss.forEach((id) => {
            let ent = id.getMcDbEntity();
            if (!ent) return;
            let cent = ent.clone() as McDbEntity;
            blkTableRecord.appendAcDbEntity(cent);
        });
        // Sets the block insertion point in the center of the graphic object.
        blkTableRecord.origin = new McGePoint3d(this.center.x, this.center.y, 0);
        let blkRef = new McDbBlockReference();
        blkRef.blockTableRecordId = blkRecId;
        blkRef.position = this.position;
        const blkRefId = mxcad.drawEntity(blkRef);
        blkRef = blkRefId.getMcDbEntity() as McDbBlockReference;

        // Set a circle to be its clipped boundary.
        let samplePoints = circle.getSamplePoints(this.radius * 0.00001);
        let aryPoint = new McGePoint3dArray();
        samplePoints.forEach((val, _type, dxf) => {
            if (dxf === 1010) {
                const point = new McGePoint3d(val.x, val.y, val.z);
                aryPoint.append(point);
            }
        });
        blkRef.createSpatialFilter();
        blkRef.setScale(this.scale);
        let idSpatialFilter = blkRef.getSpatialFilterId();
        let blkFilter: McDbSpatialFilter = idSpatialFilter.getMcDbObject() as any;
        blkFilter.setBoundary(aryPoint);
        draw.drawEntity(blkRef);
        blkRefId.erase();

        const vec = this.position.sub(this.center).normalize();
        const pt1 = this.center.clone().addvec(vec.mult(this.radius));
        const pt2 = this.position.clone().subvec(vec.mult(this.scale));
        const line = new McDbLine(pt1, pt2);
        draw.drawEntity(line)
    }
    // Get position
    public setPosition(pt: McGePoint3d) {
        this.assertWrite();
        this.position = pt.clone();
    }
    // Get position
    public getPosition() {
        return this.position;
    }
}
  1. Register custom class information
ts
new McDbTestEnlarge().rxInit();

3.Write a method, call McDbTestEnlarge custom local magnification annotation class to achieve local magnification function

  • Get zoom range

We can use take object MxCADUiPrPoint() for the center of the zoom range, Call again MxCADUiPrDist() set the zoom range.

ts
// Set the zoom center point
const getPoint = new MxCADUiPrPoint();
getPoint.setMessage('Please select the zoom center point');
const point = await getPoint.go();
if (!point) return;

// Set magnification range
const getDist = new MxCADUiPrDist();
getDist.setMessage('Please select the zoom range');
getDist.setBasePt(point);
getDist.setUserDraw((pt, pw) => {
    const radius = point.distanceTo(pt);
    const circle = new McDbCircle(point.x, point.y, point.z, radius);
    pw.drawMcDbEntity(circle);
});
const distVal = await getDist.go();
if (!distVal) return;
const dist = getDist.value();

const mxcad = MxCpp.getCurrentMxCAD();
const circle1 = new McDbCircle(point.x, point.y, point.z, dist);
  • Set magnification
ts
// Set magnification
const getAmplifyDist = new MxCADUiPrDist();
getAmplifyDist.setMessage('Please set the magnification');
getAmplifyDist.setBasePt(point);
getAmplifyDist.setUserDraw((pt, pw) => {
    const radius = point.distanceTo(pt);
    const circle = new McDbCircle(point.x, point.y, point.z, radius);
    pw.drawMcDbEntity(circle);
    pw.drawMcDbEntity(circle1);
});
const aDistVal = await getAmplifyDist.go();
if (!aDistVal) return;
const aDist = getAmplifyDist.value();
const scale = aDist / dist
  • Specify the zoom image position and draw local zoom annotations

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 draw the object, so that the user can more intuitively observe the position change of the enlarged label.

ts
// Set the zoom insertion point
const getInsertPt = new MxCADUiPrPoint();
getInsertPt.setMessage('Please select the zoom insertion point');
getInsertPt.setUserDraw((pt, pw) => {
    const circle = new McDbCircle(pt.x, pt.y, pt.z, aDist);
    pw.drawMcDbEntity(circle);
    pw.drawMcDbEntity(circle1);
})
const insertPt = await getInsertPt.go();
if (!insertPt) return;

const enlarge = new McDbTestEnlarge();
enlarge.enlargeCenter = point;
enlarge.enlargeRadius = dist;
enlarge.enlargeScale = scale;
enlarge.setPosition(insertPt);
mxcad.drawEntity(enlarge)

Functional practice

Practical effects are as follows:

  • Click the local zoom button to perform the local zoom method
  • Select the zoom center point and determine the zoom range
  • Set the magnification
  • Determine the location of the label
  • Successfully drew local magnification annotation