(WEB在线CAD)在线CAD如何实现图形识别功能

打印 上一主题 下一主题

主题 863|帖子 863|积分 2589

媒介

     CAD图形识别功能可资助用户快速识别和提取CAD图纸中的各种图形,从而加速计划过程。可应用在识别与分类阶段,自动识别图纸中的不同元素,通过特定特征举行区分,减少了手动分类的工作量;也可应用在数量统计阶段,统计图纸中各种构件的数量用于预算;还可运用在图纸定位和应用阶段,快速定位图纸上的特定元素,便于快速查找和修改。
     mxcad 为用户提供了图形识别功能和API,用户可根据自身需求对该功能举行拓展或二次开发,更多开发文档关注公众号:空想云图网页CAD。
     图形识别步调

     1. 打开mxcad在线示例demo:demo.mxdraw3d.com:3000/mxcad/。
     2. 点击【工具(A)】菜单栏,找到图形识别功能,选择【图形识别】按钮,如下图:

     3.根据命令行提示,点击鼠标左键点选图元或拉框选择必要识别的图形(图形识别功能现在支持识别直线类、多段线类、弧线类、圆类,以及块这五类图元),如下图:
     

     4.点击右键结束选择后,在弹出的图形识别框内设置查找图形详情,设置图形名称可方便后续查找已识别图形;设置重新选择图形时,会覆盖当前选中图形;设置区域查找时,必要用户框选查找范围,若未框选范围则会默以为全图纸查找图形,如下图:
     

     5. 在图形识别框内点击【开始识别】按钮,开始在目的范围内查找图形,并将查找结果展示在图形识别列表中。点击图形识别列表下的坐标对应的【查看】按钮会自动定位到对应的图形位置,并圈选出目的图形,如下图:

     6. 当识别多个图形后,可点击目的图形统计表格对应的操作列中的【详情】按钮查看识别详情,图形坐标列表将转换为该目的图形的识别结果,如下图:

     识别注意事项:

           如果必要识别的图形较为复杂,为保证识别速率与精度,我们需尽大概查找图形中的特别部门而不是选取整个图形(图形对象过多时大概会导致卡顿,影响用户利用服从)。
      图形识别支持区域选择,用户可根据自身需求准确定位图形筛选区域。
          功能开发

     mxcad 图形识别功能中运用的焦点头脑是通过[McDbEntity]实体中每个实体的特征在图纸中举行查找,查找的实体中包括了[直线类]、[多段线类] 、[弧线类]、[圆类],以及[块]。
     下列为基于mxcad 封装的图形识别类 SearchSamePattern 用户可根据该类的利用方法利用 mxcad 举行二次开发,代码如下:
                                   登录后复制                        
  1. import {
  2.     DxfCode, McCmColor, McDbArc, McDbBlockReference, McDbCircle, McDbLine, McDbPolyline, McDbWipeout, McGePoint3d,
  3.     McGePoint3dArray, McGeVector3d, MxCADResbuf, MxCADSelectionSet, MxCADUtility, MxCpp
  4. } from "mxcad";
  5. import { MxFun } from "mxdraw";
  6. export class SearchSamePattern {
  7.     /** 识别图元数 */
  8.     private objectCount: number = 0;
  9.     /** 选择图形集合 Map<className,[Ent]>*/
  10.     private selectObjects: any;
  11.     private dTol = 0.000001;
  12.     /**
  13.      * pt1:左下角
  14.      * pt2:右上角
  15.      * pt3:左上角
  16.      * pt4:右下角
  17.      */
  18.     private pt1: McGePoint3d;
  19.     private pt2: McGePoint3d;
  20.     private pt3: McGePoint3d;
  21.     private pt4: McGePoint3d;//包围盒大小
  22.     private pl: McDbPolyline;
  23.     /** 识别图形类名集合 [string] */
  24.     private classNames: any
  25.     /** 识别图形图片地址 */
  26.     private patternImgUrl: String
  27.     /** 识别对象详情  Map<ClassName,[{}]>*/
  28.     private objectsDetails: any = {};
  29.     // 下列为识别结果数据
  30.     /** 识别后的图形位置数组集合 */;
  31.     private graphBoxsPos: any[] = [];
  32.     private formPt: McGePoint3d;
  33.     private toPt: McGePoint3d;
  34.     /** 点精度值 */
  35.     private dTolPt: any;
  36.     /** 识别后图形列表 */
  37.     private patternList: any = {};
  38.     /** 选择的图形集合 */
  39.     public setSelectset(ss: MxCADSelectionSet): Promise<String> {
  40.         if (!ss?.count()) return;
  41.         const mxcad = MxCpp.getCurrentMxCAD();
  42.         // 获取当前图纸的空间块表记录包围盒
  43.         const { maxPt, minPt } = mxcad.getDatabase().currentSpace.getBoundingBox();
  44.         const currentDrawOrder = mxcad.getDatabase().currentSpace.getMinMaxDrawOrder()
  45.         const n = MxFun.screenCoordLong2Doc(Math.abs(maxPt.x - minPt.x));
  46.         minPt.x -= n; minPt.y -= n; maxPt.x += n; maxPt.y += n;
  47.         let points = new McGePoint3dArray();
  48.         points.append(minPt);
  49.         points.append(new McGePoint3d(minPt.x, maxPt.y, 0));
  50.         points.append(new McGePoint3d(maxPt.x, maxPt.y, 0));
  51.         points.append(new McGePoint3d(maxPt.x, minPt.y, 0));
  52.         this.objectCount = ss.count();
  53.         // 获取遮罩层drawOrder
  54.         let wipeout = new McDbWipeout
  55.         wipeout.setVertices(points);
  56.         const wipeoutId = mxcad.drawEntity(wipeout);
  57.         const e = wipeoutId.getMcDbEntity();
  58.         e.drawOrder = currentDrawOrder.maxDrawOrder + 1;
  59.         this.selectObjects = {};
  60.         const oldDrawOder = [];
  61.         ss.forEach(id => {
  62.             const ent = id.getMcDbEntity();
  63.             /** 记录识别图形的信息 */
  64.             if (!this.selectObjects[ent.objectName]) this.selectObjects[ent.objectName] = [];
  65.             this.selectObjects[ent.objectName].push(ent);
  66.             if (ent.objectName === 'McDbLine') {
  67.                 if (!this.objectsDetails['McDbLine']) this.objectsDetails['McDbLine'] = [];
  68.                 this.objectsDetails['McDbLine'].push({ entity: ent, length: (ent as McDbLine).getLength().val });
  69.             } else if (ent.objectName === 'McDbArc') {
  70.                 if (!this.objectsDetails['McDbArc']) this.objectsDetails['McDbArc'] = [];
  71.                 const length = (ent as McDbArc).getLength().val;
  72.                 const { bugle } = this.getBugle((ent as McDbArc), length)
  73.                 this.objectsDetails['McDbArc'].push({ entity: ent, length, bugle });
  74.             } else if (ent.objectName === 'McDbCircle') {
  75.                 if (!this.objectsDetails['McDbCircle']) this.objectsDetails['McDbCircle'] = [];
  76.                 const radius = (ent as McDbCircle).radius;
  77.                 this.objectsDetails['McDbCircle'].push({ entity: ent, radius });
  78.             } else if (ent.objectName === 'McDbBlockReference') {
  79.                 if (!this.objectsDetails['McDbBlockReference']) this.objectsDetails['McDbBlockReference'] = [];
  80.                 const blkName = (ent as McDbBlockReference).blockName;
  81.                 this.objectsDetails['McDbBlockReference'].push({ entity: ent, blkName });
  82.             } else if (ent.objectName === 'McDbPolyline') {
  83.                 if (!this.objectsDetails['McDbPolyline']) this.objectsDetails['McDbPolyline'] = [];
  84.                 const length = (ent as McDbPolyline).getLength().val;
  85.                 this.objectsDetails['McDbPolyline'].push({ entity: ent, length });
  86.             }
  87.             /** 渲染顺序 */
  88.             oldDrawOder.push({ obj: ent, drawOrder: ent.drawOrder });
  89.             ent.drawOrder = e.drawOrder + 1;
  90.             const { maxPt, minPt } = ent.getBoundingBox();
  91.             if (!this.pt1 || !this.pt2) {
  92.                 this.pt1 = minPt;
  93.                 this.pt2 = maxPt;
  94.             } else {
  95.                 if (minPt.x < this.pt1.x) this.pt1.x = minPt.x;
  96.                 if (minPt.y < this.pt1.y) this.pt1.y = minPt.y;
  97.                 if (maxPt.x > this.pt2.x) this.pt2.x = maxPt.x;
  98.                 if (maxPt.y > this.pt2.y) this.pt2.y = maxPt.y;
  99.             }
  100.         });
  101.         this.classNames = Object.keys(this.selectObjects);
  102.         /**
  103.          * 计算包围盒其他两个角点
  104.          */
  105.         this.pt3 = new McGePoint3d(this.pt1.x, this.pt2.y);
  106.         this.pt4 = new McGePoint3d(this.pt2.x, this.pt1.y);
  107.         /** 绘制识别图形包围盒 */
  108.         this.pl = new McDbPolyline()
  109.         this.pl.addVertexAt(this.pt1);
  110.         this.pl.addVertexAt(this.pt3);
  111.         this.pl.addVertexAt(this.pt2);
  112.         this.pl.addVertexAt(this.pt4);
  113.         this.pl.isClosed = true;
  114.         const num = MxFun.screenCoordLong2Doc(10);
  115.         this.pt1.x -= num; this.pt1.y -= num; this.pt2.x += num; this.pt2.y += num;
  116.         // 生成预览图
  117.         let w = Math.abs(this.pt1.x - this.pt2.x);
  118.         let h = Math.abs(this.pt1.y - this.pt2.y);
  119.         if (w < 1 || h < 1) return;
  120.         let jpg_width = 300;
  121.         let jpg_height = 240;
  122.         return new Promise<String>((resolve, reject) => {
  123.             MxFun.getCurrentDraw().createCanvasImageData(
  124.                 (imageData: String) => {
  125.                     this.patternImgUrl = imageData;
  126.                     // 恢复绘制顺序
  127.                     oldDrawOder.forEach(item => {
  128.                         item.obj.drawOrder = item.drawOrder;
  129.                     })
  130.                     wipeoutId.erase();
  131.                     resolve(imageData)
  132.                 },
  133.                 {
  134.                     width: jpg_width, // 图片宽
  135.                     height: jpg_height, // 图片高
  136.                     range_pt1: this.pt1.toVector3(), // 截图范围角点1
  137.                     range_pt2: this.pt2.toVector3(), // 截图范围角点2
  138.                 }
  139.             );
  140.         });
  141.     };
  142.     // 开始识别图形
  143.     /**
  144.      * 1.查找初始包围盒
  145.      * 2.筛选符合条件的包围盒
  146.      * 3.比较包围盒内的每一个图元与需要识别的图元是否匹配
  147.      */
  148.     public identifyGraphics(corner1?: McGePoint3d, corner2?: McGePoint3d): any {
  149.         /** 记录图形缩略图 */
  150.         this.patternList.patternImgUrl = this.patternImgUrl;
  151.         /**初始化图形位置列表 */
  152.         this.graphBoxsPos.length = 0;
  153.         const mxcad = MxCpp.getCurrentMxCAD();
  154.         this.dTolPt = mxcad.mxdraw.viewCoordLong2Cad(0.5);// 设置精度值
  155.         if (!this.classNames) return;
  156.         const array = this.classNames.map(name => this.selectObjects[name].length);
  157.         const minIndex = array.findIndex(element => element === Math.min(...array));
  158.         const str = this.classNames[minIndex];
  159.         /** 识别块 */
  160.         if (str === 'McDbBlockReference') {
  161.             const refBlk = this.selectObjects['McDbBlockReference'][0].clone() as McDbBlockReference;
  162.             const blkName = refBlk.blockName; // 图块名
  163.             const { position } = this.getBlkMidPt(refBlk);
  164.             this.formPt = position;
  165.             const rotate = refBlk.rotation;
  166.             // 设置图块过滤器
  167.             const filter = new MxCADResbuf([DxfCode.kEntityType, "INSERT"])
  168.             const ss = new MxCADSelectionSet()
  169.             if (corner1 && corner2) {
  170.                 // 局部选择
  171.                 ss.crossingSelect(corner1.x, corner1.y, corner2.x, corner2.y, filter);
  172.             } else {
  173.                 // 全局选择
  174.                 ss.allSelect(filter);
  175.             };
  176.             // 筛选出符合条件的块
  177.             const boxs: any[] = [];
  178.             ss.forEach(id => {
  179.                 const _blk = id.getMcDbEntity().clone() as McDbBlockReference;
  180.                 /** 块名相等=》计算旋转角度=》计算包围盒大小 */
  181.                 if (blkName === _blk.blockName) {
  182.                     const _rotate = _blk.rotation;
  183.                     const angle = rotate >= 0 ? _rotate - rotate : rotate - _rotate;
  184.                     const { position: _position, minPt, maxPt } = this.getBlkMidPt(_blk);
  185.                     if (this.classNames.length === 1) {
  186.                         this.toPt = _position;
  187.                         this.identificationBBox(minPt, maxPt, 0)
  188.                     } else {
  189.                         // 平移旋转初始包围盒。计算出最新包围盒的大小
  190.                         const _pl = this.pl.clone() as McDbPolyline;
  191.                         _pl.move(this.formPt, _position);
  192.                         _pl.rotate(_position, angle);
  193.                         let x = [], y = [];
  194.                         for (let i = 0; i < _pl.numVerts(); i++) {
  195.                             const pt = _pl.getPointAt(i).val;
  196.                             x.push(pt.x);
  197.                             y.push(pt.y);
  198.                         }
  199.                         const _minPt = new McGePoint3d(Math.min(...x) - 1, Math.min(...y) - 1);
  200.                         const _maxPt = new McGePoint3d(Math.max(...x) + 1, Math.max(...y) + 1);
  201.                         const res = boxs.filter(item => {
  202.                             let ret1 = _minPt.distanceTo(item.pt1) < this.dTolPt && _maxPt.distanceTo(item.pt2) < this.dTolPt
  203.                             let ret2 = _minPt.distanceTo(item.pt2) < this.dTolPt && _maxPt.distanceTo(item.pt1) < this.dTolPt
  204.                             return ret1 || ret2
  205.                         })
  206.                         if (!res.length) {
  207.                             boxs.push({ pt1: _minPt, pt2: _maxPt });
  208.                             this.toPt = _position;
  209.                             // MxCpp.getCurrentMxCAD().drawLine(_maxPt.x, _maxPt.y, _minPt.x, _minPt.y);
  210.                             this.identificationBBox(_minPt, _maxPt, angle);
  211.                         }
  212.                     }
  213.                 }
  214.             });
  215.         }
  216.         /** 识别弧线 */
  217.         else if (str === 'McDbArc') {
  218.             // 识别直线
  219.             const refArc = this.selectObjects['McDbArc'][0].clone() as McDbArc;
  220.             const length = refArc.getLength().val; // 弧线线长度
  221.             // 圆弧凸度
  222.             const { bugle, midPt } = this.getBugle(refArc, length);
  223.             const center = refArc.center;
  224.             const vec = center.sub(midPt);
  225.             // 设置弧线过滤器
  226.             const filter = new MxCADResbuf([DxfCode.kEntityType, "ARC"])
  227.             const ss = new MxCADSelectionSet()
  228.             if (corner1 && corner2) {
  229.                 // 局部选择
  230.                 ss.crossingSelect(corner1.x, corner1.y, corner2.x, corner2.y, filter);
  231.             } else {
  232.                 // 全局选择
  233.                 ss.allSelect(filter);
  234.             };
  235.             // 筛选出符合条件的弧线
  236.             const boxs: any[] = [];
  237.             ss.forEach(id => {
  238.                 const _arc = id.getMcDbEntity().clone() as McDbArc;
  239.                 const _length = _arc.getLength().val;
  240.                 const { bugle: _bugle, midPt: _midPt } = this.getBugle(_arc, _length);
  241.                 /** 筛选出圆弧凸度与长度相同的弧线*/
  242.                 if (Math.abs(_length - length) < this.dTol && Math.abs(_bugle - bugle) < this.dTol) {
  243.                     /** 分两种情况
  244.                      * 1.直接旋转平移得到
  245.                      * 2.镜像得到=》移动到目标位置+旋转角度+镜像翻转=》比较起始点位置
  246.                      */
  247.                     // 平移+旋转
  248.                     const _center = _arc.center;
  249.                     const _vec = _center.sub(_midPt);
  250.                     const angle = _vec.angleTo2(vec, McGeVector3d.kNegateZAxis);
  251.                     // 旋转平移初始包围盒。计算出最新包围盒的大小
  252.                     const _pl = this.pl.clone() as McDbPolyline;
  253.                     _pl.move(midPt, _midPt);
  254.                     _pl.rotate(_midPt, angle);
  255.                     let x = [], y = [];
  256.                     for (let i = 0; i < _pl.numVerts(); i++) {
  257.                         const pt = _pl.getPointAt(i).val;
  258.                         x.push(pt.x);
  259.                         y.push(pt.y);
  260.                     }
  261.                     const _minPt = new McGePoint3d(Math.min(...x) - 1, Math.min(...y) - 1);
  262.                     const _maxPt = new McGePoint3d(Math.max(...x) + 1, Math.max(...y) + 1);
  263.                     const res = boxs.filter(item => {
  264.                         let ret1 = _minPt.distanceTo(item.pt1) < this.dTolPt && _maxPt.distanceTo(item.pt2) < this.dTolPt
  265.                         let ret2 = _minPt.distanceTo(item.pt2) < this.dTolPt && _maxPt.distanceTo(item.pt1) < this.dTolPt
  266.                         let ret3 = _midPt.distanceTo(item.midPt) < this.dTolPt
  267.                         return (ret1 || ret2) && ret3
  268.                     })
  269.                     if (!res.length) {
  270.                         boxs.push({ pt1: _minPt, pt2: _maxPt, midPt: _midPt });
  271.                         this.toPt = _midPt;
  272.                         this.formPt = midPt;
  273.                         this.identificationBBox(_minPt, _maxPt, angle);
  274.                     }
  275.                 }
  276.             });
  277.         }
  278.         /** 识别直线 */
  279.         else if (str === 'McDbLine') {
  280.             // 识别直线
  281.             const refLine = this.selectObjects['McDbLine'][0].clone() as McDbLine;
  282.             const length = refLine.getLength().val; // 直线长度
  283.             const vec = refLine.endPoint.sub(refLine.startPoint); // 直线角度
  284.             // 设置直线过滤器
  285.             const filter = new MxCADResbuf([DxfCode.kEntityType, "LINE"])
  286.             const ss = new MxCADSelectionSet()
  287.             if (corner1 && corner2) {
  288.                 // 局部选择
  289.                 ss.crossingSelect(corner1.x, corner1.y, corner2.x, corner2.y, filter);
  290.             } else {
  291.                 // 全局选择
  292.                 ss.allSelect(filter);
  293.             };
  294.             // 筛选出符合条件的直线
  295.             const lineArr: McDbLine[] = [];
  296.             ss.forEach(id => {
  297.                 const line = id.getMcDbEntity().clone() as McDbLine;
  298.                 const _length = line.getLength().val;
  299.                 /**
  300.                  * 1.未旋转
  301.                  * 2.旋转过
  302.                  */
  303.                 if (Math.abs(_length - length) < this.dTol) {
  304.                     lineArr.push(line);
  305.                 }
  306.             });
  307.             // 筛选出符合条件的直线后,根据包围盒范围再次筛选出符合条件的直线组合
  308.             const boxs: any[] = [];
  309.             if (lineArr.length > 0) {
  310.                 lineArr.forEach((item) => {
  311.                     /**
  312.                      * 将要识别的图形进行平移+旋转到目标位置
  313.                      */
  314.                     const ptArr = [item.startPoint, item.endPoint];
  315.                     ptArr.forEach((point, index) => {
  316.                         const _line = refLine.clone() as McDbLine;
  317.                         _line.move(refLine.startPoint, point);
  318.                         const _vec = ptArr[1 - index].sub(point);
  319.                         const angle = _vec.angleTo2(vec, McGeVector3d.kNegateZAxis);
  320.                         _line.rotate(point, angle)
  321.                         const pt = _line.endPoint;
  322.                         const _pl = this.pl.clone() as McDbPolyline;
  323.                         _pl.move(refLine.startPoint, point);
  324.                         _pl.rotate(point, angle);
  325.                         const _refBoxPt1 = _pl.getPointAt(0).val;
  326.                         const _refBoxPt2 = _pl.getPointAt(1).val;
  327.                         const refVec1 = _refBoxPt1.sub(_line.startPoint);
  328.                         const refVec2 = _refBoxPt2.sub(_line.startPoint);
  329.                         if (pt.distanceTo(ptArr[1 - index]) < this.dTolPt && refVec1.isEqualTo(_refBoxPt1.sub(point)) && refVec2.isEqualTo(_refBoxPt2.sub(point))) {
  330.                             let x = [], y = [];
  331.                             for (let i = 0; i < _pl.numVerts(); i++) {
  332.                                 const pt = _pl.getPointAt(i).val;
  333.                                 x.push(pt.x);
  334.                                 y.push(pt.y);
  335.                             }
  336.                             const _minPt = new McGePoint3d(Math.min(...x) - 1, Math.min(...y) - 1);
  337.                             const _maxPt = new McGePoint3d(Math.max(...x) + 1, Math.max(...y) + 1);
  338.                             const res = boxs.filter(item => {
  339.                                 let r1 = _minPt.distanceTo(item.pt1) < this.dTolPt && _maxPt.distanceTo(item.pt2) < this.dTolPt
  340.                                 let r2 = _minPt.distanceTo(item.pt2) < this.dTolPt && _maxPt.distanceTo(item.pt1) < this.dTolPt
  341.                                 return r1 || r2
  342.                             })
  343.                             if (!res.length) {
  344.                                 boxs.push({ pt1: _minPt, pt2: _maxPt });
  345.                                 this.toPt = point;
  346.                                 this.formPt = refLine.startPoint;
  347.                                 // MxCpp.getCurrentMxCAD().drawLine(_maxPt.x, _maxPt.y, _minPt.x, _minPt.y);
  348.                                 this.identificationBBox(_minPt, _maxPt, angle);
  349.                             }
  350.                         }
  351.                     })
  352.                 })
  353.             };
  354.         }
  355.         /** 识别圆 */
  356.         else if (str === 'McDbCircle') {
  357.             const refCricle = this.selectObjects['McDbCircle'][0].clone() as McDbCircle;
  358.             const radius = refCricle.radius; // 圆半径
  359.             // 设置圆过滤器
  360.             const filter = new MxCADResbuf([DxfCode.kEntityType, "CIRCLE"])
  361.             const ss = new MxCADSelectionSet()
  362.             if (corner1 && corner2) {
  363.                 // 局部选择
  364.                 ss.crossingSelect(corner1.x, corner1.y, corner2.x, corner2.y, filter);
  365.             } else {
  366.                 // 全局选择
  367.                 ss.allSelect(filter);
  368.             };
  369.             // 筛选出符合条件的圆
  370.             ss.forEach(id => {
  371.                 const _circle = id.getMcDbEntity().clone() as McDbCircle;
  372.                 const _radius = _circle.radius;
  373.                 /** 筛选出圆半径相同的圆*/
  374.                 if (Math.abs(_radius - radius) < this.dTol) {
  375.                     const _center = _circle.center;
  376.                     this.toPt = _center;
  377.                     this.formPt = refCricle.center;
  378.                     // 平移初始包围盒。计算出最新包围盒的大小
  379.                     const _pl = this.pl.clone() as McDbPolyline;
  380.                     _pl.move(this.formPt, this.toPt);
  381.                     let x = [], y = [];
  382.                     for (let i = 0; i < _pl.numVerts(); i++) {
  383.                         const pt = _pl.getPointAt(i).val;
  384.                         x.push(pt.x);
  385.                         y.push(pt.y);
  386.                     }
  387.                     const _minPt = new McGePoint3d(Math.min(...x) - 1, Math.min(...y) - 1);
  388.                     const _maxPt = new McGePoint3d(Math.max(...x) + 1, Math.max(...y) + 1);
  389.                     // MxCpp.getCurrentMxCAD().drawLine(_maxPt.x, _maxPt.y, _minPt.x, _minPt.y);
  390.                     this.identificationBBox(_minPt, _maxPt, 0);
  391.                 }
  392.             });
  393.         }
  394.         /** 识别多段线 */
  395.         else if (str === 'McDbPolyline') {
  396.             /** 长度+顶点数+顶点对应的凸度相等=》旋转+平移后的顶点相等+有凸度线段的中点相等*/
  397.             const refPoly = this.selectObjects['McDbPolyline'][0].clone() as McDbPolyline;
  398.             const length = refPoly.getLength().val;
  399.             const { lengthArr, bugleArr, vertNum, vec, point } = this.getPlDetails(refPoly);
  400.             // 设置多段线过滤器
  401.             const filter = new MxCADResbuf([DxfCode.kEntityType, "LWPOLYLINE"])
  402.             const ss = new MxCADSelectionSet()
  403.             if (corner1 && corner2) {
  404.                 // 局部选择
  405.                 ss.crossingSelect(corner1.x, corner1.y, corner2.x, corner2.y, filter);
  406.             } else {
  407.                 // 全局选择
  408.                 ss.allSelect(filter);
  409.             };
  410.             // 筛选出符合条件的多段线
  411.             const boxs: any[] = [];
  412.             ss.forEach(id => {
  413.                 const _poly = id.getMcDbEntity().clone() as McDbPolyline;
  414.                 const _length = _poly.getLength().val;
  415.                 /** 筛选 长度+顶点数+顶点对应的凸度 相同的多段线*/
  416.                 if (Math.abs(_length - length) < this.dTol && _poly.isClosed === refPoly.isClosed) {
  417.                     const { lengthArr: _lengthArr, bugleArr: _bugleArr, vertNum: _vertNum, vec: _vec, point: _point } = this.getPlDetails(_poly);
  418.                     const revBugleArr = _bugleArr.map(item => item === 0 ? item : -item);
  419.                     // 全等
  420.                     const r1 = lengthArr.toString() === _lengthArr.toString() && bugleArr.toString() === _bugleArr.toString();
  421.                     let r2 = false;
  422.                     if (!r1) {
  423.                         // 反向
  424.                         r2 = lengthArr.toString() === [..._lengthArr].reverse().toString() && bugleArr.toString() === [...revBugleArr].reverse().toString();
  425.                     }
  426.                     const r3 = vertNum === _vertNum;
  427.                     // 镜像
  428.                     const r4 = lengthArr.toString() === _lengthArr.toString() && bugleArr.toString() === [...revBugleArr].reverse().toString();
  429.                     if ((r1 || r2 || r4) && r3) {
  430.                         const poly = refPoly.clone() as McDbPolyline;
  431.                         const angle1 = vec.angleTo2(McGeVector3d.kXAxis, McGeVector3d.kNegateZAxis);
  432.                         // 如果是反向则方向取反
  433.                         const angle2 = (r2 ? _vec.negate() : _vec).angleTo2(McGeVector3d.kXAxis, McGeVector3d.kNegateZAxis);
  434.                         const angle = angle2 - angle1;
  435.                         poly.move(point, _point);
  436.                         poly.rotate(_point, angle);
  437.                         poly.trueColor = new McCmColor(255, 0, 0);
  438.                         let num = 0;
  439.                         for (let i = 0; i < vertNum; i++) {
  440.                             const pt = poly.getPointAt(i).val;
  441.                             const width = poly.getWidthsAt(i);
  442.                             const _pt = r2 ? _poly.getPointAt(vertNum - 1 - i).val : _poly.getPointAt(i).val;
  443.                             const _width = r2 ? _poly.getWidthsAt(vertNum - 1 - i) : _poly.getWidthsAt(i);
  444.                             if (pt.distanceTo(_pt) < this.dTolPt && width.val1 === _width.val1 && width.val2 === _width.val2) {
  445.                                 num += 1
  446.                             } else {
  447.                                 // 两个点且反向的情况
  448.                                 if (vertNum === 2 && i === 0) {
  449.                                     const _pt1 = _poly.getPointAt(0).val;
  450.                                     const _pt2 = _poly.getPointAt(1).val;
  451.                                     const pt2 = poly.getPointAt(1).val;
  452.                                     const _width = _poly.getWidthsAt(0);
  453.                                     if (pt2.distanceTo(_pt2) < this.dTolPt && pt.distanceTo(_pt1) < this.dTolPt && width.val1 === _width.val2 && width.val2 === _width.val1) {
  454.                                         num += 2;
  455.                                     }
  456.                                 }
  457.                             }
  458.                         };
  459.                         if (num === vertNum) {
  460.                             // 旋转平移初始包围盒。计算出最新包围盒的大小
  461.                             const _pl = this.pl.clone() as McDbPolyline;
  462.                             _pl.move(point, _point);
  463.                             _pl.rotate(_point, angle);
  464.                             let x = [], y = [];
  465.                             for (let i = 0; i < _pl.numVerts(); i++) {
  466.                                 const pt = _pl.getPointAt(i).val;
  467.                                 x.push(pt.x);
  468.                                 y.push(pt.y);
  469.                             }
  470.                             const _minPt = new McGePoint3d(Math.min(...x) - 1, Math.min(...y) - 1);
  471.                             const _maxPt = new McGePoint3d(Math.max(...x) + 1, Math.max(...y) + 1);
  472.                             const res = boxs.filter(item => {
  473.                                 let ret1 = _minPt.distanceTo(item.pt1) < this.dTolPt && _maxPt.distanceTo(item.pt2) < this.dTolPt
  474.                                 let ret2 = _minPt.distanceTo(item.pt2) < this.dTolPt && _maxPt.distanceTo(item.pt1) < this.dTolPt
  475.                                 return ret1 || ret2
  476.                             })
  477.                             if (!res.length) {
  478.                                 boxs.push({ pt1: _minPt, pt2: _maxPt });
  479.                                 this.toPt = _point;
  480.                                 this.formPt = point;
  481.                                 // MxCpp.getCurrentMxCAD().drawLine(_maxPt.x, _maxPt.y, _minPt.x, _minPt.y);
  482.                                 this.identificationBBox(_minPt, _maxPt, angle);
  483.                             }
  484.                         }
  485.                     }
  486.                 }
  487.             });
  488.         }
  489.         /** 返回识别列表 */
  490.         return this.patternList;
  491.     }
  492.     // 计算块中心点
  493.     private getBlkMidPt = (blkRef: McDbBlockReference) => {
  494.         const { minPt, maxPt } = blkRef.getBoundingBox();
  495.         const pt = minPt.clone().addvec(maxPt.sub(minPt).normalize().mult(maxPt.distanceTo(minPt) / 2))
  496.         return { position: pt, minPt, maxPt }
  497.     }
  498.     // 计算凸度
  499.     private getBugle = (arc: McDbArc, length: number) => {
  500.         const midPt = arc.getPointAtDist(length / 2).val;
  501.         const bugle = MxCADUtility.calcBulge(arc.getPointAtDist(0).val, midPt, arc.getPointAtDist(length).val).val;
  502.         return { bugle, midPt }
  503.     }
  504.     // 计算多段线的每一段线的长度和凸度
  505.     private getPlDetails = (pl: McDbPolyline) => {
  506.         const vertNum = pl.numVerts();
  507.         const lengthArr: number[] = [];
  508.         const bugleArr: number[] = [];
  509.         let point1: McGePoint3d, point2: McGePoint3d;
  510.         for (let i = 0; i < vertNum; i++) {
  511.             if (i < vertNum - 1) {
  512.                 const p1 = pl.getPointAt(i).val;
  513.                 const p2 = pl.getPointAt(i + 1).val;
  514.                 const length = pl.getDistAtPoint(p2).val - pl.getDistAtPoint(p1).val;
  515.                 const bugle = pl.getBulgeAt(i);
  516.                 lengthArr.push(Number(length.toFixed(6)));
  517.                 bugleArr.push(Number(bugle.toFixed(6)));
  518.                 if (i === 0) {
  519.                     point1 = p1;
  520.                 }
  521.                 if (i === vertNum - 2) {
  522.                     point2 = p2;
  523.                 }
  524.             }
  525.         };
  526.         const vec = point2.sub(point1)// 多段线角度
  527.         const point = point1.clone().addvec(point2.sub(point1).normalize().mult(point2.distanceTo(point1) / 2))
  528.         return { lengthArr, bugleArr, vertNum, vec, point }
  529.     }
  530.     // 将找到的实体数组与需要识别的实体数组比对
  531.     private comparisonPhysical = (objects: any, maxPt: McGePoint3d, minPt: McGePoint3d, angle: number): any => {
  532.         const calssNames = Object.keys(this.selectObjects);
  533.         if (!calssNames) return;
  534.         let num = 0;
  535.         if (calssNames.includes('McDbLine')) {
  536.             let ents = objects['McDbLine'];
  537.             const lineObjects = this.objectsDetails['McDbLine'];
  538.             for (let i = 0; i < lineObjects.length; i++) {
  539.                 const element = lineObjects[i];
  540.                 let _line = (element.entity as McDbLine).clone() as McDbLine;
  541.                 _line.move(this.formPt, this.toPt);
  542.                 _line.rotate(this.toPt, angle);
  543.                 const indexArr: number[] = [];
  544.                 const mLineArr = ents.filter((item: McDbLine, index: number) => {
  545.                     if (Math.abs(element.length - item.getLength().val) < this.dTol) {
  546.                         let r1 = item.startPoint.distanceTo(_line.startPoint) < this.dTolPt && item.endPoint.distanceTo(_line.endPoint) < this.dTolPt;
  547.                         let r2 = item.startPoint.distanceTo(_line.endPoint) < this.dTolPt && item.endPoint.distanceTo(_line.startPoint) < this.dTolPt;
  548.                         if (r1 || r2) indexArr.push(index);
  549.                         return r1 || r2;
  550.                     }
  551.                 });
  552.                 if (mLineArr.length > 0) {
  553.                     num += 1;
  554.                     ents.splice(indexArr[0], 1);
  555.                     ents = [...ents];
  556.                 } else {
  557.                     break;
  558.                 }
  559.             }
  560.         };
  561.         if (calssNames.includes('McDbArc')) {
  562.             let ents = objects['McDbArc'];
  563.             const arcObjects = this.objectsDetails['McDbArc'];
  564.             for (let i = 0; i < arcObjects.length; i++) {
  565.                 const element = arcObjects[i];
  566.                 let _arc = (element.entity as McDbArc).clone() as McDbArc;
  567.                 _arc.move(this.formPt, this.toPt);
  568.                 _arc.rotate(this.toPt, angle);
  569.                 const startPoint = _arc.getPointAtDist(0).val;
  570.                 const endPoint = _arc.getPointAtDist(element.length).val;
  571.                 const indexArr: number[] = [];
  572.                 const mArcArr = ents.filter((item: McDbArc, index: number) => {
  573.                     const _length = item.getLength().val;
  574.                     const { bugle: _bugle } = this.getBugle(item, _length)
  575.                     if (Math.abs(element.length - item.getLength().val) < this.dTol && Math.abs(_bugle - element.bugle) < this.dTol) {
  576.                         const _startPoint = item.getPointAtDist(0).val;
  577.                         const _endPoint = item.getPointAtDist(_length).val;
  578.                         let r1 = startPoint.distanceTo(_startPoint) < this.dTolPt && endPoint.distanceTo(_endPoint) < this.dTolPt;
  579.                         let r2 = startPoint.distanceTo(_endPoint) < this.dTolPt && endPoint.distanceTo(_startPoint) < this.dTolPt;
  580.                         if (r1 || r2) {
  581.                             indexArr.push(index);
  582.                         }
  583.                         return r1 || r2;
  584.                     }
  585.                 });
  586.                 if (mArcArr.length > 0) {
  587.                     num += 1;
  588.                     ents.splice(indexArr[0], 1);
  589.                     ents = [...ents];
  590.                 } else {
  591.                     break;
  592.                 }
  593.             }
  594.         };
  595.         if (calssNames.includes('McDbCircle')) {
  596.             let ents = objects['McDbCircle'];
  597.             const circleObjects = this.objectsDetails['McDbCircle'];
  598.             for (let i = 0; i < circleObjects.length; i++) {
  599.                 const element = circleObjects[i];
  600.                 let _circle = (element.entity as McDbCircle).clone() as McDbCircle;
  601.                 _circle.move(this.formPt, this.toPt);
  602.                 _circle.rotate(this.toPt, angle);
  603.                 const center = _circle.center;
  604.                 const radius = _circle.radius;
  605.                 const indexArr: number[] = [];
  606.                 const mCiecleArr = ents.filter((item: McDbCircle, index: number) => {
  607.                     const _center = item.center;
  608.                     const _radius = item.radius;
  609.                     const r = Math.abs(_radius - radius) < this.dTol && center.distanceTo(_center) < this.dTolPt;
  610.                     if (r) {
  611.                         indexArr.push(index)
  612.                     }
  613.                     return r;
  614.                 });
  615.                 if (mCiecleArr.length > 0) {
  616.                     num += 1;
  617.                     ents.splice(indexArr[0], 1);
  618.                     ents = [...ents];
  619.                 } else {
  620.                     break;
  621.                 }
  622.             }
  623.         };
  624.         if (calssNames.includes('McDbBlockReference')) {
  625.             /** 平移+旋转=>比对包围盒大小+块名字 */
  626.             let ents = objects['McDbBlockReference'];
  627.             const blkObjects = this.objectsDetails['McDbBlockReference'];
  628.             for (let i = 0; i < blkObjects.length; i++) {
  629.                 const element = blkObjects[i];
  630.                 let _blk = (element.entity as McDbBlockReference).clone() as McDbBlockReference;
  631.                 _blk.move(this.formPt, this.toPt);
  632.                 _blk.rotate(this.toPt, angle);
  633.                 const blkName = _blk.blockName;
  634.                 const { minPt: blkMinPt, maxPt: blkMaxPt } = this.getBlkMidPt(_blk);
  635.                 const indexArr: number[] = [];
  636.                const mArcArr = ents.filter((item: McDbBlockReference, index: number) => {
  637.                     const _blkName = item.blockName;
  638.                     if (_blkName === blkName) {
  639.                         if (this.classNames.length === 1) {
  640.                             indexArr.push(index);
  641.                             return true
  642.                         } else {
  643.                             const { minPt: _blkMinPt, maxPt: _blkMaxPt } = this.getBlkMidPt(item);
  644.                             let r1 = blkMinPt.distanceTo(_blkMinPt) < this.dTolPt && blkMaxPt.distanceTo(_blkMaxPt) < this.dTolPt;
  645.                             if (r1) {
  646.                                 indexArr.push(index);
  647.                             }
  648.                             return r1
  649.                         }
  650.                     }
  651.                 });
  652.                 if (mArcArr.length > 0) {
  653.                     num += 1;
  654.                     ents.splice(indexArr[0], 1);
  655.                     ents = [...ents];
  656.                 } else {
  657.                     return;
  658.                 }
  659.             }
  660.         }
  661.         if (calssNames.includes('McDbPolyline')) {
  662.             /** 平移+旋转=>比对凸度+点位置 */
  663.             let ents = objects['McDbPolyline'];
  664.             const plObjects = this.objectsDetails['McDbPolyline'];
  665.             for (let i = 0; i < plObjects.length; i++) {
  666.                 const element = plObjects[i];
  667.                 let _poly = (element.entity as McDbPolyline).clone() as McDbPolyline;
  668.                 _poly.move(this.formPt, this.toPt);
  669.                 _poly.rotate(this.toPt, angle);
  670.                 const { lengthArr, bugleArr, vertNum } = this.getPlDetails(_poly);
  671.                 const indexArr: number[] = [];
  672.                 const mPlArr = ents.filter((item: McDbPolyline, index: number) => {
  673.                     const _length = item.getLength().val;
  674.                     if (Math.abs(_length - element.length) < this.dTol && _poly.isClosed === _poly.isClosed) {
  675.                         const { lengthArr: _lengthArr, bugleArr: _bugleArr, vertNum: _vertNum } = this.getPlDetails(item);
  676.                         const revBugleArr = _bugleArr.map(item => item === 0 ? item : -item);
  677.                         const r1 = lengthArr.toString() === _lengthArr.toString() && bugleArr.toString() === _bugleArr.toString();
  678.                         let r2 = false;
  679.                         if (!r1) {
  680.                             r2 = lengthArr.toString() === [..._lengthArr].reverse().toString() && bugleArr.toString() === [...revBugleArr].reverse().toString();
  681.                         }
  682.                         const r3 = vertNum === _vertNum;
  683.                         if ((r1 || r2) && r3) {
  684.                             let _num = 0;
  685.                             for (let i = 0; i < vertNum; i++) {
  686.                                 const pt = _poly.getPointAt(i).val;
  687.                                 const width = _poly.getWidthsAt(i);
  688.                                 const _pt = r2 ? item.getPointAt(vertNum - 1 - i).val : item.getPointAt(i).val;
  689.                                 const _width = r2 ? item.getWidthsAt(vertNum - 1 - i) : item.getWidthsAt(i);
  690.                                 if (pt.distanceTo(_pt) < this.dTolPt && width.val1 === _width.val1 && width.val2 === _width.val2) {
  691.                                     _num += 1
  692.                                 } else {
  693.                                     // 两个点且反向的情况
  694.                                     if (vertNum === 2 && i === 0) {
  695.                                         const _pt1 = item.getPointAt(0).val;
  696.                                         const _pt2 = item.getPointAt(1).val;
  697.                                         const _width = item.getWidthsAt(0);
  698.                                         const pt2 = _poly.getPointAt(1).val;
  699.                                         if (pt2.distanceTo(_pt2) < this.dTolPt && pt.distanceTo(_pt1) < this.dTolPt && width.val1 === _width.val2 && width.val2 === _width.val1) {
  700.                                            _num += 2;
  701.                                         }
  702.                                     }
  703.                                 }
  704.                             };
  705.                             if (_num === vertNum) {
  706.                                 indexArr.push(index);
  707.                             }
  708.                             return _num === vertNum;
  709.                         }
  710.                     }
  711.                 });
  712.                 if (mPlArr.length > 0) {
  713.                     num += 1;
  714.                     ents.splice(indexArr[0], 1);
  715.                     ents = [...ents];
  716.                 } else {
  717.                     break;
  718.                 }
  719.             }
  720.         }
  721.         if (num === this.objectCount) {
  722.             // 匹配成功
  723.             const pt = minPt.clone().addvec(maxPt.clone().sub(minPt).normalize().mult(minPt.distanceTo(maxPt) / 2));
  724.             const res = this.graphBoxsPos.filter(point => pt.distanceTo(point) < this.dTolPt);
  725.             if (!res.length) {
  726.                 this.graphBoxsPos.push(pt)
  727.             }
  728.         };
  729.         this.patternList.graphBoxsPos = [...this.graphBoxsPos];
  730.     }
  731.     // 识别包围盒是否符合要求
  732.     private identificationBBox = (minPt: McGePoint3d, maxPt: McGePoint3d, angle: number): any => {
  733.         const _ss = new MxCADSelectionSet()
  734.         _ss.crossingSelect(minPt.x, minPt.y, maxPt.x, maxPt.y);
  735.         const boxEntity = {};
  736.         _ss.forEach(id => {
  737.             const ent = id.getMcDbEntity();
  738.             if (!boxEntity[ent.objectName]) boxEntity[ent.objectName] = [];
  739.             boxEntity[ent.objectName].push(ent);
  740.         });
  741.         let r = this.classNames.filter(name => boxEntity[name] && this.selectObjects[name].length <= boxEntity[name].length);
  742.         if (r.length === this.classNames.length) {
  743.             this.comparisonPhysical(boxEntity, maxPt, minPt, angle);
  744.         }
  745.     }
  746. };
