明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 4926|回复: 9

[讨论]如何在ObjectARX 2008中获得边界对象

[复制链接]
发表于 2010-8-28 21:28:00 | 显示全部楼层 |阅读模式

AutoCAD 2009新增了Autodesk.AutoCAD.BoundaryRepresentation可以使用BoundaryLoop class 处理边界对象,Kean的一篇Blog也提到了在2011中怎样使用  Editor.TraceBoundary() 获得边界对象。

但是,现在的问题是,在AutoCAD 2008中如何提取边界对象?

例如下图所示,四条直线的ObjectId均已知,直线封闭边界内部的某一个点的坐标也已知,怎样提取图中封闭的边界?

 

注意:这里要问的主要是思路,上图情况采用求交点的方式蛮干还是可以实现的。

         实际实现的过程中,封闭边界可能是由直线、圆弧等实体组成,亦可能包含孤岛等情况。

 

我有这样的想法:

在AutoCAD中,使用Boundary命令,定义边界内部的一个点,可以创建一个边界的多段线对象。在程序中,创建一个全新的图层并定义为当前图层,然后调用-Boundary命令,这时生成的多段线边界对象便可以提取出来了。

这个方法感觉有点笨。欢迎大家讨论!

本帖子中包含更多资源

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

x
发表于 2010-8-28 21:39:00 | 显示全部楼层

用命令还是比较简单的,但必须要让区域在视口中可见

自己实现的话,现成的算法应该是有的,google下看看?

 楼主| 发表于 2010-8-29 00:06:00 | 显示全部楼层

多谢lzh741206的关注。

还是采用-Boundary命令的方式来实现的,不过没有我在上面说的那么土,要用新图层什么的,哈哈

参考了“ObjectARX编程站”如下帖子(感谢zmkm1234和wz0406):

http://www.objectarx.net/forum.php?mod=viewthread&tid=867&highlight=%B1%DF%BD%E7

 

我的VB.Net代码如下:

 

Public Class ModelSpace

    <Runtime.InteropServices.DllImport("acad.exe", SetLastError:=True)> _

    Private Shared Function acedCmd(ByVal vlist As System.IntPtr) As Integer

    End Function

 

    Public Shared Function GetColsedBoundary(ByVal InnerX As Double, ByVal InnerY As Double) As ObjectId

 

        Dim rb As ResultBuffer = New ResultBuffer

        Try

            rb.Add(New TypedValue(5005, "._-BOUNDARY"))

            rb.Add(New TypedValue(5005, "_AD"))

            rb.Add(New TypedValue(5005, "_IS"))

            If IslandDetection = 1 Then

                rb.Add(New TypedValue(5005, "_Y"))     'Y表示启动孤单检测

            Else

                rb.Add(New TypedValue(5005, "_N"))     'N表示不启动孤单检测

                rb.Add(New TypedValue(5005, "_N"))     '射线投影类型:默认的Nearest<N>。

'注意:有时会出现点在边界外的问题,所以尽量要启用孤岛检测

            End If

 

            rb.Add(New TypedValue(5005, "_OB"))

            rb.Add(New TypedValue(5005, "PO"))

            rb.Add(New TypedValue(5005, ""))

            rb.Add(New TypedValue(5005, (InnerX.ToString + ("," + InnerY.ToString))))

            rb.Add(New TypedValue(5005, ""))

 

            acedCmd(rb.UnmanagedObject)

            Dim db As Database = GetDB()

            Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor

            Dim psr As PromptSelectionResult = ed.SelectLast

            Dim ObjIds As ObjectId() = psr.Value.GetObjectIds

            If ObjIds IsNot Nothing And ObjIds.Length > 0 Then

                Dim ObjId As ObjectId = ObjIds(0)

                Using trans As Transaction = db.TransactionManager.StartTransaction

                    Dim obj As DBObject = trans.GetObject(ObjId, OpenMode.ForRead)

                    If TypeOf (obj) Is Polyline Then

                        Dim ObjectPolyPolyline As Polyline = obj

                        Dim msg As String = String.Format("Area = {0} ", ObjectPolyPolyline.Area)

                        ed.WriteMessage(msg)

                        Return ObjId

                    End If

                End Using

 

            End If

 

        Catch ex As System.Exception

            MsgBox("Hatch Boundary Error " & ex.Message)

            Return ObjectId.Null

        Finally

            rb.Dispose()

        End Try

    End Function

 

