ObjectARX

Reply
Contributor
nk_klein
Posts: 13
Registered: ‎09-19-2007
Message 1 of 5 (341 Views)

How to erase the transient graphics when layout switching

341 Views, 4 Replies
02-22-2012 08:03 PM

Hi expert,

 

I'm working on ACM (ACA has the same issue). What I did is to call Autodesk.AutoCAD.GraphicsInterface.TransientManager.AddTransient to draw some transient graphics in model space, then if I switch to layout or set the TILEMODE to 0, I want to erase these graphics. what should I do?

 

Currently, I hook up the Application.SystemVariableChanging event to erase these graphics. If the visual style is "2D Wireframe", this method works fine. But if the visual style is NOT the "2D wireframe", for example it is the "Conceptual", the tranisent graphics can not be erased!

 

After some investigation, I found the Document.ViewChanged will be called before SystemVariableChaning if the visual style is NOT the "2D wireframe". In other words, the order of events is not the same if the visual style is different. And it seems I have to erase the transient graphics before the Document.ViewChanged event. But I don't know where can I do it.

 

Thanks,

Klein

Contributor
nk_klein
Posts: 13
Registered: ‎09-19-2007
Message 2 of 5 (327 Views)

Re: How to erase the transient graphics when layout switching

02-23-2012 09:39 PM in reply to: nk_klein

// I create a very simple example to show the issue, please see the following code.

// Test steps:

// 1. New a drawing
// 2. use netload command to load this assembly.
// 4. input "GraphTest" command
// 5. Switch to the paper space and then switch back to the model space
//
// If the visual style is the "2D Wireframe", the transient graphics will be erased successfully
// But if the visual style is NOT the "2D Wireframe", the transient graphics cannot be erased.

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

using System;
using System.Collections.Generic;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Colors;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;

 

namespace TransientGraphics
{
 public class Commands
 {
  // list used to hold the transient graphics
  private static List<Drawable> m_drawables = new List<Drawable>();

  [CommandMethod("GraphTest")]
  public static void TransientGraphicsCmd()
  {
   // hook up event
   Application.SystemVariableChanging += new Autodesk.AutoCAD.ApplicationServices.SystemVariableChangingEventHandler(Application_SystemVariableChanging);

   // create the transient graphics and then add the transient
   MyLineTransient transient = new MyLineTransient();
   TransientManager.CurrentTransientManager.AddTransient(transient, TransientDrawingMode.DirectShortTerm, 128, new IntegerCollection());

   // save it in the list
   m_drawables.Add(transient);
  }

  // erase these transient graphics when switching to paper space???
  static void Application_SystemVariableChanging(object sender, Autodesk.AutoCAD.ApplicationServices.SystemVariableChangingEventArgs e)
  {
   if (e.Name == /*MSG0*/"TILEMODE")
   {
    // If current tilemode is "1", the new tilemode is "0". At that situation, we need to clear transient graphics
    short nValue = (short)Application.TryGetSystemVariable(/*MSG0*/"TILEMODE");
    if (nValue == 1)  // Check OLD value
    {
     ClearTransGraphics(m_drawables);
    }
   }
  }

  private static void ClearTransGraphics(List<Drawable> drawables)
  {
   foreach (Drawable d in drawables)
   {
    bool transientRemoved = TransientManager.CurrentTransientManager.EraseTransient(d, new IntegerCollection());
    if (!transientRemoved)
    {
     System.Diagnostics.Debug.Assert(transientRemoved);
    }
    //d.Dispose();
   }
   drawables.Clear();
  }
 }

 //////////////////////////////////////////////////////////////////////////
 internal sealed class MyLineTransient : Transient
 {
  static readonly Vector3d UnitNormal = new Vector3d(0, 0, 1);
  internal EntityColor Color = new EntityColor(255, 0, 0);

  public MyLineTransient()
  {}

  protected override int SubSetAttributes(DrawableTraits traits)
  {
   return (int)DrawableAttributes.None;
  }

  protected override bool SubWorldDraw(WorldDraw wd)
  {
   wd.Geometry.PushPositionTransform(PositionBehavior.World, Point2d.Origin);
   return false;
  }

  Point3dCollection PathPoints
  {
   get
   {
    // Test points
    Point3dCollection points = new Point3dCollection();
    Point3d first = new Point3d(0, 10, 0);
    Point3d second = new Point3d(50, 10, 0);
    Point3d third = new Point3d(50, 60, 0);

    points.Add(first);
    points.Add(second);
    points.Add(third);

    return points;
   }
  }

  protected override void SubViewportDraw(ViewportDraw vd)
  {
   for (int i = 0; i < PathPoints.Count - 1; ++i)
   {
    Point3d startPoint = PathPoints[i];
    Point3d endPoint = PathPoints[i + 1];
    CreatePolyline(vd, startPoint, endPoint);
   }
  }

