惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

aimingoo的专栏
aimingoo的专栏
Engineering at Meta
Engineering at Meta
有赞技术团队
有赞技术团队
博客园_首页
Apple Machine Learning Research
Apple Machine Learning Research
Vercel News
Vercel News
G
Google Developers Blog
Blog — PlanetScale
Blog — PlanetScale
IT之家
IT之家
MongoDB | Blog
MongoDB | Blog
Y
Y Combinator Blog
B
Blog
The GitHub Blog
The GitHub Blog
M
MIT News - Artificial intelligence
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Stack Overflow Blog
Stack Overflow Blog
C
Check Point Blog
Microsoft Azure Blog
Microsoft Azure Blog
D
DataBreaches.Net
I
InfoQ
Recent Announcements
Recent Announcements
阮一峰的网络日志
阮一峰的网络日志
腾讯CDC
H
Help Net Security

博客园 - 梦想CAD控件

网页CAD如何在web端实现AutoCAD的绘圆弧功能 网页CAD控件中对象捕捉的运用和二次开发方法(网页端编辑DWG) 云原生CAD后台处理DWG(MxServiceCode) 网页CAD图纸保存与数据持久化(BS架构CAD插件) 网页CAD中命令行驱动与参数化绘图的使用教程 在线CAD视图控制与图层管理二开实战 Web CAD图形引擎实现DWG图纸网页批注和查看 开源网页实时协同设计平台-在线编辑CAD图纸 在线CAD SDK开发包图纸转换功能使用教程(在线CAD API) 统信麒麟鸿蒙系统软件集成CAD功能(国产系统CAD控件) 网页CAD开发包结构与功能说明(网页CAD实时协同编辑) 网页CAD结合AI实现自然语言设计CAD图纸 (JS实现预览)在线CAD中的“组”功能开发 (在线CAD)html在线预览cad图纸SDK集成方法 (JS编辑DWG文件)在线CAD二开实现图纸表格提取到excel 网页版CAD与gis结合实现在线地图和CAD编辑 (html在线预览cad图纸插件)在线CAD实现形位公差标注 (WEB CAD API )网页CAD插件如何开发焊接符号 (HTML VUE在线编辑DWG)网页CAD利用AI实现多行文本功能的开发 (web cad sdk)在线CAD中配置属性的使用教程 (WEB CAD二次开发)在线CAD SDK调用内部弹框的方法 在线CAD插件通过上下文对象MxPluginContext修改UI界面的方法 国产操作系统中好用的CAD软件(统信,麒麟,信创环境安装CAD) (pdm集成CAD SDK)在线CAD绘制条形码、二维码的教程 在线CAD绘制门和窗(WEB CAD二次开发家装设计软件) 在线CAD绘制墙体(WEB端开发室内设计软件) (在线三维参数化建模)网页三维CAD中加载和保存STEP模型 (H5在线CAD SDK)在线CAD中线型表的使用方法 (web查看三维CAD图纸)在三维网页CAD中绘制一个窗户模型
网页端CAD的图形选择、编辑与夹点操作教程(CAD in WEB)
梦想CAD控件 · 2026-08-18 · via 博客园 - 梦想CAD控件

前言

在 Web CAD 的开发领域,图纸的展示、视图的平移与缩放,这些功能构建了 CAD 系统的“只读”基础。然而 CAD 的“设计”与“修改”需要掌握图形的选择机制、几何变换原理以及夹点交互技术。

基于 MxCAD 强大的底层 API,我们将深入探讨如何通过代码精准控制图形实体,实现从简单的移动、旋转到复杂的批量筛选与变换。这不仅是功能的堆砌,更是对 CAD 图形数据底层逻辑的深度理解。

一、 精准定位:构建图形选择

在进行任何编辑操作之前,我们必须先确定“操作谁”。MxCAD 提供了极其灵活的 MxCADSelectionSet(选择集)机制,配合 MxCADUtilityClass 绘图工具类,能够实现从简单的点选到复杂的属性过滤。

