ObjectARX
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to erase the transient graphics when layout switching

4 REPLIES 4
Reply
Message 1 of 5
nk_klein
1081 Views, 4 Replies

How to erase the transient graphics when layout switching

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

4 REPLIES 4
Message 2 of 5
nk_klein
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;
  }
 }
}

Message 3 of 5
Balaji_Ram
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" 🙂

            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

Message 4 of 5
Balaji_Ram
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

Message 5 of 5
nk_klein
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).

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost