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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
// 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.
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);
})