(h5网页打开dwg)云端cad二开实现多重引线的方法 | vue.js 技术论坛-大发黄金版app下载

箭头引注

本章介绍如何利用 mxcad 插件实现在cad图纸中箭头引注的功能,该功能中用户点击画布确定箭头起点,再次连续点击画布确定箭头引线顶点及终点位置。

用户可自定义选择箭头形状,上标文字和下标文字内容,还可以根据绘制需求修改文字位置等,帮助用户快速标注图纸内容,增加图纸内容的完整性和可读性。

功能实现

1.实现自定义箭头引注类

为了方便后期管理与修改标注,我们可以通过继承自定义实体类来扩展实现自定义箭头引注类。然后我们可以利用或构造测量信息多文本对象,将标注信息绘制在页面中。

下面示例的箭头引注类中我们提供了箭头、点、十字、半箭头等箭头样式,以及上下标文字在线端、齐线中、齐线端等对齐方式,用户可参考下面的示例代码根据自身项目需求进行二次开发,为方便管理我们将箭头样式和文字对齐方式设置为枚举对象,代码如下:

   // 箭头样式
   enum arrowtype {
     // 箭头
     arrow,
     // 半箭头
     halfarrow,
     // 点
     point,
     // 十字
     cross,
     // 无
     none
   }
   // 文字对齐方式
   export enum algintype {
     // 始端
     start,
     // 中间
     middle,
     // 末端
     end
   }

