乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 140|回复: 9

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

[复制链接]

11

主题

51

帖子

2

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
95
发表于 2010-8-28 21:28:00 | 显示全部楼层 |阅读模式
2009新增了Autodesk.AutoCAD.BoundaryRepresentation可以使用BoundaryLoop class 处理边界对象,Kean的一篇Blog也提到了在2011中怎样使用  Editor.TraceBoundary() 获得边界对象。
但是,现在的问题是,在AutoCAD 2008中如何提取边界对象?
例如下图所示,四条直线的ObjectId均已知,直线封闭边界内部的某一个点的坐标也已知,怎样提取图中封闭的边界?

sus4rem25k4.jpg

sus4rem25k4.jpg




注意:这里要问的主要是思路,上图情况采用求交点的方式蛮干还是可以实现的。
         实际实现的过程中,封闭边界可能是由直线、圆弧等实体组成,亦可能包含孤岛等情况。

我有这样的想法:
在AutoCAD中,使用Boundary命令,定义边界内部的一个点,可以创建一个边界的多段线对象。在程序中,创建一个全新的图层并定义为当前图层,然后调用-Boundary命令,这时生成的多段线边界对象便可以提取出来了。
这个方法感觉有点笨。欢迎大家讨论!
回复

使用道具 举报

72

主题

2726

帖子

9

银币

社区元老

Rank: 75Rank: 75Rank: 75

铜币
3014
发表于 2010-8-28 21:39:00 | 显示全部楼层
用命令还是比较简单的,但必须要让区域在视口中可见
自己实现的话,现成的算法应该是有的,google下看看?
回复

使用道具 举报

11

主题

51

帖子

2

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
95
发表于 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
     _
    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。
'注意:有时会出现点在边界外的问题,所以尽量要启用孤岛检测
            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
回复

使用道具 举报

11

主题

51

帖子

2

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
95
发表于 2010-8-29 11:58:00 | 显示全部楼层

实际上,这样做有一个问题,如果边界内部含有孤岛的话,-Boundary命令可以检测出来,也会在CAD上提示检测到,但是使用上面的代码却是无法提取孤岛边界多段线的。
假如:有外部边界和内部孤岛边界时,-Boundary检测并创建两个封闭的多段线边界,但在
Dim psr As PromptSelectionResult = ed.SelectLast
Dim ObjIds As ObjectId() = psr.Value.GetObjectIds
执行后,objIds的长度只有1,也就是只能提取外部边界对象,内部孤岛边界对象是无法提取的。

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

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

使用道具 举报

72

主题

2726

帖子

9

银币

社区元老

Rank: 75Rank: 75Rank: 75

铜币
3014
发表于 2010-8-29 17:34:00 | 显示全部楼层
.NET里面这两个函数的对应函数:Utils.EntLast/Next
内部孤岛:
命令: -Boundary
指定内部点或 [高级选项(A)]: a
输入选项 [边界集(B)/孤岛检测(I)/对象类型(O)]: i
是否需要孤岛检测?[是(Y)/否(N)] : y
输入选项 [边界集(B)/孤岛检测(I)/对象类型(O)]: o
输入边界对象类型 [面域(R)/多段线(P)] : p
输入选项 [边界集(B)/孤岛检测(I)/对象类型(O)]:
指定内部点或 [高级选项(A)]: 正在选择所有对象...
正在选择所有可见对象...
正在分析所选数据...
正在分析内部孤岛...
指定内部点或 [高级选项(A)]:
BOUNDARY 已创建 2 个多段线
回复

使用道具 举报

72

主题

2726

帖子

9

银币

社区元老

Rank: 75Rank: 75Rank: 75

铜币
3014
发表于 2010-8-29 17:36:00 | 显示全部楼层
不过如果内部点选择错误的话,-Boundary命令会出问题的,要考虑这个问题

回复

使用道具 举报

11

主题

51

帖子

2

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
95
发表于 2010-8-29 20:48:00 | 显示全部楼层
AutoCAD2010版本的acmgd.dll才有Utils.EntLast/Next函数。
在AutoCAD2008,acmgdinternal.dll有Utils,但是没有上面的两个函数。
好遗憾啊!
回复

使用道具 举报

11

主题

51

帖子

2

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
95
发表于 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)

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

使用道具 举报

72

主题

2726

帖子

9

银币

社区元老

Rank: 75Rank: 75Rank: 75

铜币
3014
发表于 2010-8-30 16:55:00 | 显示全部楼层
多段线是"LWPolyline“吧?
回复

使用道具 举报

11

主题

51

帖子

2

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
95
发表于 2010-8-31 10:52:00 | 显示全部楼层
正解!就是这个的问题!换成LWPolyline就没有问题了!
佩服!感谢!

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

使用道具 举报

发表回复

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

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-3-15 07:32 , Processed in 0.368019 second(s), 75 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表