明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 2614|回复: 4

关于trim功能的运用

[复制链接]
发表于 2003-12-25 20:59:00 | 显示全部楼层 |阅读模式
根据看到的帖子,我做了一个vb实现trim功能的程序.基本思路如下:
先做出一个封闭的矩形polyline,然后用sendcommand命令,边界选用此矩形,然后用"F"命令,输入比矩形polyline四个顶点稍靠内的四个点坐标,这样矩形polyline范围内所有能剪切的实体都被截断.
这样做如果是在cad命令行中操作,一切正常.但通过vb程序操作时,cad会出现一个对话框"Can't run macro,AutoCAD is busy",点击确定后对话框消失,程序结束.然后再在命令行中输入一个回车,命令行的trim命令结束.此时polyline内的实体被截断,达到预定目标.
请问这个对话框是怎么回事,怎样避免?它对我的程序无用,除去就大吉了.
 楼主| 发表于 2003-12-25 21:33:00 | 显示全部楼层
另外,刚刚调试时发现,如果一个实体,比如多义线,来回几次穿过剪切边界时,用"F"一次只能截断一次穿过剪切边界的部分,再"F"一次又截断一部分,就跟用点选取一样.由于不能事先知道有几次穿过,也就是说不能确定要"F"几次.各位有什么办法解决吗?
注:在命令行执行trim命令,情况一样.
发表于 2003-12-26 12:49:00 | 显示全部楼层
我也做了一个和你一样的程序,编程的思路也一样,不过我是用vba做的,已经调试成功,没有可以直接使用了。
你说的那个多段线多次穿过的问题我也遇到了,还没有解决,在程序里我用了2次截断,对于穿过边界的一般的多段线是够用了。
下面是我的程序代码,如果方便可以和楼主交流一下,看看怎么才能做的更好。

  1. Sub blkTrim()

  2. On Error Resume Next
  3.   Dim ent As AcadEntity
  4.   Dim sset As AcadSelectionSet
  5.   Set sset = CreateSelectionSet("sset")
  6.   Dim fType, fData As Variant
  7.   Dim lwplineobj As AcadLWPolyline
  8.   Dim pt1, pt2 As Variant
  9.   Dim points(0 To 9) As Double
  10.   Dim isblock As Boolean
  11.   BuildFilter fType, fData, 0, "INSERT"
  12.   ThisDrawing.Utility.Prompt "选择对象,会过滤其它对象,只留下块,若直接回车,则可选择多段线。"
  13.   sset.SelectOnScreen fType, fData
  14.   
  15.   If sset.Count = 0 Then
  16.     ThisDrawing.Utility.Prompt "选择对象,会过滤其它对象,只留下多段线。"
  17.     BuildFilter fType, fData, 0, "lwPolyline"
  18.     sset.SelectOnScreen fType, fData
  19.     If sset.Count = 0 Then Exit Sub
  20.    
  21.     For Each ent In sset
  22.       entTrimF ent
  23.     Next
  24.   Else
  25.     For Each ent In sset
  26.       ent.GetBoundingBox pt1, pt2
  27.       points(0) = pt1(0): points(1) = pt1(1)
  28.       points(2) = pt1(0): points(3) = pt2(1)
  29.       points(4) = pt2(0): points(5) = pt2(1)
  30.       points(6) = pt2(0): points(7) = pt1(1)
  31.       points(8) = pt1(0): points(9) = pt1(1)
  32.       Set lwplineobj = ThisDrawing.ModelSpace.AddLightWeightPolyline(points)
  33.       entTrimF lwplineobj
  34.       lwplineobj.Delete
  35.     Next
  36.   End If
  37.   sset.Delete
  38. End Sub

  39. '此过程把和多段线plineobj相交的线都剪切
  40. Sub entTrimF(plineObj As AcadEntity)
  41.     Dim offplineObj As Variant
  42.     Dim copyplineobj As AcadEntity
  43.     Dim Coors As Variant
  44.     Dim coorString, cmdString As String
  45.     Dim i As Integer
  46.     Dim offdist As Double
  47.     Set copyplineobj = plineObj.Copy
  48.    
  49.     If IsClockWise(copyplineobj) Then offdist = 0.01 Else: offdist = -0.01
  50.    
  51.     offplineObj = copyplineobj.Offset(offdist)
  52.     offplineObj(0).Update
  53.    
  54.     Coors = offplineObj(0).Coordinates
  55.     offplineObj(0).Delete
  56.     copyplineobj.Delete
  57.    
  58.     coorString = ""
  59.     For i = LBound(Coors) To UBound(Coors) Step 2
  60.       coorString = coorString & Coors(i) & "," & Coors(i + 1) & ",0" & vbCr
  61.     Next i
  62.     cmdString = "trim" & vbCr & "(handent """ & plineObj.Handle & """)" & vbCr & vbCr & _
  63.                 "f" & vbCr & coorString & vbCr & vbCr
  64.    
  65.     ThisDrawing.SendCommand cmdString
  66.     ThisDrawing.SendCommand cmdString

  67. End Sub

以下是引用的函数,基本上都是从明经下载的,根据自己的要求做了一些改动。呵呵

  1. Public Sub BuildFilter(typeArray, dataArray, ParamArray gCodes())
  2.     Dim fType() As Integer, fData()
  3.     Dim index As Long, i As Long
  4.    
  5.     index = LBound(gCodes) - 1
  6.         
  7.     For i = LBound(gCodes) To UBound(gCodes) Step 2
  8.         index = index + 1
  9.         ReDim Preserve fType(0 To index)
  10.         ReDim Preserve fData(0 To index)
  11.         fType(index) = CInt(gCodes(i))
  12.         fData(index) = gCodes(i + 1)
  13.     Next
  14.     typeArray = fType: dataArray = fData
  15. End Sub
  16. Public Sub ssDelete(ss As AcadSelectionSet, ent As AcadEntity)

  17.     Dim objArray(0 To 0) As AcadEntity
  18.    
  19.     Set objArray(0) = ent
  20.     ss.RemoveItems objArray

  21. End Sub

  22. Public Function CreateSelectionSet(Optional ssName As String = "ss") As AcadSelectionSet

  23.     Dim ss As AcadSelectionSet
  24.    
  25.     On Error Resume Next
  26.     Set ss = ThisDrawing.SelectionSets(ssName)
  27.     If Err Then Set ss = ThisDrawing.SelectionSets.Add(ssName)
  28.     ss.Clear
  29.     Set CreateSelectionSet = ss

  30. End Function

  31. Public Function IsClockWise(objEntity As AcadEntity) As Boolean
  32.     On Error Resume Next
  33.     Dim NewObj As Variant
  34.     Dim oldobj As AcadEntity
  35.     Set oldobj = objEntity.Copy
  36.     NewObj = oldobj.Offset(-0.01)
  37.     Dim Area1 As Double
  38.     Dim Area2 As Double
  39.     Area1 = objEntity.Area
  40.     Area2 = NewObj(0).Area
  41.     Dim i As Integer
  42.     For i = 0 To UBound(NewObj)
  43.         NewObj(i).Delete
  44.     Next
  45.     oldobj.Delete
  46.     If Area1 < Area2 Then IsClockWise = True
  47. End Function
 楼主| 发表于 2003-12-26 19:02:00 | 显示全部楼层
3楼,我想你可能还没有对你的程序进行多种情况下的测试.比如弧线,各种线宽的多义线(线宽小于剪切范围,线宽大于剪切范围,线宽一部分在剪切范围内等)等等.另外我发现,用"F"时偏移量的多少(0.001和0.1)剪切的结果有时候也不一样.你试试你的看.
另外给个建议,你现在是用"F"时选择了一圈,这样对于反复穿越的线只算一次,而改为"F"时一次只输入一段,多"F"几次,这样同样是选择一圈,"F"的次数却不同.还有你选择时没有回到第一点,是个未封闭区域,应该再把第一点加在最后.
对于需要多次剪切的问题,我也没办法.多次剪切总归不是治本之道.
关于此程序,有什么新的思路,欢迎与我交流.
发表于 2003-12-29 12:02:00 | 显示全部楼层
4楼说得对,我的多义线几乎都不用宽度的。所以有线宽的多义线都没有测试过。这个程序主要是让自己绘图时能快一些。所以一些自己不会遇到的情况都没有测试。封闭的弧形我试过是可以的。
偏移量的多少好像没有关系,一般的图几乎没有会用到0.01以下的数值。所以只要偏移的精度达到0.01就应该没有问题了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-11-28 10:47 , Processed in 0.156422 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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