Skip to content
On this page

Block table

In the DWG database, all blocks are stored in the block table McDbBlockTable(), and each record in the block table is called the block record object McDbBlockTableRecord(). Block records store all the entity data, and users can modify the corresponding entity data by changing the property Settings of the block.

We can get the current control by calling 'MxCpp.getCurrentMxCAD()' in mxcad and then call the getDatabase() method of the control instance to get the database instance McDbDatabase(). By calling the getBlockTable() method in this database instance, we get the block table McDbBlockTable().

Click on the watch McDbBlockTable(), figure block record object McDbLinetypeTableRecord(), the database instance McDbDatabase() to check the detailed description attributes and methods.

ts
import { MxCpp} from "mxcad"

let mxcad = MxCpp.App.getCurrentMxCAD();
// Fetch block table
let blockTable = mxcad.getDatabase().getBlockTable();

Insert block

We can call the insertBlock() method in the instance object of mxcad to introduce the plug-in block file to get the referenced block ID, and finally instantiate a CAD block reference entity through McDbBlockReference(). By setting the entity's blockTableRecordId property value to the referenced block ID, the target block can be inserted into the drawing.

Click McObject insertBlock() to check the properties and methods in detail. Click McDbBlockReference() to check the properties and methods in detail.

ts
import { MxCpp, McDbBlockReference, MxCADUiPrPoint } from "mxcad"

async function MxTest_InsertBlock(){
    // Destination block file Network file path and the file is in mxweb format
    let blkFilePath = new URL("../src/assets/tree.mxweb", import.meta.url).href
    let mxcad = MxCpp.getCurrentMxCAD()
    let blkrecId = await mxcad.insertBlock(blkFilePath, "tree")
    if (!blkrecId.isValid()) return;
    let blkRef = new McDbBlockReference();
    blkRef.blockTableRecordId = blkrecId;
    // Set block size
    let box = blkRef.getBoundingBox();
    if (box.ret) {
      let dLen = box.maxPt.distanceTo(box.minPt);
      if (dLen > 0.00001) {
        blkRef.setScale(mxcad.getMxDrawObject().screenCoordLong2Doc(100) / dLen);
      }
    }
    // Set block base
    let getPoint = new MxCADUiPrPoint();
    getPoint.setMessage("\指定插入基点");
    getPoint.setUserDraw((v, worldDraw) => {
      blkRef.position = v;
      worldDraw.drawMcDbEntity(blkRef);
    });
    let pt = await getPoint.go();
    if (!pt) return;
    blkRef.position = pt;
    mxcad.drawEntity(blkRef);
}

Tip

The block file path in the insertBlock() method must be the network file path and the file must be in mxweb format.

Add a block

We can add to the block table by instantiating a block record object, McDbBlockTableRecord(), and then calling the add() method. The block record object can add entities to the target object by calling the appendAcDbEntity() method to achieve custom block functionality.

ts
import { MxCpp, McDbBlockTableRecord, McDbBlockReference, McDbLine, McCmColor } from "mxcad"

let mxcad = MxCpp.getCurrentMxCAD();
let blkTable =  mxcad.getDatabase().getBlockTable();
let blkRecId = blkTable.add(new McDbBlockTableRecord());

// Get the newly added block record again based on ObjectId
let blkTableRecord:McDbBlockTableRecord = blkRecId.getMcDbBlockTableRecord()

// Add two line segments and then the specific properties of each line segment here in the block record, such as the start point and the end point, are assigned to themselves
const line = new McDbLine(80, 80, 0, -80, -80, 0)
line.trueColor = new McCmColor(255, 0, 0)
const line1 = new McDbLine(-80, 80, 0, 80, -80, 0)
blkTableRecord.appendAcDbEntity(line);
blkTableRecord.appendAcDbEntity(line1);

// Set the base point of the block is generally a point in the surrounding box and can be specified arbitrarily
blkTableRecord.origin = new McGePoint3d(0,0,0);

// The instantiation block reference here needs to set the ObjectId we just added to the block record
let blkRef = new McDbBlockReference();
blkRef.blockTableRecordId = blkRecId;
// Finally set the position render block
blkRef.position = new McGePoint3d(0,0,0);

mxcad.drawEntity(blkRef);

Go through all blocks

We can get the ids of all blocks by calling the getAllRecordId() method in the block table McDbBlockTable(). Then call getMcDbBlockTableRecord() method to return the block record object McDbBlockTableRecord(), and get all the block record object data.

ts
import { MxCpp } from "mxcad"

let mxcad = MxCpp.App.getCurrentMxCAD();
let blockTable = mxcad.getDatabase().getBlockTable();
let aryId = blockTable.getAllRecordId();
aryId.forEach((id) => {
let blkRec = id.getMcDbBlockTableRecord();
if (blkRec === null) return;
    console.log(blkRec);
    console.log("blkRec.name:" + blkRec.name);
    console.log("blkRec.origin:" + blkRec.origin);
});