箭头引注自定义实体代码如下,下面示例只作参考,用户可根据自身需求修改, 代码如下:

 class mcdbtestarrowcitation extends mcdbcustomentity {
       // 定义mcdbtestconmeasurement内部的点对象 
       // 箭头线点数组
       private points: mcgepoint3d[] = [];
       // 文字点位置集合
       private positionarr: mcgepoint3d[] = [];
       // 文字高度
       private height: number = 0;
       // 上标文字内容
       private _textup: string = "";
       // 下标文字内容
       private _textdown: string = "";
       // 箭头样式
       private _arrowtype: number = arrowtype.arrow;
       // 对齐方式
       private _algintype: number = algintype.start;
       // 记录初始长度
       private arrowlength: number = mxfun.viewcoordlong2cad(20);;
       // 文字旋转角度
       private angle: number = 0;
       // 构造函数
       constructor(imp?: any) {
           super(imp);
       }
       // 创建函数
       public create(imp: any) {
           return new mcdbtestarrowcitation(imp)
       }
       // 获取类名
       public gettypename(): string {
           return "mcdbtestarrowcitation";
       }
       //设置或获取文本字高
       public set textheight(val: number) {
           this.height = val;
       }
       public get textheight(): number {
           return this.height;
       }
       //设置或获取上标文本
       public set textup(val: string) {
           this._textup = val;
       }
       public get textup(): string {
           return this._textup;
       }
       //设置或获取下标文本
       public set textdown(val: string) {
           this._textdown = val;
       }
       public get textdown(): string {
           return this._textdown;
       }
       //设置或获取箭头样式
       public set arrowtype(val: number) {
           this._arrowtype = val;
       }
       public get arrowtype(): number {
           return this._arrowtype;
       }
       //设置或获取对齐样式
       public set algintype(val: number) {
           this._algintype = val;
       }
       public get algintype(): number {
           return this._algintype;
       }
       // 读取自定义实体数据
       public dwginfields(filter: imcdbdwgfiler): boolean {
           this.points = filter.readpoints("points").val;
           this.positionarr = filter.readpoints("positionarr").val;
           this._textdown = filter.readstring("textdown").val;
           this._textup = filter.readstring("textup").val;
           this._arrowtype = filter.readlong("arrowtype").val;
           this._algintype = filter.readlong("algintype").val;
           this.arrowlength = filter.readlong("arrowlength").val;
           this.angle = filter.readdouble("angle").val;
           this.height = filter.readdouble("height").val;
           return true;
       }
       // 写入自定义实体数据
       public dwgoutfields(filter: imcdbdwgfiler): boolean {
           filter.writepoints("points", this.points);
           filter.writepoints("positionarr", this.positionarr);
           filter.writestring("textdown", this._textdown);
           filter.writestring("textup", this._textup);
           filter.writelong("arrowtype", this._arrowtype);
           filter.writelong("algintype", this._algintype);
           filter.writelong("arrowlength", this.arrowlength);
           filter.writedouble("angle", this.angle);
           filter.writedouble("height", this.height);
           return true;
       }
       // 移动自定义对象的夹点
       public movegrippointsat(iindex: number, dxoffset: number, dyoffset: number, dzoffset: number) {
           this.assertwrite();
           const length = this.points.length
           if (iindex <= length - 1) {
               this.points[iindex].x  = dxoffset;
               this.points[iindex].y  = dyoffset;
               this.points[iindex].z  = dzoffset;
           }
           if (iindex === length - 1) {
               this.positionarr.foreach(position => {
                   position.x  = dxoffset;
                   position.y  = dyoffset;
                   position.z  = dzoffset;
               });
               this.recountdata();
           };
           if (iindex > length - 1) {
               this.positionarr.foreach((position, index) => {
                   if (iindex - length === index) {
                       position.x  = dxoffset;
                       position.y  = dyoffset;
                       position.z  = dzoffset;
                   }
               });
           }
       };
       // 获取自定义对象的夹点
       public getgrippoints(): mcgepoint3darray {
           let ret = new mcgepoint3darray()
           this.points.foreach(pt => {
               ret.append(pt)
           });
           this.positionarr.foreach(pt => {
               ret.append(pt);
           })
           return ret;
       };
       // 画箭头
       private drawarrow(): mcdbentity[] {
           const pt1 = this.points[0];
           const pt2 = this.points[1];
           if (this._arrowtype === arrowtype.arrow || this._arrowtype === arrowtype.halfarrow) {
               const vec = pt2.sub(pt1).normalize().mult(this.arrowlength);
               const pt = pt1.clone().addvec(vec);
               const _vec = vec.clone().rotateby(math.pi / 2).normalize().mult(this.arrowlength / 8);
               const pt3 = pt.clone().addvec(_vec);
               const pt4 = pt.clone().subvec(_vec);
               const solid = new mcdbhatch();
               this._arrowtype === arrowtype.arrow ? solid.appendloop(new mcgepoint3darray([pt1, pt3, pt4])) : solid.appendloop(new mcgepoint3darray([pt1, pt3, pt]));
               return [solid]
           }else if(this._arrowtype === arrowtype.point){
               const solid = new mcdbhatch();
               solid.appendcircleloop(pt1.x,pt1.y,this.arrowlength/3);
               return [solid]
           }else if(this._arrowtype === arrowtype.cross){
               const point1 = pt1.clone().addvec(mcgevector3d.kxaxis.normalize().mult(this.arrowlength/2));
               const point2 = pt1.clone().subvec(mcgevector3d.kxaxis.normalize().mult(this.arrowlength/2));
               const point3 = pt1.clone().addvec(mcgevector3d.kyaxis.normalize().mult(this.arrowlength/2));
               const point4 = pt1.clone().subvec(mcgevector3d.kyaxis.normalize().mult(this.arrowlength/2));
               const line1 = new mcdbline(point1,point2);
               const line2 = new mcdbline(point3, point4);
               return [line1,line2]
           }
       }
       // 画文字
       private drawtext(): mcdbentity[] {
           const textarr = [];
           const textup = new mcdbtext();
           textup.height = this.height;
           textup.textstring = this._textup;
           textup.position = textup.alignmentpoint = this.positionarr[0];
           textup.horizontalmode = mcdb.texthorzmode.ktextleft;
           textup.rotate(this.positionarr[0], this.angle);
           if (this._algintype === algintype.middle || this._algintype === algintype.end) {
               const textdown = new mcdbmtext()
               textdown.contents = this._textdown;
               textdown.location = this.positionarr[1];
               textdown.textheight = this.height;
               textdown.attachment = mcdb.attachmentpoint.ktopcenter;
               textdown.rotate(this.positionarr[1], this.angle);
               if (this._algintype === algintype.middle) {
                   textup.horizontalmode = mcdb.texthorzmode.ktextmid;
               }
               if (this._algintype === algintype.end) {
                   textdown.attachment = mcdb.attachmentpoint.ktopleft;
               }
               textarr.push(textdown);
           }
           textarr.push(textup);
           return textarr
       }
       // 绘制实体 
       public worlddraw(draw: mxcadworlddraw): void {
           // 画多段线
           const pl = new mcdbpolyline();
           this.points.foreach((pt) => {
               pl.addvertexat(pt);
           });
           draw.drawentity(pl);
           // 画箭头
           if(this._arrowtype !== arrowtype.none && this.points.length > 1){
               const arrowarr = this.drawarrow();
               arrowarr.foreach( arrow =>{
                   draw.drawentity(arrow)
               })
           }
           if (this.points.length > 1) {
               // 画标注
               const textarr = this.drawtext();
               textarr.foreach(text => {
                   draw.drawentity(text)
               })
           }
       }
       private recountdata() {
           const length = this.points.length;
           // 获取最后一段直线的方向与旋转角度
           if (length > 1) {
               const pt1 = this.points[length - 2];
               const pt2 = this.points[length - 1];
               if (!this.height) {
                   this.height = this.arrowlength*(2/3);
               };
               const vec = pt2.sub(pt1).normalize().mult(this.height / 2);
               const _vec = vec.clone().rotateby(math.pi / 2).normalize().mult(this.height / 2);
               this.angle = vec.angleto2(mcgevector3d.kxaxis, mcgevector3d.knegatezaxis);
               if (math.pi * (3 / 2) > this.angle && this.angle > math.pi / 2) {
                   this.angle  = math.pi;
                   _vec.negate();
               }
               if (this._algintype === algintype.start) {
                   // 在线端,只有上标文字
                   const position = pt2.clone().addvec(vec).subvec(_vec);
                   this.positionarr[0] = position;
               } else if (this._algintype === algintype.middle) {
                   // 齐线中,上下标文字居中
                   const distance = pt1.distanceto(pt2);
                   const midpt = pt1.clone().addvec(vec.normalize().mult(distance / 2))
                   this.positionarr[1] = midpt.clone().subvec(_vec);
                   this.positionarr[0] = midpt.clone().addvec(_vec);
               } else if (this._algintype === algintype.end) {
                   // 齐线端,上下标文字在末尾
                   this.positionarr[1] = pt2.clone().addvec(vec).subvec(_vec);
                   this.positionarr[0] = pt2.clone().addvec(vec).addvec(_vec);
               }
           }
       }
       // 添加顶点
       public addvertex(pt: mcgepoint3d) {
           this.assertwrite();
           this.points.push(pt);
           this.recountdata();
       }
       // 获取顶点数组
       public getpoints() {
           return this.points;
       }
   };

