
<p id="343D5BID"><strong>前言</strong></p><p id="343D5BIE">本章介绍如何利用mxcad插件实现在CAD图纸中箭头引注的功能,该功能中用户点击画布确定箭头起点,再次连续点击画布确定箭头引线顶点及终点位置。</p><p id="343D5BIF">用户可自定义选择箭头形状,上标文字和下标文字内容,还可以根据绘制需求修改文字位置等,帮助用户快速标注图纸内容,增加图纸内容的完整性和可读性。</p><p id="343D5BIG"><strong>功能实现</strong></p><p id="343D5BIH">1.实现自定义箭头引注类</p><p id="343D5BII">为了方便后期管理与修改标注,我们可以通过继承[McDbCustomEntity]自定义实体类来扩展实现自定义箭头引注类。然后我们可以利用[McDbMText]或[McDbText]构造测量信息多文本对象,将标注信息绘制在页面中。</p><p id="343D5BIJ">下面示例的箭头引注类中我们提供了箭头、点、十字、半箭头等箭头样式,以及上下标文字在线端、齐线中、齐线端等对齐方式,用户可参考下面的示例代码根据自身项目需求进行二次开发,为方便管理我们将箭头样式和文字对齐方式设置为枚举对象,代码如下:</p><p><blockquote id="343D5BJB"> // 箭头样式<br/>enum arrowType {<br/>// 箭头<br/>arrow,<br/>// 半箭头<br/>halfArrow,<br/>// 点<br/>point,<br/>// 十字<br/>cross,<br/>// 无<br/>none<br/>}<br/>// 文字对齐方式<br/>export enum alginType {<br/>// 始端<br/>start,<br/>// 中间<br/>middle,<br/>// 末端<br/>end<br/>}<br/></blockquote></p><p id="343D5BIL">箭头引注自定义实体代码如下,下面示例只作参考,用户可根据自身需求修改, 代码如下:</p><p><blockquote id="343D5BJC">class McDbTestArrowCitation extends McDbCustomEntity {<br/>// 定义McDbTestConMeasurement内部的点对象<br/>// 箭头线点数组<br/>private points: McGePoint3d[] = [];<br/>// 文字点位置集合<br/>private positionArr: McGePoint3d[] = [];<br/>// 文字高度<br/>private height: number = 0;<br/>// 上标文字内容<br/>private _textUp: string = "";<br/>// 下标文字内容<br/>private _textDown: string = "";<br/>// 箭头样式<br/>private _arrowType: number = arrowType.arrow;<br/>// 对齐方式<br/>private _alginType: number = alginType.start;<br/>// 记录初始长度<br/>private arrowLength: number = MxFun.viewCoordLong2Cad(20);;<br/>// 文字旋转角度<br/>private angle: number = 0;<br/>// 构造函数<br/>constructor(imp?: any) {<br/>super(imp);<br/>}<br/>// 创建函数<br/>public create(imp: any) {<br/>return new McDbTestArrowCitation(imp)<br/>}<br/>// 获取类名<br/>public getTypeName(): string {<br/>return "McDbTestArrowCitation";<br/>}<br/>//设置或获取文本字高<br/>public set textHeight(val: number) {<br/>this.height = val;<br/>}<br/>public get textHeight(): number {<br/>return this.height;<br/>}<br/>//设置或获取上标文本<br/>public set textUp(val: string) {<br/>this._textUp = val;<br/>}<br/>public get textUp(): string {<br/>return this._textUp;<br/>}<br/>//设置或获取下标文本<br/>public set textDown(val: string) {<br/>this._textDown = val;<br/>}<br/>public get textDown(): string {<br/>return this._textDown;<br/>}<br/>//设置或获取箭头样式<br/>public set arrowType(val: number) {<br/>this._arrowType = val;<br/>}<br/>public get arrowType(): number {<br/>return this._arrowType;<br/>}<br/>//设置或获取对齐样式<br/>public set alginType(val: number) {<br/>this._alginType = val;<br/>}<br/>public get alginType(): number {<br/>return this._alginType;<br/>}<br/>// 读取自定义实体数据<br/>public dwgInFields(filter: IMcDbDwgFiler): boolean {<br/>this.points = filter.readPoints("points").val;<br/>this.positionArr = filter.readPoints("positionArr").val;<br/>this._textDown = filter.readString("textDown").val;<br/>this._textUp = filter.readString("textUp").val;<br/>this._arrowType = filter.readLong("arrowType").val;<br/>this._alginType = filter.readLong("alginType").val;<br/>this.arrowLength = filter.readLong("arrowLength").val;<br/>this.angle = filter.readDouble("angle").val;<br/>this.height = filter.readDouble("height").val;<br/>return true;<br/>}<br/>// 写入自定义实体数据<br/>public dwgOutFields(filter: IMcDbDwgFiler): boolean {<br/>filter.writePoints("points", this.points);<br/>filter.writePoints("positionArr", this.positionArr);<br/>filter.writeString("textDown", this._textDown);<br/>filter.writeString("textUp", this._textUp);<br/>filter.writeLong("arrowType", this._arrowType);<br/>filter.writeLong("alginType", this._alginType);<br/>filter.writeLong("arrowLength", this.arrowLength);<br/>filter.writeDouble("angle", this.angle);<br/>filter.writeDouble("height", this.height);<br/>return true;<br/>}<br/>// 移动自定义对象的夹点<br/>public moveGripPointsAt(iIndex: number, dXOffset: number, dYOffset: number, dZOffset: number) {<br/>this.assertWrite();<br/>const length = this.points.length<br/>if (iIndex <= length - 1) {<br/>this.points[iIndex].x += dXOffset;<br/>this.points[iIndex].y += dYOffset;<br/>this.points[iIndex].z += dZOffset;<br/>}<br/>if (iIndex === length - 1) {<br/>this.positionArr.forEach(position => {<br/>position.x += dXOffset;<br/>position.y += dYOffset;<br/>position.z += dZOffset;<br/>});<br/>this.reCountData();<br/>};<br/>if (iIndex > length - 1) {<br/>this.positionArr.forEach((position, index) => {<br/>if (iIndex - length === index) {<br/>position.x += dXOffset;<br/>position.y += dYOffset;<br/>position.z += dZOffset;<br/>}<br/>});<br/>}<br/>};<br/>// 获取自定义对象的夹点<br/>public getGripPoints(): McGePoint3dArray {<br/>let ret = new McGePoint3dArray()<br/>this.points.forEach(pt => {<br/>ret.append(pt)<br/>});<br/>this.positionArr.forEach(pt => {<br/>ret.append(pt);<br/>})<br/>return ret;<br/>};<br/>// 画箭头<br/>private drawArrow(): McDbEntity[] {<br/>const pt1 = this.points[0];<br/>const pt2 = this.points[1];<br/>if (this._arrowType === arrowType.arrow || this._arrowType === arrowType.halfArrow) {<br/>const vec = pt2.sub(pt1).normalize().mult(this.arrowLength);<br/>const pt = pt1.clone().addvec(vec);<br/>const _vec = vec.clone().rotateBy(Math.PI / 2).normalize().mult(this.arrowLength / 8);<br/>const pt3 = pt.clone().addvec(_vec);<br/>const pt4 = pt.clone().subvec(_vec);<br/>const solid = new McDbHatch();<br/>this._arrowType === arrowType.arrow ? solid.appendLoop(new McGePoint3dArray([pt1, pt3, pt4])) : solid.appendLoop(new McGePoint3dArray([pt1, pt3, pt]));<br/>return [solid]<br/>}else if(this._arrowType === arrowType.point){<br/>const solid = new McDbHatch();<br/>solid.appendCircleLoop(pt1.x,pt1.y,this.arrowLength/3);<br/>return [solid]<br/>}else if(this._arrowType === arrowType.cross){<br/>const point1 = pt1.clone().addvec(McGeVector3d.kXAxis.normalize().mult(this.arrowLength/2));<br/>const point2 = pt1.clone().subvec(McGeVector3d.kXAxis.normalize().mult(this.arrowLength/2));<br/>const point3 = pt1.clone().addvec(McGeVector3d.kYAxis.normalize().mult(this.arrowLength/2));<br/>const point4 = pt1.clone().subvec(McGeVector3d.kYAxis.normalize().mult(this.arrowLength/2));<br/>const line1 = new McDbLine(point1,point2);<br/>const line2 = new McDbLine(point3, point4);<br/>return [line1,line2]<br/>}<br/>}<br/>// 画文字<br/>private drawText(): McDbEntity[] {<br/>const textArr = [];<br/>const textUp = new McDbText();<br/>textUp.height = this.height;<br/>textUp.textString = this._textUp;<br/>textUp.position = textUp.alignmentPoint = this.positionArr[0];<br/>textUp.horizontalMode = McDb.TextHorzMode.kTextLeft;<br/>textUp.rotate(this.positionArr[0], this.angle);<br/>if (this._alginType === alginType.middle || this._alginType === alginType.end) {<br/>const textDown = new McDbMText()<br/>textDown.contents = this._textDown;<br/>textDown.location = this.positionArr[1];<br/>textDown.textHeight = this.height;<br/>textDown.attachment = McDb.AttachmentPoint.kTopCenter;<br/>textDown.rotate(this.positionArr[1], this.angle);<br/>if (this._alginType === alginType.middle) {<br/>textUp.horizontalMode = McDb.TextHorzMode.kTextMid;<br/>}<br/>if (this._alginType === alginType.end) {<br/>textDown.attachment = McDb.AttachmentPoint.kTopLeft;<br/>}<br/>textArr.push(textDown);<br/>}<br/>textArr.push(textUp);<br/>return textArr<br/>}<br/>// 绘制实体<br/>public worldDraw(draw: MxCADWorldDraw): void {<br/>// 画多段线<br/>const pl = new McDbPolyline();<br/>this.points.forEach((pt) => {<br/>pl.addVertexAt(pt);<br/>});<br/>draw.drawEntity(pl);<br/>// 画箭头<br/>if(this._arrowType !== arrowType.none && this.points.length > 1){<br/>const arrowArr = this.drawArrow();<br/>arrowArr.forEach( arrow =>{<br/>draw.drawEntity(arrow)<br/>})<br/>}<br/>if (this.points.length > 1) {<br/>// 画标注<br/>const textArr = this.drawText();<br/>textArr.forEach(text => {<br/>draw.drawEntity(text)<br/>})<br/>}<br/>}<br/>private reCountData() {<br/>const length = this.points.length;<br/>// 获取最后一段直线的方向与旋转角度<br/>if (length > 1) {<br/>const pt1 = this.points[length - 2];<br/>const pt2 = this.points[length - 1];<br/>if (!this.height) {<br/>this.height = this.arrowLength*(2/3);<br/>};<br/>const vec = pt2.sub(pt1).normalize().mult(this.height / 2);<br/>const _vec = vec.clone().rotateBy(Math.PI / 2).normalize().mult(this.height / 2);<br/>this.angle = vec.angleTo2(McGeVector3d.kXAxis, McGeVector3d.kNegateZAxis);<br/>if (Math.PI * (3 / 2) > this.angle && this.angle > Math.PI / 2) {<br/>this.angle += Math.PI;<br/>_vec.negate();<br/>}<br/>if (this._alginType === alginType.start) {<br/>// 在线端,只有上标文字<br/>const position = pt2.clone().addvec(vec).subvec(_vec);<br/>this.positionArr[0] = position;<br/>} else if (this._alginType === alginType.middle) {<br/>// 齐线中,上下标文字居中<br/>const distance = pt1.distanceTo(pt2);<br/>const midPt = pt1.clone().addvec(vec.normalize().mult(distance / 2))<br/>this.positionArr[1] = midPt.clone().subvec(_vec);<br/>this.positionArr[0] = midPt.clone().addvec(_vec);<br/>} else if (this._alginType === alginType.end) {<br/>// 齐线端,上下标文字在末尾<br/>this.positionArr[1] = pt2.clone().addvec(vec).subvec(_vec);<br/>this.positionArr[0] = pt2.clone().addvec(vec).addvec(_vec);<br/>}<br/>}<br/>}<br/>// 添加顶点<br/>public addVertex(pt: McGePoint3d) {<br/>this.assertWrite();<br/>this.points.push(pt);<br/>this.reCountData();<br/>}<br/>// 获取顶点数组<br/>public getPoints() {<br/>return this.points;<br/>}<br/>};<br/></blockquote></p><p id="343D5BIN">2.注册自定义类信息</p><p id="343D5BIO">运行代码:</p><p><blockquote id="343D5BJD">new McDbTestArrowCitation().rxInit();<br/></blockquote></p><p id="343D5BIQ">3.调用McDbTestArrowCitation自定义箭头引注类</p><p id="343D5BIR">3.1设置箭头样式,上下标文字内容及对齐方式</p><p id="343D5BIS">我们可以利用[MxCADUiPrString()]根据根据用户输入得到上下标文字内容,或者通过其他方式直接赋值。选择箭头样式或对齐方式时,我们可以通过[MxCADUiPrKeyWord()]根据用户选择的关键词来设置相应操作,代码如下:</p><p><blockquote id="343D5BJE"> // 设置箭头样式<br/>const getArrowStyle = new MxCADUiPrKeyWord()<br/>getArrowStyle.setMessage("请选着箭头样式:")<br/>getArrowStyle.setKeyWords("[箭头(A)/半箭头(HA)/点(P)/十字(C)/无(N)]")<br/>let arrowStyle = await getArrowStyle.go();<br/>// 转换arrowStyle的值<br/>switch (arrowStyle) {<br/>case 'A':<br/>arrowStyle = arrowType.arrow;<br/>case 'HA':<br/>arrowStyle = arrowType.halfArrow;<br/>case 'P':<br/>arrowStyle = arrowType.point;<br/>case 'C':<br/>arrowStyle = arrowType.cross;<br/>case 'N':<br/>arrowStyle = arrowType.none;<br/>default:<br/>arrowStyle = arrowType.arrow;<br/>}<br/>// 设置对齐方式<br/>const getAlignType = new MxCADUiPrKeyWord()<br/>getAlignType.setMessage("请选择上下标文字对齐方式:")<br/>getAlignType.setKeyWords("[在线端(S)/齐线中(M)/齐线端(E)]")<br/>let alignType = await getAlignType.go();<br/>// 转换alignType的值<br/>switch (alignType) {<br/>case 'S':<br/>alginType = alginType.start;<br/>case 'M':<br/>alginType = alginType.middle;<br/>case 'E':<br/>alginType = alginType.end;<br/>default:<br/>alginType = alginType.start;<br/>}<br/>/<br/>设置上下标文字<br/>在线端只能设置上标文字<br/>*/<br/>const getStrUp = new MxCADUiPrString();<br/>getStrUp.setMessage('请设置上标文字内容:');<br/>let strUp = await getStrUp.go();<br/>if (!strUp) strUp = "上";<br/>let strDown = "";<br/>if(alignType === "M" || alignType === "R"){<br/>const getStrDown = new MxCADUiPrString();<br/>getStrDown.setMessage('请设置下标文字内容:');<br/>strDown = await getStrDown.go();<br/>if (!strDown) strDown = "下";<br/>}<br/></blockquote></p><p id="343D5BIU">3.2. 获取箭头起点,及引线顶点</p><p id="343D5BIV">我们可以利用取点对象[MxCADUiPrPoint]连续取点来获取箭头起点和引线的各个顶点。结合上述步骤中获取的箭头引注的信息,构造新的箭头引注对象,并动态绘制方便用户观察,代码如下:</p><p><blockquote id="343D5BJF"> const arrowCiatat = new McDbTestArrowCitation();<br/>arrowCiatat.textUp = strUp;<br/>arrowCiatat.textDown = strDown;<br/>arrowCiatat.arrowType = arrowStyle;<br/>arrowCiatat.alginType = alginType;<br/>const getPoint = new MxCADUiPrPoint();<br/>getPoint.setMessage('指定箭头起点:');<br/>const point = await getPoint.go();<br/>if (!point) return;<br/>arrowCiatat.addVertex(point);<br/>while (true) {<br/>const getPt = new MxCADUiPrPoint();<br/>getPt.setMessage('指定下一点或终点,右键完成');<br/>getPt.setUserDraw((pt, pw) => {<br/>const _clone = arrowCiatat.clone() as McDbTestArrowCitation;<br/>_clone.addVertex(pt);<br/>pw.drawMcDbEntity(_clone)<br/>})<br/>const pt = await getPt.go();<br/>if (!pt) break;<br/>arrowCiatat.addVertex(pt);<br/>}<br/>const mxcad = MxCpp.getCurrentMxCAD();<br/>mxcad.drawEntity(arrowCiatat);<br/></blockquote></p><p id="343D5BJ1"><strong>功能实践</strong></p><p id="343D5BJ2">操作流程如下图:</p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2024%2F1022%2Fb30dfce1j00slqvxs002nd000v400fxp.jpg&thumbnail=660x&quality=80&type=jpg"/><br/><br/></p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2024%2F1022%2F946f1a0cj00slqvxw002jd000v800fxp.jpg&thumbnail=660x&quality=80&type=jpg"/><br/><br/></p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2024%2F1022%2F2b4488afj00slqvxz0064d000v900k0p.jpg&thumbnail=660x&quality=80&type=jpg"/><br/><br/></p><p class="f_center"><img src="https://nimg.ws.126.net/?url=http%3A%2F%2Fdingyue.ws.126.net%2F2024%2F1022%2F1a8c9c29j00slqvy20029d000v100fsp.jpg&thumbnail=660x&quality=80&type=jpg"/><br/><br/></p>
讯享网

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/205497.html