Skip to content
On this page

Custom entities

In mxcad, we support user-defined entities, which can be created and managed according to specific needs. We can inherit the entity name, attributes, methods, etc. from the custom entity class McDbCustomEntity(), or we can override the attributes or methods in the custom entity class according to our own needs. The following uses a custom line as an example:

  1. By overriding the dwgInFields() function to read data from defined entities, dwgOutFields() function writes custom entity data (both functions are called when reading entities from a file or writing entities to a file, copying entities, etc.).

  2. The getGripPoints() method provides an action point when the rendered graph is clicked, returns the custom editing pinch point, and processes the pinch editing result in the click-point move callback function moveGripPointsAt().

  3. Dynamic drawing worldDraw() method can draw the display effect of custom entities.

  4. Each time dynamic draw worldDraw is triggered, the original instance object is deleted (and the rendered three.js object is also deleted), and the instance is recreated through the create method.

Click McDbCustomEntity to check the properties and methods in detail.

ts
import { IMcDbDwgFiler, McDbCustomEntity, McDbLine, McGePoint3d, McGePoint3dArray, MxCADUiPrPoint, MxCADWorldDraw, MxCpp } from "mxcad";
import { MxFun } from "mxdraw";

class McDbTestLineCustomEntity extends McDbCustomEntity {

  private pt1: McGePoint3d = new McGePoint3d();
  private pt2: McGePoint3d = new McGePoint3d();

  constructor(imp?: any) {
    super(imp);
  }

  public create(imp: any) {
    return new McDbTestLineCustomEntity(imp)
  }

  public getTypeName(): string {
    return "McDbTestLineCustomEntity";
  }

  public dwgInFields(filter: IMcDbDwgFiler): boolean {
    this.pt1 = filter.readPoint("pt1").val;
    this.pt2 = filter.readPoint("pt2").val;
    return true;
  }

  public dwgOutFields(filter: IMcDbDwgFiler): boolean {
    filter.writePoint("pt1", this.pt1);
    filter.writePoint("pt2", this.pt2);
    return true;
  }

  public moveGripPointsAt(iIndex: number, dXOffset: number, dYOffset: number, dZOffset: number) {
    this.assertWrite();
    if (iIndex == 0) {
      this.pt1.x += dXOffset;
      this.pt1.y += dYOffset;
      this.pt1.z += dZOffset;
    }
    else if (iIndex == 1) {
      this.pt2.x += dXOffset;
      this.pt2.y += dYOffset;
      this.pt2.z += dZOffset;
    }
  };

  public getGripPoints(): McGePoint3dArray {
    let ret = new McGePoint3dArray()
    ret.append(this.pt1);
    ret.append(this.pt2);
    return ret;
  };

  public worldDraw(draw: MxCADWorldDraw): void {
    let tmpline = new McDbLine(this.pt1, this.pt2);
    draw.drawEntity(tmpline);
  }

  public setPoint1(pt1: McGePoint3d) {
    this.assertWrite();
    this.pt1 = pt1.clone();
  }

  public setPoint2(pt2: McGePoint3d) {
    this.assertWrite();
    this.pt2 = pt2.clone();
  }

  public getPoint1() {
    return this.pt1;
  }

  public getPoint2() {
    return this.pt2;
  }
}

async function MxTest_DrawCustomEntity() {
  let mxcad = MxCpp.getCurrentMxCAD();
  const getPoint = new MxCADUiPrPoint();
  getPoint.setMessage("\nSpecify first point:");
  let pt1 = (await getPoint.go());
  if (!pt1) return;

  getPoint.setBasePt(pt1);
  getPoint.setUseBasePt(true);

  getPoint.setMessage("\nSpecify second point:");
  let pt2 = (await getPoint.go());
  if (!pt2) return;

  let myline = new McDbTestLineCustomEntity();
  new McDbTestLineCustomEntity().rxInit();
  myline.setPoint1(pt1);
  myline.setPoint2(pt2);
  mxcad.drawEntity(myline);
}

MxTest_DrawCustomEntity()