2.注册自定义类信息

运行代码:

  new mcdbtestarrowcitation().rxinit();

3.调用mcdbtestarrowcitation自定义箭头引注类

3.1设置箭头样式,上下标文字内容及对齐方式
我们可以利用根据根据用户输入得到上下标文字内容,或者通过其他方式直接赋值。选择箭头样式或对齐方式时,我们可以通过根据用户选择的关键词来设置相应操作,代码如下:

   // 设置箭头样式
   const getarrowstyle = new mxcaduiprkeyword()
   getarrowstyle.setmessage("请选着箭头样式:")
   getarrowstyle.setkeywords("[箭头(a)/半箭头(ha)/点(p)/十字(c)/无(n)]")
   let arrowstyle = await getarrowstyle.go();
   // 转换arrowstyle的值
   switch (arrowstyle) {
       case 'a':
           arrowstyle = arrowtype.arrow;
       case 'ha':
           arrowstyle = arrowtype.halfarrow;
       case 'p':
           arrowstyle = arrowtype.point;
       case 'c':
           arrowstyle = arrowtype.cross;
       case 'n':
           arrowstyle = arrowtype.none;
       default:
           arrowstyle = arrowtype.arrow;
   }
   // 设置对齐方式
   const getaligntype = new mxcaduiprkeyword()
   getaligntype.setmessage("请选择上下标文字对齐方式:")
   getaligntype.setkeywords("[在线端(s)/齐线中(m)/齐线端(e)]")
   let aligntype = await getaligntype.go();
   // 转换aligntype的值
   switch (aligntype) {
       case 's':
           algintype = algintype.start;
       case 'm':
           algintype = algintype.middle;
       case 'e':
           algintype = algintype.end;
       default:
           algintype = algintype.start;
   }
   /**
    设置上下标文字
    在线端只能设置上标文字
    */
   const getstrup = new mxcaduiprstring();
   getstrup.setmessage('请设置上标文字内容:');
   let strup = await getstrup.go();
   if (!strup) strup = "上";
   let strdown = "";
   if(aligntype === "m" || aligntype === "r"){
     const getstrdown = new mxcaduiprstring();
     getstrdown.setmessage('请设置下标文字内容:');
     strdown = await getstrdown.go();
     if (!strdown) strdown = "下";
   }

3.2. 获取箭头起点,及引线顶点
我们可以利用取点对象连续取点来获取箭头起点和引线的各个顶点。结合上述步骤中获取的箭头引注的信息,构造新的箭头引注对象,并动态绘制方便用户观察,代码如下:

   const arrowciatat = new mcdbtestarrowcitation();
   arrowciatat.textup = strup;
   arrowciatat.textdown = strdown;
   arrowciatat.arrowtype = arrowstyle;
   arrowciatat.algintype = algintype;
   const getpoint = new mxcaduiprpoint();
   getpoint.setmessage('指定箭头起点:');
   const point = await getpoint.go();
   if (!point) return;
   arrowciatat.addvertex(point);
   while (true) {
     const getpt = new mxcaduiprpoint();
     getpt.setmessage('指定下一点或终点,右键完成');
     getpt.setuserdraw((pt, pw) => {
      const _clone = arrowciatat.clone() as mcdbtestarrowcitation;
      _clone.addvertex(pt);
      pw.drawmcdbentity(_clone)
     })
     const pt = await getpt.go();
     if (!pt) break;
     arrowciatat.addvertex(pt);
   }
   const mxcad = mxcpp.getcurrentmxcad();
   mxcad.drawentity(arrowciatat);

功能实践

在线示例demo: 操作流程如下图:



本作品采用《cc 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
网站地图