乐筑天下

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

尝试查找块引用,但没有成功

[复制链接]

21

主题

58

帖子

3

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
142
发表于 2017-5-11 06:12:59 | 显示全部楼层 |阅读模式
使用以下代码
  1.     Private Function GetBlockReferenceFromList(ByVal thisDocument As Document, _
  2.                                                ByVal db As Database, _
  3.                                                ByVal transaction As Transaction, _
  4.                                                ByVal listOfBlockRefNames As List(Of String)) As List(Of BlockReference)
  5.         Dim listOfBlockRef As New List(Of BlockReference)
  6.         Dim blockTable As BlockTable
  7.         Dim blockTableRecord As BlockTableRecord
  8.         Dim objectID As ObjectId
  9.         Dim objectCollection As ObjectIdCollection
  10.         Dim i As Integer
  11.         Dim blockRef As BlockReference
  12.         Try
  13.             blockTable = transaction.GetObject(db.BlockTableId, OpenMode.ForRead)
  14.             For Each objectID In blockTable
  15.                 blockTableRecord = TryCast(transaction.GetObject(objectID, OpenMode.ForRead), BlockTableRecord)
  16.                 If Not IsNothing(blockTableRecord) Then
  17.                     objectCollection = blockTableRecord.GetBlockReferenceIds(True, False)
  18.                     If Not IsNothing(objectCollection) Then
  19.                         If objectCollection.Count > 0 Then
  20.                             For i = 0 To objectCollection.Count
  21.                                 blockRef = TryCast(transaction.GetObject(objectCollection(i), OpenMode.ForRead), BlockReference)
  22.                                 If Not IsNothing(blockRef) Then
  23.                                     If listOfBlockRefNames.Contains(blockRef.Name) Then
  24.                                         listOfBlockRef.Add(blockRef)
  25.                                     End If
  26.                                 End If
  27.                             Next
  28.                         End If
  29.                     End If
  30.                 End If
  31.             Next
  32.         Catch ex As Exception
  33.             MsgBox("HollowCore_RemoveBlockReference.GetBlockReferenceFromList : " & ex.Message, MsgBoxStyle.OkOnly, EasiCADException.EasiCADErrorTitle)
  34.         End Try
  35.         Return listOfBlockRef
  36.     End Function

我使用的是AutoCAD 2014, VS2010(. NET v4)。
为了正确看待这个功能,我继承了一个创建和维护块(用于表示平面图上的混凝土板)的系统,每个块应该只有一个块引用。我正在寻找具有重复块引用的图纸,其中一个或其他定制命令,例如复制、移动,正在破坏并将这些重复的东西留在周围,这些是不可见的。上述功能是删除重复块引用的更广泛功能的一部分。

本帖以下内容被隐藏保护;需要你回复后,才能看到!

游客,如果您要查看本帖隐藏内容请回复
回复

使用道具 举报

170

主题

1424

帖子

8

银币

顶梁支柱

Rank: 50Rank: 50

铜币
2119
发表于 2017-5-11 11:25:13 | 显示全部楼层
检查相同的插入点和旋转。
检查可见性
检查非注释性和注释性(如果在来自同一块的块参照中发现两者,则某些块将不可见)
回复

使用道具 举报

4

主题

219

帖子

4

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
238
发表于 2017-5-11 13:49:58 | 显示全部楼层
您可能希望更详细地说明“没有成功”的含义。您的意思是您确实知道图形中存在具有给定块名称的块引用,但代码找不到它(因此,函数返回具有Count= 0的列表)?
如果是这种情况,那么可能有 2 个原因,从你的代码中看到:
1. 代码将块引用的名称与此处的已知块名称列表进行比较:
如果 listOfBlockRefNames.Contains(blockRef.Name) 则
此代码有问题的原因是列表中的块名称,块引用的名称可能字面上相同,但大小不相同(上或下), 然后是“如果...”中的条件可能会返回 False。
2. 您没有提到,但如果感兴趣的块是动态块,则块引用的名称可能是由 AutoCAD 生成的匿名块名称。因此,如果该块可能是动态的,则需要找到其“有效”名称,而不是 BlockReference.Name。
此外,由于您只对一组给定的块名称感兴趣,因此您可以遍历块名称列表,而不是遍历整个块记录表。这将使代码逻辑更易于遵循。类似的东西:
Private Function GetBlockReferenceFromList(db as Database, tran as Trsnaction, blkNames as List(of String)) As ...
Dim listOfBlockRef As New List(of BlockReference)
Dim blockTable as BlockTable=....
对于每个 blkName As String in blkNames
If blockTable.Has(blkName) 则
Dim brefs=GetBlockRefs(tran, blockTable(blkName))
if brefs.Count>0 then
listOfBlockref.AddRange(brefs)
End If
End If
Next
Return lisOfBlockRef
End Function
Private Function GetBlockRefs(tran as Transaction, blkId as ObjectId) As List(of BlockReference)
Dim brefs as New List(of BlockReference)()
Dim blockRecord=DirectCast(tran.GetObject(blkId,OpenMode.ForRead), BlockTableRecord)