1. 开启交互的大门:环境配置

在开始编码之前,我们需要在项目初始化阶段“唤醒” CAD 的交互能力。这一步至关重要,它决定了用户能否通过鼠标与图形进行交互。

通过 MxFun.setIniset 配置,我们主要开启三个核心开关:

  • EnableGripEdit:开启夹点编辑系统变量。这是 CAD 特有的交互方式,开启后选中的图形会显示蓝色的小方块(夹点),用户可以直接拖拽修改。

  • multipleSelect:启动多选功能。允许用户通过框选或累加选择来操作多个实体。

  • IntelliSelectType:智能选择类型。设置为 2 表示支持连续多选,极大地提升了批量操作的效率。

image-20260427134513876

代码实现:

import { MxFun } from "mxdraw";
// 开启夹点编辑系统变量
MxFun.setIniset({
    /**
     *启动夹点编辑
     *true,1表示启用,0,fase表示禁用,2表示只显示夹点,但不响应夹点编辑.
     */
    EnableGripEdit: true,
    /** 启动多选,框选功能,默认值是false */
    multipleSelect: true,
    /**
     * 开启多选
     * 选择方式控制 1:多选,暂不支持连续多选,2:多选,并支持连续多选,默认值为1 
     */
    IntelliSelectType: 2
});

此外,mxcad对象中也设置了相关的选择属性配置项目,用户也可以直接在mxcad对象中开启选择设置:

import { createMxCad } from "mxcad";
createMxCad({
    //...
    enableIntelliSelect:true,// 是否启用选择功能,默认是使用
    multipleSelect: true, // 开启多选
    //...
  })

2. 选择的艺术:从交互到过滤

在实际开发中,构建选择集通常有两种截然不同的路径:

  • 交互式选择:这是最直观的方式。根据用户的需求,我们可以引导用户进行“点选”(精准打击)、“框选”(区域覆盖)、“累加选择”(按住 Shift 逐个添加)或“全选”。这种方式依赖于用户的鼠标操作,MxCAD 内部已经封装了完善的逻辑,开发者只需调用相应的命令接口即可。

    选择方式的实现详情请参考mxcad开发文档中的 [选择图形]。

    image-20260427134839166

  • 构建过滤器(高级应用):当业务逻辑需要自动筛选特定对象时(例如:自动选中图纸中所有的圆),交互式选择就显得力不从心了。此时,我们需要祭出 MxCADResbuf。通过构建过滤器,我们可以根据实体的类型(如 McDbText、McDbMText)、图层、颜色或扩展数据进行精确筛选。这就像在数据库中执行 SQL 查询一样,让代码自动帮你找到目标,是实现自动化批量处理的基石。

  • image-20260427135724768

    代码实现:

    import { MxCADResbuf, MxCpp, MxCADSelectionSet } from "mxcad";
    const mxcad = MxCpp.getCurrentMxCAD();
    // 创建过滤器
    const filter = new MxCADResbuf();
    filter.AddMcDbEntityTypes("TEXT,MTEXT");
    // 设置选择集,筛选文本对象
    let ss = new MxCADSelectionSet();
    ss.allSelect(filter);
    ss.forEach((id) => {
        mxcad.addCurrentSelect(id)
    });
    mxcad.updateDisplay();

二、 几何变换:从直观操作到数学本质

一旦目标实体被锁定,我们便进入了编辑的核心环节——几何变换。在 CAD 的底层世界里,所有的移动、旋转和缩放,本质上都是对实体顶点坐标进行的数学运算。

1. 核心引擎:变换矩阵

在 MxCAD 的底层逻辑中,一切皆矩阵。所有的复杂变换在数学上都统一为矩阵乘法。通过构建一个 McGeMatrix3d 变换矩阵,我们可以描述任意的空间变换。

