My program checks several existing polylines, and I want to check all of them that don't meet some specific conditions.
I thought about duplicating the polyline with a problem with the yellow color, but it would be interesting if this duplicated polyline was temporary, and disappeared when used when the user applied the regen command.
Something similar to Autolisp's grdraw.
Thanks.
Solved! Go to Solution.
Solved by cadVDJ3M. Go to Solution.
Solved by hippe013. Go to Solution.
In general, you could use Transient Graphics for this kind of temporary graphics. Do a search this forum/the Internet for "Transient Graphics", you would find quite some sample code.
Norman Yuan
As @norman.yuan points out, using Transients would be ideal for something like this. I use transients all the time so I came up with the following classes.
Transient Base
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.GraphicsInterface
Namespace Transients
Public MustInherit Class TransientBase
Implements IDisposable
Public Property Entities As New List(Of Entity)
Public Overridable Sub SetColor(index As Integer)
For Each ent As Entity In Entities
ent.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByAci, index)
'ent.ColorIndex = index
Next
UpdateTransient()
End Sub
Protected Friend Sub AddTransients()
Dim ctm As TransientManager = TransientManager.CurrentTransientManager
For Each drawable As Drawable In Entities
ctm.AddTransient(drawable, TransientDrawingMode.Main, 128, New IntegerCollection)
Next
End Sub
Protected Friend Sub RemoveTransients()
Dim ctm As TransientManager = TransientManager.CurrentTransientManager
For Each drawable As Drawable In Entities
ctm.EraseTransient(drawable, New IntegerCollection)
Next
For Each ent As Entity In Entities
ent.Dispose()
Next
Entities.Clear()
End Sub
Protected Sub UpdateTransient()
Dim ctm As TransientManager = TransientManager.CurrentTransientManager
For Each drawable As Drawable In Entities
ctm.UpdateTransient(drawable, New IntegerCollection)
Next
End Sub
#Region "IDisposable Support"
Friend disposedValue As Boolean ' To detect redundant calls
' IDisposable
Protected Overridable Sub Dispose(disposing As Boolean)
If Not disposedValue Then
If disposing Then
' TODO: dispose managed state (managed objects).
End If
' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
' TODO: set large fields to null.
RemoveTransients()
For Each drawable As Drawable In Entities
drawable.Dispose()
Next
Entities.Clear()
End If
disposedValue = True
End Sub
' TODO: override Finalize() only if Dispose(disposing As Boolean) above has code to free unmanaged resources.
'Protected Overrides Sub Finalize()
' ' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above.
' Dispose(False)
' MyBase.Finalize()
'End Sub
' This code added by Visual Basic to correctly implement the disposable pattern.
Public Sub Dispose() Implements IDisposable.Dispose
' Do not change this code. Put cleanup code in Dispose(disposing As Boolean) above.
Dispose(True)
' TODO: uncomment the following line if Finalize() is overridden above.
' GC.SuppressFinalize(Me)
End Sub
#End Region
End Class
End Namespace
Transient that clears upon Regen
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.ApplicationServices
Namespace Transients
Public Class RegenClearTransient
Inherits TransientBase
Private _doc As Document
Public Sub New(entity As Entity, doc As Document)
Me.Entities.Add(entity)
AddTransients()
_doc = doc
AddHandler _doc.CommandWillStart, cmdStartHandler
End Sub
Private ReadOnly cmdStartHandler As CommandEventHandler = AddressOf OnCmdStart
Private Sub OnCmdStart(sender As Object, e As CommandEventArgs)
If e.GlobalCommandName.Contains("REGEN") Then
Me.RemoveTransients()
RemoveHandler _doc.CommandWillStart, cmdStartHandler
End If
End Sub
End Class
End Namespace
And then an example on how to use it
Private rcTrans As Transients.RegenClearTransient 'Must have a backer variable for the transient to stay in view.
<CommandMethod("TempPolyTransientExample")>
Public Sub CmdTempPolyTrans()
Dim aDoc As Document = Application.DocumentManager.MdiActiveDocument
Dim db As Database = aDoc.Database
Dim ed As Editor = aDoc.Editor
Dim opt As New PromptEntityOptions(vbCrLf + "Select Polyline: ")
opt.SetRejectMessage(vbCrLf + "Selected entity must be a Polyline. Try Again.")
opt.AddAllowedClass(GetType(Polyline), False)
Dim res As PromptEntityResult = ed.GetEntity(opt)
If res.Status <> PromptStatus.OK Then
Exit Sub
End If
Using tr As Transaction = db.TransactionManager.StartTransaction
Dim poly As Polyline = tr.GetObject(res.ObjectId, OpenMode.ForRead)
Dim cPoly As Entity = poly.Clone
cPoly.ColorIndex = 2
rcTrans = New Transients.RegenClearTransient(cPoly, aDoc)
tr.Commit()
End Using
End Sub
Thanks @hippe013 since the @norman.yuan talked about transients I've been researching this, but I haven't found such an effective way to eliminate them in a simple way through Regen..
I'll convert this code to C# (ie good because I learn more).
Thank you @hippe013 and @norman.yuan , with the tips provided I managed to solve the issue and understand how Transient Graphics works.
Here the solution I applied, a simpler code that meets my needs.
The idea of monitoring events is fantastic, and it can be useful for many things... I like this.
Here is the final code, with a lot of help from the web.
using System.Collections.Generic;
using System;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.ApplicationServices;
using AcadApplication = Autodesk.AutoCAD.ApplicationServices.Application;
using AcadDocument = Autodesk.AutoCAD.ApplicationServices.Document;
namespace MyTransients
{
class MyTransients
{
public static List<Entity> entities = new List<Entity>();
public static bool IsMonitoring = false;
public static void CreateTransient(Entity ent)
{
entities.Add(ent);
TransientManager.CurrentTransientManager.AddTransient(ent, TransientDrawingMode.DirectShortTerm, 128, new IntegerCollection());
MonitorCommandEvents_Method(); // Initialize Commands Events Monitor
}
public static void ClearTransient()
{
foreach (var item in entities)
{
TransientManager.CurrentTransientManager.EraseTransient(item, new IntegerCollection());
item.Dispose();
}
}
#region Event Monitor, to capture Autocad Commands
/// <summary>
/// Initialize event monitor
/// </summary>
public static void MonitorCommandEvents_Method()
{
if (!IsMonitoring)
{
SubscribeToDoc(AcadApplication.DocumentManager.MdiActiveDocument);
IsMonitoring = true;
}
}
/// <summary>
/// Monitored events
/// </summary>
/// <param name="doc"></param>
public static void SubscribeToDoc(AcadDocument doc)
{
doc.CommandWillStart += new CommandEventHandler(doc_CommandWillStart);
//Disabled for future use
//doc.CommandEnded += new CommandEventHandler(doc_CommandEnded);
//doc.CommandCancelled += new CommandEventHandler(doc_CommandCancelled);
//doc.CommandFailed += new CommandEventHandler(doc_CommandFailed);
//doc.UnknownCommand += new UnknownCommandEventHandler(doc_UnknownCommand);
}
static void doc_UnknownCommand(object sender, UnknownCommandEventArgs e)
{
(sender as AcadDocument).Editor.WriteMessage(string.Format("\nCommand {0} unknown.\n", e.GlobalCommandName));
}
static void doc_CommandFailed(object sender, CommandEventArgs e)
{
(sender as AcadDocument).Editor.WriteMessage(string.Format("\nCommand {0} failed.\n", e.GlobalCommandName));
}
static void doc_CommandCancelled(object sender, CommandEventArgs e)
{
(sender as AcadDocument).Editor.WriteMessage(string.Format("\nCommand {0} cancelled.\n", e.GlobalCommandName));
}
static void doc_CommandEnded(object sender, CommandEventArgs e)
{
(sender as AcadDocument).Editor.WriteMessage(string.Format("\nCommand {0} ended.\n", e.GlobalCommandName));
}
static void doc_CommandWillStart(object sender, CommandEventArgs e)
{
if (e.GlobalCommandName.Equals("REGEN", StringComparison.CurrentCultureIgnoreCase))
{
ClearTransient();
}
}
#endregion
}
}
Can't find what you're looking for? Ask the community or share your knowledge.