复制代码
      

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.
  • 97.
  • 98.
  • 99.
  • 100.
  • 101.
  • 102.
  • 103.
  • 104.
  • 105.
  • 106.
  • 107.
  • 108.
  • 109.
  • 110.
  • 111.
  • 112.
  • 113.
  • 114.
  • 115.
  • 116.
  • 117.
  • 118.
  • 119.
  • 120.
  • 121.
  • 122.
  • 123.
  • 124.
  • 125.
  • 126.
  • 127.
  • 128.
  • 129.
  • 130.
  • 131.
  • 132.
  • 133.
  • 134.
  • 135.
  • 136.
  • 137.
  • 138.
  • 139.
  • 140.
  • 141.
  • 142.
  • 143.
  • 144.
  • 145.
  • 146.
  • 147.
  • 148.
  • 149.
  • 150.
  • 151.
  • 152.
  • 153.
  • 154.
  • 155.
  • 156.
  • 157.
  • 158.
  • 159.
  • 160.
  • 161.
  • 162.
  • 163.
  • 164.
  • 165.
  • 166.
  • 167.
  • 168.
  • 169.
  • 170.
  • 171.
  • 172.
  • 173.
  • 174.
  • 175.
  • 176.
  • 177.
  • 178.
  • 179.
  • 180.
  • 181.
  • 182.
  • 183.
  • 184.
  • 185.
  • 186.
  • 187.
  • 188.
  • 189.
  • 190.
  • 191.
  • 192.
  • 193.
  • 194.
  • 195.
  • 196.
  • 197.
  • 198.
  • 199.
  • 200.
  • 201.
  • 202.
  • 203.
  • 204.
  • 205.
  • 206.
  • 207.
  • 208.
  • 209.
  • 210.
  • 211.
  • 212.
  • 213.
  • 214.
  • 215.
  • 216.
  • 217.
  • 218.
  • 219.
  • 220.
  • 221.
  • 222.
  • 223.
  • 224.
  • 225.
  • 226.
  • 227.
  • 228.
  • 229.
  • 230.
  • 231.
  • 232.
  • 233.
  • 234.
  • 235.
  • 236.
  • 237.
  • 238.
  • 239.
  • 240.
  • 241.
  • 242.
  • 243.
  • 244.
  • 245.
  • 246.
  • 247.
  • 248.
  • 249.
  • 250.
  • 251.
  • 252.
  • 253.
  • 254.
  • 255.
  • 256.
  • 257.
  • 258.
  • 259.
  • 260.
  • 261.
  • 262.
  • 263.
  • 264.
  • 265.
  • 266.
  • 267.
  • 268.
  • 269.
  • 270.
  • 271.
  • 272.
  • 273.
  • 274.
  • 275.
  • 276.
  • 277.
  • 278.
  • 279.
  • 280.
  • 281.
  • 282.
  • 283.
  • 284.
  • 285.
  • 286.
  • 287.
  • 288.
  • 289.
  • 290.
  • 291.
  • 292.
  • 293.
  • 294.
  • 295.
  • 296.
  • 297.
  • 298.
  • 299.
  • 300.
  • 301.
  • 302.
  • 303.
  • 304.
  • 305.
  • 306.
  • 307.
  • 308.
  • 309.
  • 310.
  • 311.
  • 312.
  • 313.
  • 314.
  • 315.
  • 316.
  • 317.
  • 318.
  • 319.
  • 320.
  • 321.
  • 322.
  • 323.
  • 324.
  • 325.
  • 326.
  • 327.
  • 328.
  • 329.
  • 330.
  • 331.
  • 332.
  • 333.
  • 334.
  • 335.
  • 336.
  • 337.
  • 338.
  • 339.
  • 340.
  • 341.
  • 342.
  • 343.
  • 344.
  • 345.
  • 346.
  • 347.
  • 348.
  • 349.
  • 350.
  • 351.
  • 352.
  • 353.
  • 354.
  • 355.
  • 356.
  • 357.
  • 358.
  • 359.
  • 360.
  • 361.
  • 362.
  • 363.
  • 364.
  • 365.
  • 366.
  • 367.
  • 368.
  • 369.
  • 370.
  • 371.
  • 372.
  • 373.
  • 374.
  • 375.
  • 376.
  • 377.
  • 378.
  • 379.
  • 380.
  • 381.
  • 382.
  • 383.
  • 384.
  • 385.
  • 386.
  • 387.
  • 388.
  • 389.
  • 390.
  • 391.
  • 392.
  • 393.
  • 394.
  • 395.
  • 396.
  • 397.
  • 398.
  • 399.
  • 400.
  • 401.
  • 402.
  • 403.
  • 404.
  • 405.
  • 406.
  • 407.
  • 408.
  • 409.
  • 410.
  • 411.
  • 412.
  • 413.
  • 414.
  • 415.
  • 416.
  • 417.
  • 418.
  • 419.
  • 420.
  • 421.
  • 422.
  • 423.
  • 424.
  • 425.
  • 426.
  • 427.
  • 428.
  • 429.
  • 430.
  • 431.
  • 432.
  • 433.
  • 434.
  • 435.
  • 436.
  • 437.
  • 438.
  • 439.
  • 440.
  • 441.
  • 442.
  • 443.
  • 444.
  • 445.
  • 446.
  • 447.
  • 448.
  • 449.
  • 450.
  • 451.
  • 452.
  • 453.
  • 454.
  • 455.
  • 456.
  • 457.
  • 458.
  • 459.
  • 460.
  • 461.
  • 462.
  • 463.
  • 464.
  • 465.
  • 466.
  • 467.
  • 468.
  • 469.
  • 470.
  • 471.
  • 472.
  • 473.
  • 474.
  • 475.
  • 476.
  • 477.
  • 478.
  • 479.
  • 480.
  • 481.
  • 482.
  • 483.
  • 484.
  • 485.
  • 486.
  • 487.
  • 488.
  • 489.
  • 490.
  • 491.
  • 492.
  • 493.
  • 494.
  • 495.
  • 496.
  • 497.
  • 498.
  • 499.
  • 500.
  • 501.
  • 502.
  • 503.
  • 504.
  • 505.
  • 506.
  • 507.
  • 508.
  • 509.
  • 510.
  • 511.
  • 512.
  • 513.
  • 514.
  • 515.
  • 516.
  • 517.
  • 518.
  • 519.
  • 520.
  • 521.
  • 522.
  • 523.
  • 524.
  • 525.
  • 526.
  • 527.
  • 528.
  • 529.
  • 530.
  • 531.
  • 532.
  • 533.
  • 534.
  • 535.
  • 536.
  • 537.
  • 538.
  • 539.
  • 540.
  • 541.
  • 542.
  • 543.
  • 544.
  • 545.
  • 546.
  • 547.
  • 548.
  • 549.
  • 550.
  • 551.
  • 552.
  • 553.
  • 554.
  • 555.
  • 556.
  • 557.
  • 558.
  • 559.
  • 560.
  • 561.
  • 562.
  • 563.
  • 564.
  • 565.
  • 566.
  • 567.
  • 568.
  • 569.
  • 570.
  • 571.
  • 572.
  • 573.
  • 574.
  • 575.
  • 576.
  • 577.
  • 578.
  • 579.
  • 580.
  • 581.
  • 582.
  • 583.
  • 584.
  • 585.
  • 586.
  • 587.
  • 588.
  • 589.
  • 590.
  • 591.
  • 592.
  • 593.
  • 594.
  • 595.
  • 596.
  • 597.
  • 598.
  • 599.
  • 600.
  • 601.
  • 602.
  • 603.
  • 604.
  • 605.
  • 606.
  • 607.
  • 608.
  • 609.
  • 610.
  • 611.
  • 612.
  • 613.
  • 614.
  • 615.
  • 616.
  • 617.
  • 618.
  • 619.
  • 620.
  • 621.
  • 622.
  • 623.
  • 624.
  • 625.
  • 626.
  • 627.
  • 628.
  • 629.
  • 630.
  • 631.
  • 632.
  • 633.
  • 634.
  • 635.
  • 636.
  • 637.
  • 638.
  • 639.
  • 640.
  • 641.
  • 642.
  • 643.
  • 644.
  • 645.
  • 646.
  • 647.
  • 648.
  • 649.
  • 650.
  • 651.
  • 652.
  • 653.
  • 654.
  • 655.
  • 656.
  • 657.
  • 658.
  • 659.
  • 660.
  • 661.
  • 662.
  • 663.
  • 664.
  • 665.
  • 666.
  • 667.
  • 668.
  • 669.
  • 670.
  • 671.
  • 672.
  • 673.
  • 674.
  • 675.
  • 676.
  • 677.
  • 678.
  • 679.
  • 680.
  • 681.
  • 682.
  • 683.
  • 684.
  • 685.
  • 686.
  • 687.
  • 688.
  • 689.
  • 690.
  • 691.
  • 692.
  • 693.
  • 694.
  • 695.
  • 696.
  • 697.
  • 698.
  • 699.
  • 700.
  • 701.
  • 702.
  • 703.
  • 704.
  • 705.
  • 706.
  • 707.
  • 708.
  • 709.
  • 710.
  • 711.
  • 712.
  • 713.
  • 714.
  • 715.
  • 716.
  • 717.
  • 718.
  • 719.
  • 720.
  • 721.
  • 722.
  • 723.
  • 724.
  • 725.
  • 726.
  • 727.
  • 728.
  • 729.
  • 730.
  • 731.
  • 732.
  • 733.
  • 734.
  • 735.
  • 736.
  • 737.
  • 738.
  • 739.
  • 740.
  • 741.
  • 742.
  • 743.
  • 744.
  • 745.
  • 746.
  • 747.
  • 748.
                       调用 SearchSamePattern 类,实现图形识别功能,代码如下:
                                   登录后复制                        
  1. /** 获取需要识别的图形 */
  2. const getIdentificationPattern = async () => {
  3.     // 获取需要识别的图形
  4.     const ss = new MxCADSelectionSet();// 选择集
  5.     const filter = new MxCADResbuf([DxfCode.kEntityType, "LINE,ARC,CIRCLE,LWPOLYLINE,INSERT"])
  6.     if (!await ss.userSelect("请点击左键或拉框选择需要识别的图形:", filter)) return;
  7.     if (ss.count() == 0) return;
  8.     // 搜索图形
  9.     const searchPattern = new SearchSamePattern();
  10.     // 搜索图形简图地址
  11.     const patternImgUrl = await searchPattern.setSelectset(ss);
  12.     if (!patternImgUrl.value) return;
  13.     // 获取识别结果
  14.     const searchList = searchPattern.identifyGraphics();
  15.     console.log(searchList);
  16. }
复制代码
      

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

宝塔山

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表