室内平面图中墙体是最重要的图形之一,其中砖墙、混凝土墙、钢架墙、隔墙、隔热墙等类型的墙在设计图中均有不同的表现方式,墙体的用途一般可以分为一般墙、虚墙、卫生隔断、阳台挡板、矮墙等,根据不同的需求绘制对应的墙体能够增强建筑设计的专业性和准确性。下面我们将介绍如何使用mxcad实现基础墙体功能,并展示其实践运用效果。
下述的墙体功能为一个基于mxcad开发的demo示例,因此存在无法百分百适配用户实际使用需求的情况,用户可在下述源码的基础上基于mxcad实现二次开发一次来适配实际需求。
功能开发
mxcad墙体功能的核心思想是通过继承mxcad中的自定义实体[McDbCustomEntity],自己实现一个独立的墙体对象,以及通过监测墙体相交的变化实现自主计算墙体绘制的一系列逻辑。如果你对mxcad中的自定义实体还不熟悉,点击[自定义实体开发文档链接]了解自定义实体是什么,内部存在的方法以及如何通过该实体实现自定义的功能实体。
1.封装计算墙体对应的多段线方法
在计算墙体多段线的方法中,我们需要传入墙体开始点、墙体结束点和墙体宽度,如果目标墙体存在与其他墙体相交产生拐点的情况还需要传入目标墙体生成的拐点。为了方便后续与其他墙体之间的比对和计算,我们将返回墙体的四个断点(pt1,pt2,pt3,pt4)、整体多段线(pl)、以及所在的中心直线(line),参考代码:
2.实现自定义墙体类:McDbTestWall
3.计算墙体相交后的断点和拐点。
计算与目标墙体相交的墙体,参考代码:
//相交墙体集合constintersectingWalls:McObjectId[]=[];/***startPoint:墙体开始点*endPoint:墙体结束点*wallWidth:墙体宽度*/const{pt1,pt3,line}=getPolyline(startPoint,endPoint,wallWidth);constlength=line.getLength().val;//设置过滤器,过滤出自定义实体letfilter=newMxCADResbuf();filter.AddString("McDbCustomEntity",5020);constss=newMxCADSelectionSet();ss.crossingSelect(pt1.x-length,pt1.y-length,pt3.x+length,pt3.y+length,filter);//与其他墙体相交if(ss.count()!==0){ss.forEach(id=>{constent=id.getMcDbEntity();if((entasMcDbCustomEntity).getTypeName()==="McDbTestWall"){intersectingWalls.push(id);}});}
根据相交墙体信息获取墙体断点与拐点,参考代码:
4.整合绘制墙体方法:MxdrawWalls
5.调用MxdrawWalls绘制墙体
6.夹点编辑、实体删除情况处理
调用夹点编辑监听事件,监听墙体变化,当墙体位置发生改变则触发墙体更新方法,参考代码:
constmxcad:McObject=MxCpp.getCurrentMxCAD();//监听wall夹点变化mxcad.mxdraw.on("objectGripEdit",(grips)=>{grips.forEach((grip)=>{constid=newMcObjectId(grip.id,grip.type==="mxcad"McObjectIdType.kMxCAD:McObjectIdType.kMxDraw);if(id.isErase())return;constwall=id.getMcDbEntity()asMcDbTestWall;if(!wall)return;if(wall.objectName==="McDbCustomEntity"&&(wallasMcDbCustomEntity).getTypeName()==="McDbTestWall"){//更新绘制wallconstnewWall=newMxdrawWalls();newWall.updateWall(id,true);mxcad.clearMxCurrentSelect();};})})
调用实体选择监听事件,监听实体选择,若监听到选择的墙体被删除则触法墙体更新方法,参考代码:
//监听mxcad选择,若wall被删除则触发更新constoldSelectIds:McObjectId[]=[];mxcad.on("selectChange",(ids:McObjectId[])=>{if(ids.length>0){ids.forEach(id=>{constentity=id.getMcDbEntity();if(entity&&entity.objectName==="McDbCustomEntity"&&(entityasMcDbCustomEntity).getTypeName()==="McDbTestWall"){oldSelectIds.push(id)}})}else{setTimeout(()=>{oldSelectIds.forEach(id=>{if(id.isErase()){constnewWall=newMxdrawWalls();newWall.updateWall(id,false);}});oldSelectIds.length=0;},0)}})