明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 721|回复: 0

Drawing transient graphics appropriately in AutoCAD within m-paperspace vp

[复制链接]
发表于 2011-3-30 20:43 | 显示全部楼层 |阅读模式

Drawing transient graphics appropriately in AutoCAD within multiple paperspace viewports using .NET

作者:kean

原文地址:http://through-the-interface.typepad.com/through_the_interface/2011/03/drawing-transient-graphics-appropriately-in-autocad-within-multiple-paperspace-viewports-using-net.html

 

We’ve been looking a lot at transient graphics, recently. The standard approach we’ve been using to displaying graphics in all viewports has been to pass in an empty IntegerCollection into the various transient graphics-related methods, rather than listing the viewports specifically in which we want to display the graphics.

Thorsten Meinecke made the very valid point that this doesn’t always work as you’d like, particularly when you have multiple floating paperspace viewport. Now I fully admit I’m not a big user of viewports, as far as it goes, so I sometimes forget to cater for scenarios that are probably extremely common among AutoCAD users. Thorsten also kindly provided some code that does a much better job of supporting display in multiple viewports.

Here’s Thorsten’s C# code (formatted to fit this blog):

using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Geometry;

using Autodesk.AutoCAD.Runtime;

using AcGi = Autodesk.AutoCAD.GraphicsInterface;

using System.Collections.Generic;

using System;

 

namespace MyInsert

{

  public class MyInsertCommand

  {

    // The command MyInsert displays the transient entity

    // in all viewports (IntegerCollection is always empty)

 

    [CommandMethod("MyInsert")]

    public void MyInsert()

    {

      MyInsertCmd(new int[] { });

    }

 

    // The command MyInsertVP tries to be sensible: it

    // shows the transient entity in all viewports only

    // when TILEMODE = 1; in the paper space viewport

    // alone when CVPORT = 1; else in the active floating

    // viewports

 

    [CommandMethod("MyInsertVP")]

    public void MyInsertVP()

    {

      MyInsertCmd(ViewportNumbers());

    }

 

    // Naive implementation of block insert to demonstrate

    // the display of a transient entity

 

    void MyInsertCmd(int[] vps)

    {

      Document doc =

          Application.DocumentManager.MdiActiveDocument;

      Editor ed = doc.Editor;

      Database db = HostApplicationServices.WorkingDatabase;

 

      // Ask user for a block name and check if it's in

      // the BlockTable

 

      PromptStringOptions pso =

        new PromptStringOptions("Block name")

        {

          AllowSpaces = true

        };

      PromptResult psr = ed.GetString(pso);

 

      if (psr.Status != PromptStatus.OK)

        return;

 

      Transaction tr =

        db.TransactionManager.StartTransaction();

      using (tr)

      {

        BlockTable bt =

          (BlockTable)tr.GetObject(

            db.BlockTableId, OpenMode.ForRead

          );

        if (!bt.Has(psr.StringResult))

          ed.WriteMessage(

            "\nBlock {0} not found.", psr.StringResult

          );

        else

        {

          // Set up the BlockReference to draw as transient

 

          AcGi.TransientManager ctm =

            AcGi.TransientManager.CurrentTransientManager;

          IntegerCollection ints = new IntegerCollection(vps);

          BlockReference br =

            new BlockReference(

              Point3d.Origin, bt[psr.StringResult]

            );

          ctm.AddTransient(

            br, AcGi.TransientDrawingMode.DirectShortTerm,

            128, ints

          );

 

          // Add event handler for PointMonitor event, then

          // let user select an insertion point, afterwards

          // ensure removal of event handler and transient

 

          PointMonitorEventHandler handler =

            delegate(object sender, PointMonitorEventArgs e)

            {

              br.Position = e.Context.RawPoint;

              ctm.UpdateTransient(br, ints);

            };

          ed.PointMonitor += handler;

 

          PromptPointResult ppr;

          try

          {

            ppr = ed.GetPoint("Select insertion point");

          }

          finally

          {

            ed.PointMonitor -= handler;

            ctm.EraseTransient(br, ints);

          }

 

          // If insertion point selection was

          // successfull, add BlockReference to

          // current space

 

          if (ppr.Status == PromptStatus.OK)

          {

            BlockTableRecord cs =

              (BlockTableRecord)tr.GetObject(

                db.CurrentSpaceId, OpenMode.ForWrite

              );

            cs.AppendEntity(br);

            tr.AddNewlyCreatedDBObject(br, true);

          }

        }

        // Common exit point for all code paths inside

        // using statement

 

        tr.Commit();

      }

    }

 

    // Determines which viewports will display the transient

 

    int[] ViewportNumbers()

    {

      Document doc =

          Application.DocumentManager.MdiActiveDocument;

      Editor ed = doc.Editor;

      Database db = HostApplicationServices.WorkingDatabase;

 

      // Are we in model space outside floating viewports?

      // Then we'll initalize an empty IntegerCollection

 

      if (db.TileMode)

        return new int[] {};

 

      IList<int> vps = new List<int>();

      Transaction tr =

        db.TransactionManager.StartTransaction();

      using (tr)

      {

        Viewport vp =

          tr.GetObject(ed.ActiveViewportId, OpenMode.ForRead)

            as Viewport;

 

        // Are we in paper space and not inside a floating

        // viewport? Then only the paper space viewport itself

        // is of interest

 

        if (vp != null && vp.Number == 1)

          vps.Add(1);

        else

 

          // Now we're inside a floating viewport and

          // will display transients in active viewports

 

          foreach (ObjectId vpId in db.GetViewports(false))

          {

            vp = (Viewport)tr.GetObject(vpId, OpenMode.ForRead);

            vps.Add(vp.Number);

          };

 

        tr.Commit();

      }

      int[] ints = new int[vps.Count];

      vps.CopyTo(ints, 0);

 

      return ints;

    }

  }

}

The above code defines two commands:

  • MYINSERT, which uses the “empty IntegerCollection” approach to show transients in all viewports
  • MYINSERTVP, which uses a more controlled approach to display the graphics in selected paperspace viewports

To demonstrate the problem with the first approach, let’s take a paperspace view with two floating viewports:

When we make the larger viewport active and start the MYINSERT command to insert a block, we sometimes see unwanted graphics in the top-level paperspace view:

But if we use MYINSERTVP, we don’t have that problem:

Many thanks, Thorsten, for highlighting this issue and providing a solution for it! :-)

本帖子中包含更多资源

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

x
"觉得好,就打赏"
还没有人打赏,支持一下

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

GMT+8, 2024-5-18 13:46 , Processed in 0.187457 second(s), 31 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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