- 积分
- 6498
- 明经币
- 个
- 注册时间
- 2018-1-17
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
本帖最后由 MxDraw 于 2024-9-20 13:34 编辑
一、前言
本章将介绍如何利用mxcad插件实现在CAD图纸中测量圆和测量面积的功能,用户点击目标圆对象将自动标记出这个圆的半径、面积值和周长值,同时可以自定义选择标注文字的位置,测量圆功能能够快速掌握目标圆对象的数据信息,方便统计工程量。
测量面积功能(多边形、矩形)以多边形的每一个顶点来确定多边形的形状和位置,通过点击矩形的量角点来确定矩形的大小和位置,也可以自定义标注文字的位置。
二、测量圆的功能实现​
2.1.实现自定义圆标注类
- // 自定义圆标注类
- class McDbTestMeasuringCircle extends McDbCustomEntity {
- // 定义McDbTestMeasuringCircle内部的点对象
- // 圆心
- private center: McGePoint3d = new McGePoint3d();
- // 标注点
- private position: McGePoint3d = new McGePoint3d();
- // 圆半径
- private radius: number;
- // 构造函数
- constructor(imp?: any) {
- super(imp);
- }
- // 创建函数
- public create(imp: any) {
- return new McDbTestMeasuringCircle(imp)
- }
- // 获取类名
- public getTypeName(): string {
- return "McDbTestMeasuringCircle";
- }
- //设置或获取圆半径
- public set circleRadius(val: number) {
- this.radius = val;
- }
- public get circleRadius(): number {
- return this.radius;
- }
- // 读取自定义实体数据center、position、radius
- public dwgInFields(filter: IMcDbDwgFiler): boolean {
- this.center = filter.readPoint("center").val;
- this.position = filter.readPoint("position").val;
- this.radius = filter.readDouble("radius").val;
- return true;
- }
- // 写入自定义实体数据center、position、radius
- public dwgOutFields(filter: IMcDbDwgFiler): boolean {
- filter.writePoint("center", this.center);
- filter.writePoint("position", this.position);
- filter.writeDouble("radius", this.radius);
- return true;
- }
- // 移动自定义对象的夹点
- public moveGripPointsAt(iIndex: number, dXOffset: number, dYOffset: number, dZOffset: number) {
- this.assertWrite();
- this.position.x += dXOffset;
- this.position.y += dYOffset;
- this.position.z += dZOffset;
- };
- // 获取自定义对象的夹点
- public getGripPoints(): McGePoint3dArray {
- let ret = new McGePoint3dArray()
- ret.append(this.position);
- return ret;
- };
- // 绘制实体
- public worldDraw(draw: MxCADWorldDraw): void {
- // 绘制标注圆与标注信息
- const circle = new McDbCircle();
- circle.center = this.center;
- circle.radius = this.radius;
- const length = circle.getLength().val;
- const radius = circle.radius;
- const area = Math.PI * radius * radius;
- const mText = new McDbMText();
- mText.contents = `半径:${radius.toFixed(2)} \\P 周长:${length.toFixed(2)} \\P 面积:${area.toFixed(2)}`
- mText.textHeight = radius / 6;
- mText.attachment = McDb.AttachmentPoint.kMiddleCenter;
- mText.location = this.position;
- mText.trueColor = circle.trueColor = this.trueColor;
- draw.drawEntity(mText);
- draw.drawEntity(circle);
- }
- // 设置pt1
- public setCenter(pt: McGePoint3d) {
- this.assertWrite();
- this.center = pt.clone();
- }
- // 获取pt1
- public getCenter() {
- return this.center;
- }
- // 获取position
- public setPosition(pt: McGePoint3d) {
- this.assertWrite();
- this.position = pt.clone();
- }
- // 获取position
- public getPosition() {
- return this.position;
- }
- }
2.2 注册自定义类信息 运行代码: - new McDbTestMeasuringCircle().rxInit();
复制代码
2.3 编写方法调用McDbTestMeasuringCircle自定义圆标注类实现测量圆功能
2.3.1 获取目标圆对象,得到相关数据信息- // 选择实体对象
- const getEnt = new MxCADUiPrEntity();
- // 设置提示信息
- getEnt.setMessage("请选择一个圆对象");
- // 设置过滤器
- const filter = new MxCADResbuf([DxfCode.kEntityType, "CIRCLE"]);
- getEnt.setFilter(filter);
- // entId过滤选择后的圆实体对象ID
- const entId = await getEnt.go();
- if (!entId.id) return;
- // 获取圆相关信息
- const circle = entId.getMcDbEntity() as McDbCircle;
- const mCircle = new McDbTestMeasuringCircle();
- mCircle.setCenter(circle.center);
- mCircle.circleRadius = circle.radius;
复制代码
2.3.2 指定标注点并绘制圆标注对象 - // 设置取点对象
- const getPt = new MxCADUiPrPoint();
- // 设置提示信息
- getPt.setMessage('请指定文字位置');
- // 动态绘制
- getPt.setUserDraw((pt, pw) => {
- pw.setColor(0xFF0000);
- mCircle.setPosition(pt);
- pw.drawMcDbEntity(mCircle);
- });
- const point = await getPt.go();
- if (!point) return;
- // 设置标注文本位置
- mCircle.setPosition(point);
- // 设置圆标注对象颜色
- mCircle.trueColor = new McCmColor(255, 0, 0)
- const mxcad = MxCpp.getCurrentMxCAD();
- // 绘制圆标注对象
- mxcad.drawEntity(mCircle);
复制代码效果如下图:
三、测量面积的功能实现
3.1 实现自定义面积标注类为了方便后期管理与修改标注,可以通过继承McDbCustomEntity自定义实体类来扩展实现面积标注类。在mxcad中多边形与矩形都是通过多段线绘制出来的,多段线对象对应的实体类为McDbPolyline,该类提供了获取或设置图形对象相关信息的属性或方法,根据功能需求去选择调用。
- // 自定义面积标注类
- class McDbTestAreaComment extends McDbCustomEntity {
- /** 点数组 */
- private ptArr: McGePoint3d[] = [];
- /** 标注点 */
- private pt: McGePoint3d;
- /** 字高 */
- private height: number = 50;
- /** 凸度数组 */
- private dbulges: number[] = [];
- /** 测量对象是否为矩形 */
- private isReactFlag: boolean = false;
- constructor(imp?: any) {
- super(imp);
- }
- public create(imp: any) {
- return new McDbTestAreaComment(imp)
- }
- /** 获取类名 */
- public getTypeName(): string {
- return "McDbTestAreaComment";
- }
- //设置或获取文本字高
- public set textHeight(val: number) {
- this.height = val;
- }
- public get textHeight(): number {
- return this.height;
- }
- //设置或获取测量对象是否为矩形
- public set isReact(val: boolean) {
- this.isReactFlag = val;
- }
- public get isReact(): boolean {
- return this.isReactFlag;
- }
- /** 读取数据 */
- public dwgInFields(filter: IMcDbDwgFiler): boolean {
- this.ptArr = filter.readPoints('ptArr').val;
- this.pt = filter.readPoint('pt').val;
- const _dbulges = filter.readString("dbulges").val;
- this.dbulges = _dbulges.split(',').map(Number);
- this.isReactFlag = filter.readLong("isReactFlag").val ? true : false;
- return true;
- }
- /** 写入数据 */
- public dwgOutFields(filter: IMcDbDwgFiler): boolean {
- filter.writePoints("ptArr", this.ptArr);
- filter.writePoint("pt", this.pt);
- const _dbulges = this.dbulges.toString();
- filter.writeString("dbulges", _dbulges);
- filter.writeLong("isReactFlag", this.isReactFlag ? 1 : 0);
- return true;
- }
- /** 移动夹点 */
- public moveGripPointsAt(iIndex: number, dXOffset: number, dYOffset: number, dZOffset: number) {
- this.assertWrite();
- this.ptArr.forEach((point, index) => {
- if (index === iIndex) {
- point.x += dXOffset;
- point.y += dYOffset;
- point.z += dZOffset;
- }
- });
- if (iIndex === this.ptArr.length) {
- this.pt.x += dXOffset;
- this.pt.y += dYOffset;
- this.pt.z += dZOffset;
- }
- };
- /** 获取夹点 */
- public getGripPoints(): McGePoint3dArray {
- let ret = new McGePoint3dArray();
- this.ptArr.forEach(point => {
- ret.append(point);
- })
- ret.append(this.pt);
- return ret;
- };
- /** 动态绘制 */
- public worldDraw(draw: MxCADWorldDraw): void {
- const pl = new McDbPolyline();
- pl.isClosed = true;
- if (this.isReactFlag) {
- // 测量的是矩形,得到的就是矩形的两个角点
- pl.addVertexAt(this.ptArr[0], 0, 0.1, 0.1);
- pl.addVertexAt(new McGePoint3d(this.ptArr[1].x, this.ptArr[0].y), 0, 0.1, 0.1);
- pl.addVertexAt(this.ptArr[1], 0, 0.1, 0.1);
- pl.addVertexAt(new McGePoint3d(this.ptArr[0].x, this.ptArr[1].y), 0, 0.1, 0.1);
- } else {
- // 测量的是多边形
- this.ptArr.forEach((pt, index) => {
- pl.addVertexAt(pt, this.dbulges[index], 0.1, 0.1);
- });
- }
- // 获取对象数据信息
- const area = pl.getArea().val;
- const length = pl.getLength().val;
- // 构造对文本对象
- const text = new McDbMText();
- text.contents = `面积:${area.toFixed(2)}\\P周长:${length.toFixed(2)} `;
- text.attachment = McDb.AttachmentPoint.kMiddleCenter;
- text.location = this.pt;
- text.textHeight = MxFun.screenCoordLong2Doc(this.height);
- // 设置标注颜色
- text.trueColor = this.trueColor;
- draw.trueColor = this.trueColor;
- // 绘制标注对象
- draw.drawEntity(text);
- draw.drawEntity(pl);
- }
- /** 设置标注点 */
- public setPoint(pt: McGePoint3d) {
- this.assertWrite();
- this.pt = pt.clone();
- }
- /** 增加顶点 */
- public addVertex(pt: McGePoint3d, dbulge?: number) {
- this.assertWrite();
- this.ptArr.push(pt.clone());
- this.dbulges.push(dbulge ? dbulge : 0);
- }
- /** 获取标注点 */
- public getPoint() {
- return this.pt;
- }
- }
3.2 注册自定义类信息 运行代码如下: - new McDbTestAreaComment().rxInit();
复制代码
3.3.1 测量多边形面积- // 测量多边形面积
- async function Mx_Area() {
- // 多边形顶点数值
- const ptArr: McGePoint3d[] = [];
- // 获取多边形第一个顶点
- const getPt1 = new MxCADUiPrPoint();
- getPt1.setMessage('请选择面积的第一个点');
- const pt1 = await getPt1.go();
- if (!pt1) return;
- ptArr.push(pt1);
- // 循环取点
- while (true) {
- const getPt = new MxCADUiPrPoint();
- getPt.setMessage('请选择下一个点');
- getPt.setKeyWords("[回退(B)/结束(O)]");
- getPt.setUserDraw((pt, pw) => {
- const draw_pl = new McDbPolyline();
- ptArr.forEach(point => {
- draw_pl.addVertexAt(point, 0, 0.1, 0.1);
- });
- draw_pl.addVertexAt(pt);
- pw.drawMcDbEntity(draw_pl);
- });
- const pt = await getPt.go();
- const key = getPt.keyWordPicked();
- if (key === 'B') {
- // 回退到上一个取点对象
- if (ptArr.length > 1) {
- ptArr.pop();
- }
- } else if (key === 'O') {
- // 结束取点
- break;
- } else {
- if (!pt) break;
- ptArr.push(pt);
- }
- };
- // 测量多边形至少取3个点
- if(ptArr.length < 2) return;
- // 构造面积标注对象并设置标注位置
- const mxcad = MxCpp.getCurrentMxCAD();
- const area = new McDbTestAreaComment();
- ptArr.forEach((point) => {
- area.addVertex(point, 0);
- });
- const position = new MxCADUiPrPoint();
- position.setMessage('请选择面积标注的位置');
- position.setUserDraw((pt, pw) => {
- pw.setColor(0xFF0000)
- area.setPoint(pt);
- pw.drawMcDbEntity(area);
- })
- const positionPt = await position.go();
- if (!positionPt) return;
- area.setPoint(positionPt);
- area.trueColor = new McCmColor(255,0,0)
- mxcad.drawEntity(area);
- }
复制代码 3.3.2 测量矩形面积测量矩形面积只需要选取矩形的两个角点就可以确定矩形的大小与位置,参考代码如下: - // 矩形面积
- async function Mx_ReactArea() {
- // 设置测量矩形的两个角点
- const getPt1 = new MxCADUiPrPoint();
- getPt1.setMessage('请选择矩形的角点1');
- const pt1 = await getPt1.go();
- if (!pt1) return;
- const getPt2 = new MxCADUiPrPoint();
- getPt2.setMessage('请选择矩形的角点2');
- // 动态绘制矩形
- getPt2.setUserDraw((pt, pw) => {
- const pl = new McDbPolyline();
- pl.isClosed = true;
- pl.addVertexAt(pt1);
- pl.addVertexAt(new McGePoint3d(pt.x, pt1.y));
- pl.addVertexAt(pt);
- pl.addVertexAt(new McGePoint3d(pt1.x, pt.y));
- pw.drawMcDbEntity(pl);
- })
- const pt2 = await getPt2.go();
- if (!pt2) return;
- // 构造面积标注
- const reactArea = new McDbTestAreaComment();
- reactArea.isReact = true;
- reactArea.addVertex(pt1);
- reactArea.addVertex(pt2);
- // 设置标注位置
- const getPos = new MxCADUiPrPoint();
- getPos.setMessage('请设置面积标注的位置');
- getPos.setUserDraw((pt, pw) => {
- pw.setColor(0xFF0000)
- reactArea.setPoint(pt);
- pw.drawMcDbEntity(reactArea);
- });
- const position = await getPos.go();
- if (!position) return;
- reactArea.setPoint(position);
- // 设置标注颜色
- reactArea.trueColor = new McCmColor(255, 0, 0)
- MxCpp.getCurrentMxCAD().drawEntity(reactArea);
- }
复制代码效果如下图:
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?注册
x
|