乐筑天下

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

如何以动态块名来设置过滤器来过滤图形中所有块参照?

[复制链接]

89

主题

410

帖子

8

银币

中流砥柱

Rank: 25

铜币
766
发表于 2013-12-4 15:27:00 | 显示全部楼层 |阅读模式
如题,常规块可以通过blockname过滤,而动态块CAD名与取得的blockname不一致?怎么解决?谢谢!
回复

使用道具 举报

4

主题

19

帖子

2

银币

初来乍到

Rank: 1

铜币
35
发表于 2013-12-6 22:27:00 | 显示全部楼层
每一个动态块参照的本质是一个匿名块。
如果按匿名块的块名来过滤,其过滤器需要在匿名块名前加“‘”字符
例如(2,'*D2)
回复

使用道具 举报

4

主题

19

帖子

2

银币

初来乍到

Rank: 1

铜币
35
发表于 2013-12-6 22:32:00 | 显示全部楼层
Creating a selection filter that finds dynamic blocks in AutoCAD using .NET

An interesting question came in via email from Rob Outman. He’s interested in applying a selection filter when the user selects dynamic blocks. This is straightforward for unmodified dynamic blocks – just as with standard blocks, you can filter on the block name very easily – but it works less well on dynamic blocks whose properties have been modified at an instance level.
Essentially what happens is this: if you select a block reference to a dynamic block in the AutoCAD editor and then use (for example) the Properties window to edit some of the custom properties associated with that block, the block definition gets duplicated as an anonymous block – with the modified properties, of course – and the reference gets updated to point to that. If you LIST the block reference, you can see that it still mentions the originating block by name, so it’s clear some connection still exists between the two block definitions, at the very least.
Listing the properties of a modified dynamic block reference
This makes it a little difficult to use a SelectionFilter to look for these BlockReference objects, as their associated BlockTableRecord has a name such as “*U24” rather than the name being searched for.
The answer to this riddle was actually reasonably straightforward, in the end. Using the very handy ArxDbg sample, it was easy to find out that the modified block definition contains XData linking back to the original – under the AcDbBlockRepBTag app name there’s an entry containing its handle – which we can use to compile a list of the (anonymous) names of modified blocks for which to look.
ArxDbg showing the XData linking modified dynamic blocks to their originals
We can then create a conditional SelectionFilter – with an “or” clause listing each of these names – and use that to find any block meeting the condition.
Here’s the C# code that does all this:
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using System.Collections.Generic;

namespace EntitySelection
{
  public class Commands
  {
    [CommandMethod("SDB")]
    static public void SelectDynamicBlocks()
    {
      var doc = Application.DocumentManager.MdiActiveDocument;
      var ed = doc.Editor;

      var pso =
        new PromptStringOptions(
          "\nName of dynamic block to search for"
        );
      pso.AllowSpaces = true;

      var pr = ed.GetString(pso);

      if (pr.Status != PromptStatus.OK)
        return;

      string blkName = pr.StringResult;

      List blkNames = new List();
      blkNames.Add(blkName);

      var tr = doc.TransactionManager.StartTransaction();
      using (tr)
      {
        var bt =
          (BlockTable)tr.GetObject(
            doc.Database.BlockTableId,
            OpenMode.ForRead
          );

        // Start by getting the handle of our block, if it exists

        if (!bt.Has(blkName))
        {
          ed.WriteMessage(
            "\nCannot find block called \"{0}\".", blkName
          );
          return;
        }

        var btr =
          (BlockTableRecord)tr.GetObject(
            bt[blkName], OpenMode.ForRead
          );

        var blkHand = btr.Handle;

        foreach (var bid in bt)
        {
          // We'll check each block in turn, to see if it has
          // XData pointing to our original block definition

          var btr2 =
            (BlockTableRecord)tr.GetObject(bid, OpenMode.ForRead);

          // Only check blocks that don't share the name :-)

          if (btr2.Name != blkName)
          {
            // And only check blocks with XData

            var xdata = btr2.XData;
            if (xdata != null)
            {
              // Get the XData as an array of TypeValues and loop
              // through it

              var tvs = xdata.AsArray();
              for (int i=0; i  blkNames
    )
    {
      // If we don't have any block names, return null

      if (blkNames.Count == 0)
        return null;

      // If we only have one, return an array of a single value

      if (blkNames.Count == 1)
        return new TypedValue[] {
          new TypedValue(
            (int)DxfCode.BlockName,
           blkNames[0]
          )
        };

      // We have more than one block names to search for...

      // Create a list big enough for our block names plus
      // the containing "or" operators

      List tvl =
        new List(blkNames.Count + 2);

      // Add the initial operator

      tvl.Add(
        new TypedValue(
          (int)DxfCode.Operator,
          ""
        )
      );

      // Return an array from the list

      return tvl.ToArray();
    }
  }
}
An interesting point to note: we need to prefix any anonymous block name with an inverted apostrophe (“`”) character, as that seems to be the way to “escape” asterisks in this situation.
回复

使用道具 举报

89

主题

410

帖子

8

银币

中流砥柱

Rank: 25

铜币
766
发表于 2013-12-27 09:27:00 | 显示全部楼层
非常感谢!
回复

使用道具 举报

14

主题

80

帖子

7

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
136
发表于 2014-11-3 21:19:00 | 显示全部楼层
标记一下,方便查找
回复

使用道具 举报

发表回复

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

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

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

GMT+8, 2025-6-28 23:12 , Processed in 0.635965 second(s), 63 queries .

© 2020-2025 乐筑天下

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