End Class

 楼主| 发表于 2010-8-29 11:58:00 | 显示全部楼层
本帖最后由 作者 于 2010-8-29 14:05:03 编辑

实际上,这样做有一个问题,如果边界内部含有孤岛的话,-Boundary命令可以检测出来,也会在CAD上提示检测到,但是使用上面的代码却是无法提取孤岛边界多段线的。
假如:有外部边界和内部孤岛边界时,-Boundary检测并创建两个封闭的多段线边界,但在

Dim psr As PromptSelectionResult = ed.SelectLast

Dim ObjIds As ObjectId() = psr.Value.GetObjectIds

执行后,objIds的长度只有1,也就是只能提取外部边界对象,内部孤岛边界对象是无法提取的。

 

怎样才能将内部孤岛的多段线对象也提取出来呢?

 

另:有人使用ARX命令acdbEntLastacdbEntNext可以实现,在ObjectARX .NET里面这两个函数的对应函数分别是什么?

发表于 2010-8-29 17:34:00 | 显示全部楼层

.NET里面这两个函数的对应函数:Utils.EntLast/Next

内部孤岛:

命令: -Boundary
指定内部点或 [高级选项(A)]: a
输入选项 [边界集(B)/孤岛检测(I)/对象类型(O)]: i
是否需要孤岛检测?[是(Y)/否(N)] <Y>: y
输入选项 [边界集(B)/孤岛检测(I)/对象类型(O)]: o
输入边界对象类型 [面域(R)/多段线(P)] <多段线>: p
输入选项 [边界集(B)/孤岛检测(I)/对象类型(O)]:
指定内部点或 [高级选项(A)]: 正在选择所有对象...
正在选择所有可见对象...
正在分析所选数据...

正在分析内部孤岛...

指定内部点或 [高级选项(A)]:
BOUNDARY 已创建 2 个多段线

发表于 2010-8-29 17:36:00 | 显示全部楼层

不过如果内部点选择错误的话,-Boundary命令会出问题的,要考虑这个问题

 

 楼主| 发表于 2010-8-29 20:48:00 | 显示全部楼层

AutoCAD2010版本的acmgd.dll才有Utils.EntLast/Next函数。

在AutoCAD2008,acmgdinternal.dll有Utils,但是没有上面的两个函数。

好遗憾啊!

 楼主| 发表于 2010-8-30 00:04:00 | 显示全部楼层

多谢lzh741206的提醒!

 

经过不懈的努力,终于搞定了。

具体思路为:

在ObjectARX .Net程序中同时使用COM编程,在调用-Boundary命令之前和之后分别使用

       ThisDrawing.ModelSpace.Count

得到各个状态模型空间的实体总个数,然后在两个实体总个数差异值的区间内使用

       Dim ent As AcadEntity = ThisDrawing.ModelSpace.Item(i)

得到外部边界与内部边界多段线对象。

----------------------------------------------------------------------------------------

实际上,在此之前,我也使用了在调用-Boundary命令之前新建图层并设为当前图层,

在调用-Boundary命令之后再使用ed.SelectAll()选择当前图层上的所有对象这一思路。

代码如下:

            '定义过滤条件
            Dim value1 As TypedValue = New TypedValue(DxfCode.LayerName, TempLayerName)
            Dim value2 As TypedValue = New TypedValue(DxfCode.Start, "Polyline")
            Dim Values() As TypedValue = {value1, value2}
            Dim sf As New SelectionFilter(Values)
            '执行选择
            Dim psr As PromptSelectionResult = ed.SelectAll(sf)

但是执行到上面最后一条语句时报错,不知道怎么回事。

望指教!

发表于 2010-8-30 16:55:00 | 显示全部楼层

多段线是"LWPolyline“吧?

 楼主| 发表于 2010-8-31 10:52:00 | 显示全部楼层
lzh741206发表于2010-8-30 16:55:00多段线是\"LWPolyline“吧?

正解!就是这个的问题!换成LWPolyline就没有问题了!

佩服!感谢!

 

顺着这个思路,重新复习了一下DXF参考手册,有收获啊!

您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-11-26 00:50 , Processed in 0.198622 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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