  private void CreatePolyline(ViewportDraw vd, Point3d startPoint, Point3d endPoint)
  {
   Point3dCollection vertices = new Point3dCollection() { startPoint, endPoint };

   EntityColor oldColor = vd.SubEntityTraits.TrueColor;
   LineWeight oldLineWeight = vd.SubEntityTraits.LineWeight;

   vd.SubEntityTraits.TrueColor = Color;
   vd.SubEntityTraits.LineWeight = Autodesk.AutoCAD.DatabaseServices.LineWeight.LineWeight018;
   vd.Geometry.Polyline(vertices, UnitNormal, IntPtr.Zero);

   vd.SubEntityTraits.TrueColor = oldColor;
   vd.SubEntityTraits.LineWeight = oldLineWeight;
  }
 }
}

ADN Support Specialist
Balaji_Ram
Posts: 660
Registered: ‎03-21-2011
Message 3 of 5 (315 Views)

Re: How to erase the transient graphics when layout switching

02-24-2012 01:24 AM in reply to: nk_klein

Hi Klein,

 

Can you try using the "Editor.UpdateTiledViewportsFromDatabase()" from the layoutswitched event callback ?.

Here is the modified sample code :

 

<code>

      // list used to hold the transient graphics

        privatestaticList<Drawable> m_drawables = newList<Drawable>();

 

        [CommandMethod("GraphTest")]

        publicstaticvoid TransientGraphicsCmd()

        {

            // Set the visual style to "Realistic"

            // Just to be sure I dont try all this with "2d Wireframe" :smileyhappy:

            SetVisualStyle();

 

            TransientGraphics.MyLineTransient transient = new TransientGraphics.MyLineTransient();

            TransientManager.CurrentTransientManager.AddTransient(transient, TransientDrawingMode.DirectShortTerm, 128, newIntegerCollection());

 

            LayoutManager.Current.LayoutSwitched += newLayoutEventHandler(Current_LayoutSwitched);

            m_drawables.Add(transient);

        }

 

        staticvoid Current_LayoutSwitched(object sender, LayoutEventArgs e)

        {

            if(e.Name.Equals("Model"))

            {

                ClearTransGraphics(m_drawables);

                Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

                ed.UpdateTiledViewportsFromDatabase();

            }

        }

 

        privatestaticvoid ClearTransGraphics(List<Drawable> drawables)

        {

            foreach (Drawable d in drawables)

            {

                bool transientRemoved = TransientManager.CurrentTransientManager.EraseTransient(d, newIntegerCollection());

                if (!transientRemoved)

                {

                    System.Diagnostics.Debug.Assert(transientRemoved);

                }

            }

            drawables.Clear();

        }

 

        privatestaticvoid SetVisualStyle()

        {

            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;

            Database db = HostApplicationServices.WorkingDatabase;

            using(Transaction tr = db.TransactionManager.StartTransaction())

            {

                ViewportTable vt = (ViewportTable)tr.GetObject(db.ViewportTableId, OpenMode.ForRead);

                ViewportTableRecord vtr = (ViewportTableRecord)tr.GetObject(vt["*Active"], OpenMode.ForWrite);

                DBDictionary dict = (DBDictionary)tr.GetObject(db.VisualStyleDictionaryId, OpenMode.ForRead);

                vtr.VisualStyleId = dict.GetAt("Realistic");

                tr.Commit();

            }

            ed.UpdateTiledViewportsFromDatabase();

        }

</code>

 



Balaji
Developer Technical Services
Autodesk Developer Network

ADN Support Specialist
Balaji_Ram
Posts: 660
Registered: ‎03-21-2011
Message 4 of 5 (314 Views)

Re: How to erase the transient graphics when layout switching

02-24-2012 01:26 AM in reply to: nk_klein

Hi Klein,

 

Just wanted to inform you that there is also a separate AutoCAD .Net API forum within the AutoCAD discussion groups. Since it was a .Net API related question, it fits in that more correctly.

 

 



Balaji
Developer Technical Services
Autodesk Developer Network

Contributor
nk_klein
Posts: 13
Registered: ‎09-19-2007
Message 5 of 5 (293 Views)

Re: How to erase the transient graphics when layout switching

02-26-2012 06:49 PM in reply to: Balaji_Ram

Thanks so much for your reply, Balaji.

UpdateTiledViewportsFromDatabase() can update the view only when switching back to Model space again, so I can see a fliker (the transient graphics disappear).

You are not logged in.

Log into access your profile, ask and answer questions, share ideas and more. Haven't signed up yet? Register

Announcements
Are you familiar with the Autodesk Expert Elites? The Expert Elite program is made up of customers that help other customers by sharing knowledge and exemplifying an engaging style of collaboration. To learn more, please visit our Expert Elite website.

Need installation help?

Start with some of our most frequented solutions to get help installing your software.

Ask the Community