这种设计的精妙之处在于效率。你可以将多次变换(例如先旋转 45 度,再移动 100 单位,最后缩小一半)合并为一个单一的矩阵。通过 entity.transformBy(matrix) 接口一次性应用,实体的坐标将瞬间完成所有计算,避免了多次循环计算顶点的性能损耗。

2. 常见操作的两种境界

虽然底层是矩阵,但为了开发的便捷性,MxCAD 为开发者提供了“快捷方法”和“矩阵变换”两种实现层级。

  • 移动:直观上,我们定义一个位移向量,将实体所有点的坐标加上这个向量。快捷方式是 move(basePoint, toPoint),直接定义起点和终点;底层则是通过 McGeMatrix3d.setToTranslation(vector) 生成平移矩阵。

    image-20260427142622951

    代码实现:

    import { McDbCircle, McGeVector3d, MxCpp, McGePoint3d, McGeMatrix3d } from "mxcad";
    const mxcad = MxCpp.getCurrentMxCAD();
    const center = new McGePoint3d(0,0,0)
    const circle = new McDbCircle(center.x,center.y,center.z,10);
    // 移动前
    mxcad.drawEntity(circle);
    // 方式一:快捷调用平移函数move
    const movePt = new McGeVector3d(50,50,0);
    circle.move(center,movePt);
    ​
    // 方式二:调用平移矩阵
    const matrix = new McGeMatrix3d();
    const vec = new McGeVector3d(50,50,0)
    matrix.setToTranslation(vec);
    circle.transformBy(matrix);
    ​
    // 移动后
    mxcad.drawEntity(circle);
    mxcad.updateDisplay();
  • 旋转:旋转需要三个关键要素:旋转基点旋转轴旋转角度。实体上的点将绕着指定轴旋转指定的弧度。快捷方式 rotate(basePoint, dRotationAngle) 让你无需关心复杂的三角函数计算;而矩阵方式 McGeMatrix3d.setToRotation(angle, axis, center) 则赋予了你对空间旋转的绝对控制权。

    image-20260427145054081

    代码实现:

    import { McDb, McGeVector3d, MxCpp, McGePoint3d, McGeMatrix3d } from "mxcad";
    const mxcad = MxCpp.getCurrentMxCAD();
    const basePt = new McGePoint3d(0,0,0)
    // 旋转前
    const id = mxcad.drawText(0,0,'test',10,0, McDb.TextHorzMode.kTextLeft, McDb.TextVertMode.kTextBottom);
    const text = id.getMcDbEntity();
    const angle = Math.PI/4;
    // 方式一:快捷调用旋转函数rotate
    text.rotate(basePt,angle);
    // 方式二:调用旋转矩阵
    const matrix = new McGeMatrix3d();
    matrix.setToRotation(angle,McGeVector3d.kZAxis,basePt);
    text.transformBy(matrix);
    mxcad.updateDisplay();
  • 缩放:缩放是相对于基点进行的。新坐标 = 基点 + (旧坐标 - 基点) × 比例因子。无论是使用 scaleEntity(basePoint, dScaleFactor) 的便捷接口,还是通过矩阵 McGeMatrix3d.setToScaling(scaleAll, center),核心都在于基点的选择——它决定了图形是“原地缩小”还是“飞出屏幕”。

    image-20260427151004961

    代码实现:

    import { McDb, McCmColor, MxCpp, McGePoint3d, McGeMatrix3d } from "mxcad";
    const mxcad = MxCpp.getCurrentMxCAD();
    const basePt = new McGePoint3d(0,0,0)
    // 旋转前
    const id = mxcad.drawText(0,0,'test',10,0, McDb.TextHorzMode.kTextLeft, McDb.TextVertMode.kTextBottom);
    const text = id.getMcDbEntity();
    // 方式一:快捷调用缩放函数scaleEntity
    text.scaleEntity(basePt,0.5);
    ​
    // 方式二:调用缩放矩阵
    const matrix = new McGeMatrix3d();
    matrix.setToScaling(0.5,basePt);
    text.transformBy(matrix);
    ​
    text.trueColor = new McCmColor(255,0,0)
    mxcad.updateDisplay();

