- Keep track of current snaps.
- Set new snaps.
- Perform one or more actions.
- Restore initial snaps.
Usefull links
/// <summary>
///
Integer. Initial value 4133. Saved in Registry.
/// Sets
running object snaps.
/// The
setting is stored as a bitcode using the sum of the following values.
/// To
specify more then one object snap, enter the sum of their values.
/// </summary>
public enum Snaps
{
None = 0,
Endpoint = 1,
Midpoint = 2,
Center = 4,
Node = 8,
Quadrant = 16,
Intersection = 32,
Insertion = 64,
Perpendicular = 128,
Tangent = 256,
Nearest = 512,
ClearAll = 1024,
ApparentIntersection = 2048,
Extention = 4096,
Parallel = 8192,
TrackingLines = 16384
}
- My class will implement an interface
public interface ISnapMode
{
int InitialSnapMode { get; }
int CurrentSnapMode { get; }
int GetSnapMode();
void SetSnapMode(int mode);
void SetInitialSnapMode();
}
- The actual class implementation of the ISnapMode Interface
/// <summary>
/// Class that will keep track of the initial
snap mode when creating an instance of the class and sets the requested snap
mode.
/// Sets the snapmode to it's original state
when disposed.
/// </summary>
public class SnapMode : ISnapMode
{
#region Variables & Properties
/// <summary>
/// Private Variable. Keeps track of the
initial Snap Mode
/// </summary>
private readonly int _initialSnapMode;
/// <summary>
/// Public Property. Get the initial Snap Mode
before object initialization.
/// </summary>
public int InitialSnapMode
{
get { return _initialSnapMode; }
}
/// <summary>
/// Public Property. Get the current snap mode
after changing the initial snap mode.
/// </summary>
public int CurrentSnapMode
{
get { return GetSnapMode(); }
}
#endregion
#region Constructors
/// <summary>
/// Protected default constructor. Initialize
an instance of the object SnapMode.
/// </summary>
protected SnapMode()
{
_initialSnapMode = GetSnapMode();
}
/// <summary>
/// Overloaded constructor. Initialize an
instance of the object SnapMode.
/// </summary>
/// <param
name="snapTypes"></param>
public SnapMode(IEnumerable<Snaps> snapTypes)
: this()
{
//Only distinct snaps to calculate
the sum of all snap mode bitcode values.
SetSnapMode(CalculateSnapMode(snapTypes.Distinct()));
}
/// <summary>
/// Overloaded constructor. Initialize an
instance of the object SnapMode.
/// </summary>
/// <param
name="snap"></param>
public SnapMode(Snaps snap)
: this()
{
SetSnapMode(int.Parse(snap.ToString()));
}
/// <summary>
/// Overloaded constructor. Initialize an
instance of the object SnapMode.
/// </summary>
/// <param
name="snapMode">Integer. Requested snapmode. To specify more then one
object snap, enter the sum of their values</param>
public SnapMode(int snapMode)
{
SetSnapMode(snapMode);
}
#endregion
#region Implementing ISnapMode
/// <summary>
/// Get the current snap mode.
/// </summary>
/// <returns>Current snap mode bitcode
value.</returns>
public int GetSnapMode()
{
return int.Parse(Application.GetSystemVariable("osmode").ToString());
}
/// <summary>
/// Set the snap mode.
/// </summary>
/// <param
name="snapMode">Snap mode bitcode value.</param>
public void SetSnapMode(int snapMode)
{
Application.SetSystemVariable("osmode", snapMode);
}
/// <summary>
/// Will calculate the sum of all object snap
bitcode values within the collection.
/// </summary>
/// <param
name="snapTypes">Collection of snaps</param>
/// <returns>The sum of the snap bitcode
values.</returns>
public int CalculateSnapMode(IEnumerable<Snaps> snapTypes)
{
return snapTypes.Aggregate(0, (current,
snapType) => current + Convert.ToInt16(snapType));
}
public void SetInitialSnapMode()
{
SetSnapMode(_initialSnapMode);
}
#endregion
}
- Example using the previous posts example
[CommandMethod("SnapablePolylineJig")]
public void SnapablePolylineJig()
{
Polyline polyline;
var mode = new SnapMode(new List<Snaps> { Snaps.Endpoint, Snaps.Center });
try
{
var service = new PolylineJigService();
polyline = service.Draw(true, true);
}
finally
{
mode.SetInitialSnapMode();
}
if (polyline != null)
{
// Use a for loop to get each
vertex, one by one
var vn = polyline.NumberOfVertices;
var list = new List<Point2d>();
for (var i = 0; i < vn; i++)
{
// Could also get the 3D point
here
var pt = polyline.GetPoint2dAt(i);
list.Add(new Point2d(pt.X, pt.Y));
}
}
Document doc =
Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
// Now let's add the polyline to
the modelspace
Transaction tr =
db.TransactionManager.StartTransaction();
using (tr)
{
BlockTable bt =
(BlockTable) tr.GetObject(
db.BlockTableId,
OpenMode.ForRead
);
BlockTableRecord btr =
(BlockTableRecord) tr.GetObject(
bt[BlockTableRecord.ModelSpace],
OpenMode.ForWrite
);
ObjectId plineId =
btr.AppendEntity(polyline);
tr.AddNewlyCreatedDBObject(polyline, true);
tr.Commit();
ed.WriteMessage("\nPolyline
entity is: " +
plineId.ToString()
);
}
// Clear the temp graphics
(polyline should be in
// the same location, if selection
was not cancelled)
// We could "redraw"
instead of "regen" here
ed.Regen();
}
Why would you want to store such a thing in the registry? What happens if multiple applications are running and the both start racing to set some kind of reg value? (Saving to registry from your G+ post, does not appear to be in your article itself).
ReplyDeleteI understand what you mean! I havent found myself in that kind of situation. But I can imagine when you use multiple acad applications the 2 could change the registry values at the same time resulting in interfering.
ReplyDeleteIf there is a solutions without changing the registry values then I would be very interested.
What do you mean by => (Saving to registry from your G+ post, does not appear to be in your article itself)