''Get direct BlockReference
Dim blks=FindBlockReferences(tran, blockRecord)
If blks.Count>0 然后是 brefs。AddRange(blks)
''If the block is dynamic
If blkRecord.IsDynamic then
Dim anonyBlkIds=blockRecord.GetAnonymousBlockIds()
If anonyBlkIds Is Not Nothing andAlso anonyBlkIds.Count>0 Then
For Each blkId As ObjectId in anonyBlkIds
Dim anonyBlkRecord=DirectCast(tran.GetObject(blkId,OpenMode.ForRead), BlockTableRecord)
blks=FindBlockReferences(tran, anonyBlkRecord)
If blks.Count>0 然后是 brefs。AddRange(blks)
end if
end if
end if end if
return brefs
end function
Private Function FindBlockreferences(tran As Transaction, blkRecord as BlockTableRecord) As List(of BlockReference)
Dim brefs as New List(of BlockReference)()

Dim idCollection=blkRecord.GetBlockReferenceIds(True, False)
if idCollection Is Not Nothing and also idCollection.Count>0 then
for each idCollection.Count>0 then for each idCollection in idCollection
         bref.Add((DirectCast(tran.GetObject(id, OpenMode.ForRead), Blockreference))
Next
End If
Return brefs
End Function
代码没有经过测试,但你明白了:
1. 使用 BlockTable.Has() 查看数据库中是否存在具有特定名称的块定义。在这里,您不必自己比较块名称(消除潜在角色的CASE问题);使用BlockTable.Has()方法在循环访问您的块名称列表时,如果块名称确实是定义的BlockTableRecord,则只会更深入;
2. 如果感兴趣的区块可以是动态区块,则必须确保同时搜索到相应的匿名区块引用
回复

使用道具 举报

21

主题

58

帖子

3

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
142
发表于 2017-5-12 08:09:35 | 显示全部楼层
非常感谢,n元。因此,缺乏成功的原因确实是我知道有命名块引用,而我的代码没有找到它们。它确实找到了块引用,但没有找到我知道存在的名称
系统的大部分使用COM风格的编程,最后我用这种方法编写了例程,只是为了让它正常工作:
  1.     Private Function GetBlockReferenceFromList(ByVal thisDrawing As AcadDocument, ByVal listOfBlockRefNames As List(Of String)) As List(Of AcadBlockReference)
  2.         Dim listOfBlockRef As New List(Of AcadBlockReference)
  3.         Dim blockRef As AcadBlockReference
  4.         Dim selectionSet As AcadSelectionSet = Nothing
  5.         Dim filterType(1) As Short
  6.         Dim filterData(1) As Object
  7.         Try
  8.             selectionSet = CreateSelSet(thisDrawing, "RemoveBlockReferences")
  9.             filterType(0) = 0
  10.             filterData(0) = "INSERT"     
  11.             filterType(1) = 8
  12.             filterData(1) = "SLABOUTLINE"
  13.             selectionSet.Select(AcSelect.acSelectionSetAll, , , filterType, filterData)
  14.             If selectionSet.Count > 0 Then
  15.                 For Each blockRef In selectionSet
  16.                     If listOfBlockRefNames.Contains(blockRef.Name) Then
  17.                         listOfBlockRef.Add(blockRef)
  18.                     End If
  19.                 Next
  20.             End If
  21.         Catch ex As Exception
  22.             MsgBox("HollowCore_RemoveObjects.GetBlockReferenceFromList : " & ex.Message, MsgBoxStyle.OkOnly, EasiCADException.EasiCADErrorTitle)
  23.         Finally
  24.             If Not IsNothing(selectionSet) Then
  25.                 selectionSet.Clear()
  26.             End If
  27.             DelSelSet(thisDrawing, "RemoveBlockReferences")
  28.         End Try
  29.         Return listOfBlockRef
  30.     End Function

然而,我希望尽可能远离COM,所以我会在有时间的时候使用您的指针进一步研究
所讨论的块和块引用名称是数字,因此不考虑大小写敏感度……但了解这一点很有用。谢谢。我在编辑那里注意到了这一点。GetString函数。
关于块是否是动态的,我不确定。系统使用AcadDocument.Blocks。添加函数以添加块和AcadDocument.ModelSpace。用于BlockReferences的InsertBlock函数(我无法理解为什么名为InsertBlocks的例程返回BlockReference)。
回复

使用道具 举报

发表回复

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

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

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

GMT+8, 2025-2-4 13:44 , Processed in 0.160189 second(s), 60 queries .

© 2020-2025 乐筑天下

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