Delete the block

After we get the block record object McDbBlockTableRecord(), we can call the erase() method of the object instance to delete the object.

ts
import { MxCpp } from "mxcad"

let blockTable = MxCpp.getCurrentMxCAD().getDatabase().getBlockTable()
let blockId = blockTable.get(" Target block name ")
blockId.erase()
// Update the display
mxcad.updateDisplay()

Find a block

We can call the has() method in the McDbBlockTable block table to determine whether the specified block name exists in the current database.

ts
import { MxCpp } from "mxcad";

const mxcad = MxCpp.getCurrentMxCAD();
const dataBase = mxcad.getDatabase();
const blkTable = dataBase.getBlockTable();
const res = blkTable.has("Target block name");
if(res){
    console.log("Presence target block")
}

Traverses all entities under the graph block

Since the entity in the block may be another block, we also need to traverse the block in the block when traversing all entities under the block. The following uses the id and object type of all entities in the output block of the target block as an example.

ts
import { MxCADResbuf, MxCADUiPrEntity , McDbBlockReference, McDbBlockTableRecord} from "mxcad";
// Traverse all entities under the graph block
async function Mx_ForEachBlkEntity(){
    // Select target block
    let filter = new MxCADResbuf();
    filter.AddMcDbEntityTypes("INSERT");
    const getBlockEvent = new MxCADUiPrEntity()
    getBlockEvent.setMessage('Select target block');
    getBlockEvent.setFilter(filter);
    const block_id = await getBlockEvent.go();
    if (!block_id.id) return;
    // Get block entity
    const blkRef = block_id.getMcDbEntity() as McDbBlockReference;
    // Gets the block table record object
    let blkRec = blkRef.blockTableRecordId.getMcDbBlockTableRecord();
    // Traverse the block entity
    Mx_ModyfBlockRecordEntity(blkRec)
}
function Mx_ModyfBlockRecordEntity(blkRec: McDbBlockTableRecord) {
    // Gets all entity ids in the block
    blkRec.getAllEntityId().forEach(id => {
        let ent = id.getMcDbEntity();
        // Recursively traversal if the entity is a graph block
        if (ent instanceof McDbBlockReference) {
            let blkref = ent as McDbBlockReference;
            Mx_ModyfBlockRecordEntity(blkref.blockTableRecordId.getMcDbBlockTableRecord());
        }else{
           // Output the entity id and entity class name
            console.log(id.id,ent.objectName);
        }
    })
}

Select the entity to make a block

We can obtain the target entity through the MxCADSelectionSet selection set, then create a new McDbBlockTableRecord block table record object, and write the selected entity object to the record object through the appendAcDbEntity() method. Finally, set the base point and position of the block.

ts
import { MxCADSelectionSet, MxCpp, McDbBlockTableRecord, McGePoint3d } from "mxcad";
// Select the entity to make a block
async function MxTest_SelectEntitysToBlock() {
  // Select the object you want to block
  let ss = new MxCADSelectionSet();
  if(!await ss.userSelect("Select the object you want to block:") ) return;
  if(ss.count() == 0) return;
  
  let mxcad = MxCpp.getCurrentMxCAD();
  // Gets the database block table
  let blkTable =  mxcad.getDatabase().getBlockTable();
  // Creates a new block table record object
  let blkRecId = blkTable.add(new McDbBlockTableRecord());
  let blkTableRecord:McDbBlockTableRecord = blkRecId.getMcDbBlockTableRecord() as any;
  if(blkTableRecord == null) return;
  // Defines the maximum and minimum points of the bounding box for the new block
  let pt1x:any,pt1y:any,pt2x:any,pt2y:any;
  // Traversing the selected entity gets the maximum and minimum points of the bounding box for the new block
  ss.forEach((id)=>{
    let ent = id.getMcDbEntity();
    if(!ent) return;

    let cent = ent.clone() as McDbEntity;
    blkTableRecord.appendAcDbEntity(cent);
    
    let entBox = ent.getBoundingBox();
    if(entBox.ret){
      if(!pt1x){
        pt1x = entBox.minPt.x;
        pt1y = entBox.minPt.y;
        pt2x = entBox.maxPt.x;
        pt2y = entBox.maxPt.y;
      }
      else {
        if(pt1x > entBox.minPt.x) pt1x= entBox.minPt.x;
        if(pt1y > entBox.minPt.y) pt1y= entBox.minPt.y;
        if(pt2x < entBox.maxPt.x) pt2x= entBox.maxPt.x;
        if(pt2y < entBox.maxPt.y) pt2y= entBox.maxPt.y;
      }
    }
  })
  if(pt1x === undefined){
    return;
  }
  let insertPtx =  pt1x + (pt2x - pt1x) * 0.5;
  let insertPty =  pt1y + (pt2y - pt1y) * 0.5;
  // Sets the block insertion point in the center of the graphic object.
  blkTableRecord.origin = new McGePoint3d(insertPtx,insertPty,0);
   
  // Set the block position
  let blkRef = new McDbBlockReference();
  blkRef.blockTableRecordId = blkRecId;
  blkRef.position = new McGePoint3d(insertPtx,insertPty,0);
  // Plot block
  mxcad.drawEntity(blkRef);
  // Delete original entity
  ss.forEach((id)=>{
    let ent = id.getMcDbEntity();
    if(!ent) return;
    ent.erase();
  });
}