三、综合实战:带动态预览的批量文本移动

为了串联选择、过滤、变换及交互体验,我们实现一个核心场景:批量移动全图文字,并支持拖拽预览

本案例引入MxCADUiPrPointsetUserDraw回调,实现“所见即所得”的交互效果。

image-20260427160635710

核心逻辑流程

  1. 精准筛选:利用MxCADResbuf构建针对TEXTMTEXT的过滤器,通过MxCADSelectionSet获取全图目标实体。

  2. 基点锁定:使用MxCADUiPrPoint获取用户指定的移动基点。

  3. 动态预览:在鼠标移动过程中,通过setUserDraw实时克隆并绘制文字的“幻影”,提供视觉反馈。

  4. 执行变换:用户确认目标点后,对原始实体应用真实的move变换并刷新视图。

代码实现:

import { MxCADSelectionSet, MxCADResbuf, MxCADUiPrPoint, McDbEntity, MxCpp, McDbLine } from "mxcad"
import { MxFun } from "mxdraw";
​
async function Mx_moveAllText() {
    const mxcad = MxCpp.getCurrentMxCAD();
    
    // 1. 构建过滤器:仅筛选 TEXT 和 MTEXT
    const filter = new MxCADResbuf();
    filter.AddMcDbEntityTypes("TEXT,MTEXT");
    
    // 2. 获取选择集并缓存实体
    const ss = new MxCADSelectionSet();
    ss.allSelect(filter);
    
    const entities: McDbEntity[] = [];
    ss.forEach(id => {
        mxcad.addCurrentSelect(id); // 高亮显示
        const text = id.getMcDbEntity();
        if (text) entities.push(text);
    })
​
    // 3. 交互:获取基点
    const getPoint = new MxCADUiPrPoint();
    getPoint.setMessage("请选择移动基点");
    const basePt = await getPoint.go();
    if (!basePt) return;
​
    // 4. 核心:动态预览 (UserDraw)
    getPoint.setMessage("请选择移动终点");
    getPoint.setUserDraw((pt, pw) => {
        // 绘制辅助线
        pw.drawMcDbEntity(new McDbLine(basePt, pt));
        
        // 克隆实体并绘制“幻影”
        entities.forEach(text => {
            const _text = text.clone() as McDbEntity;
            _text.move(basePt, pt); // 仅移动克隆体
            pw.drawMcDbEntity(_text);
        })
    });
​
    // 5. 确认目标点并执行真实变换
    const movePt = await getPoint.go();
    if (!movePt) return;
    entities.forEach(text => {
        text.move(basePt, movePt);
    }); 
    mxcad.clearMxCurrentSelect();
    mxcad.updateDisplay();
}
​
MxFun.addCommand("Mx_moveAllText", Mx_moveAllText);

四、 总结与进阶思考

通过本文的深度解析,我们不仅掌握了 MxCAD 图形编辑的具体技法,更理解了其背后的数学原理。

  • 选择机制是入口。利用 MxCADSelectionSet 和过滤器,我们实现了从“人找图”到“代码找图”的跨越,特别是构建过滤器的能力,是实现自动化脚本的关键。

  • 变换原理是核心。深入理解基于矩阵的几何变换,让我们明白快捷方法背后的逻辑。虽然快捷方法(如 moverotate)在日常开发中足够使用,但在处理复杂的复合变换时,直接操作矩阵才是效率的最高境界。

  • 夹点交互是用户体验的灵魂。解析 CAD 特有的夹点编辑流程(即“获取-拖拽-更新”的闭环),能让我们的应用拥有原生 CAD 般流畅的交互体验。