Insert a DWG file into the current file

We can call the insertBlock() method of the mxcad object to insert a DWG file into the graph, specify a block name, and place it in the block table record. Let's take the example of inserting a stamp into a file.

Click McObject insertBlock() to check the properties and methods in detail.

ts
import { MxCpp, McDbBlockReference, MxCADUiPrPoint } from "mxcad";

// Insert stamp
async function MxTest_InsertStamp() {
  // Example Set the block file address
  let baseUrl = "http://localhost:3000/mxcad/"
  if (baseUrl.substring(0, 16) == "http://localhost") {
    baseUrl = getHostUrl() + baseUrl.substring(16);
  }
  let blkFilePath = baseUrl + "stamp.mxweb";

  let mxcad = MxCpp.App.getCurrentMxCAD();
  // Plugin block file
  let blkrecId = await mxcad.insertBlock(blkFilePath, "stamp");
  if (!blkrecId.isValid()) {
    // No block is inserted
    return;
  }
  // Create a new block reference entity
  let blkRef = new McDbBlockReference();
  // Set the block record id of the block reference entity to blkrecId
  blkRef.blockTableRecordId = blkrecId;
  // ADAPTS to block size
  let box = blkRef.getBoundingBox();
  if (box.ret) {
    let dLen = box.maxPt.distanceTo(box.minPt);
    if (dLen > 0.00001) {
      blkRef.setScale(mxcad.getMxDrawObject().screenCoordLong2Doc(100) / dLen);
    }
  }
  // Set the block base point
  let getPoint = new MxCADUiPrPoint();
  getPoint.setMessage("\ specify insert basis point ");
  // Dynamic drawing block
  getPoint.setUserDraw((v, worldDraw) => {
  blkRef.position = v;
  worldDraw.drawMcDbEntity(blkRef);
  });
  // Set the block position
  let pt = await getPoint.go();
  if (! pt) return;
  blkRef.position = pt;
  // Draw a block entity
  mxcad.drawEntity(blkRef);
}

Block properties

In AutoCAD, a block property is a label or mark that attaches data to a block. We can add attribute literals to the target block by creating the attribute definition literal class McDbAttribute in a newly created block reference. Let's take the example of inserting a block with attribute text.

Click on the McDbAttribute View detailed property and method descriptions.

ts
// Insert the attribute text ent: block entity into the block
let blkRef: McDbBlockReference = ent;
const blkrecId = blkRef.blockTableRecordId
// Gets the block record object
let blkRecord: any = blkrecId.getMcDbBlockTableRecord();
// Gets all entity object ids in the block record
let ids = blkRecord.getAllEntityId();
// Iterate over the entity type, adding attribute text
ids.forEach((id: any, index: any) => {
  if (!id.isKindOf("McDbAttributeDefinition")) return;
  let attribDef = id.getMcDbEntity() as McDbAttributeDefinition;
  let tag = attribDef.tag;
  // 设置属性详情
  let attrib = new McDbAttribute();
  attrib.position = attribDef.position;
  attrib.alignmentPoint = attribDef.alignmentPoint;
  attrib.height = attribDef.height;
  attrib.trueColor = attribDef.trueColor;
  attrib.widthFactor = attribDef.widthFactor;
  attrib.textString = "test" + index;
  attrib.tag = tag;
  attrib.isInvisible = attribDef.isInvisible;
  attrib.transformBy(blkRef.blockTransform);
  attrib = blkRef.appendAttribute(attrib).getMcDbEntity() as McDbAttribute;
  attrib.textStyle = attribDef.textStyle;
  attrib.layer = attribDef.layer;
})

Traverses the property text in the block

We can call the getAllAttribute() method in the block reference entity McDbBlockReference object to get all attribute literals in the block.

Click on the getAllAttribute() View detailed property and method descriptions.

ts
import { McDbBlockReference, McDbAttribute } from "mxcad"

// Iterate over the attribute text ent in the block: block entity
let blkRef: McDbBlockReference = ent;
let aryId = blkRef.getAllAttribute();
aryId.forEach((id) => {
  let attribt: McDbAttribute = id.getMcDbEntity() as any;
  console.log(attribt.textString);
  console.log(attribt.tag);
})