Hi all,
I need an overrule that can not snaps object in all locked layers.
I have no idea how to do that. Any idea or algorithm, at least as a start, greatly appreciated.
Hi,
how did you disable object-snaps for geometry on locked layers?
Or do I misunderstand your question?
- alfred -
Hi,
sorry, I understood it in the other way, you have no object snaps and want to activate them 😉
Anyway, >>>Through the Interface<<< has a blog for customized object-snaps, hope this is a help for you.
- alfred -
Here is a sample code, see result in command line
Public Sub TestSelectionOnLockedLayers() '' Get the current document and database Dim doc As Document = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument Dim db As Database = doc.Database Dim ed As Editor = doc.Editor '' Start a transaction Using tr As Transaction = db.TransactionManager.StartTransaction() Try Dim pso As New PromptSelectionOptions '' change allow to select on locked layers here: pso.RejectObjectsOnLockedLayers = False '<-- can select on locked layers pso.AllowDuplicates = False pso.SinglePickInSpace = False pso.SingleOnly = False pso.AllowSubSelections = False pso.MessageForAdding = (vbLf & "Select objects:") Dim tvs(4) As TypedValue tvs(0) = New TypedValue(-4, "<or") tvs(1) = New TypedValue(0, "LWPOLYLINE") tvs(3) = New TypedValue(0, "LINE") tvs(2) = New TypedValue(0, "CIRCLE") tvs(3) = New TypedValue(0, "ELLIPSE") tvs(3) = New TypedValue(0, "SPLINE") tvs(3) = New TypedValue(0, "3DPOLY") ''ETC... tvs(4) = New TypedValue(-4, "or>") Dim filter As New SelectionFilter(tvs) Dim res As PromptSelectionResult res = ed.GetSelection(pso, filter) '' If selection is ok, then continue If res.Status <> PromptStatus.OK Then Return Dim ids As ObjectId() = res.Value.GetObjectIds() If ids.Length = 0 Then Return End If For Each id As ObjectId In ids Dim ent As Entity = DirectCast(tr.GetObject(id, OpenMode.ForRead), Entity) ' cast object as Circle If TypeOf ent Is Circle Then Dim circ As Circle = ent Dim cpt As Point3d = circ.Center Dim rad As Double = circ.Radius ed.WriteMessage(vbLf & "DXF name: " & id.ObjectClass().DxfName) ed.WriteMessage(vbLf & "ObjectID: " & id.ToString()) ed.WriteMessage(vbLf & "Handle: " & id.Handle.ToString()) ed.WriteMessage(vbLf & "Layer: " & circ.Layer.ToString()) ed.WriteMessage(vbLf & "Center: {0:f4};{1:f4};{2:f4}", cpt.X, cpt.Y, cpt.Z) ed.WriteMessage(vbLf & "Radius: {0:f2}", rad) ed.WriteMessage(vbLf) End If 'cast object as Lwpolyline If TypeOf ent Is Polyline Then Dim poly As Polyline = ent Dim n As Integer = 0 Dim sb As New StringBuilder For n = 0 To poly.NumberOfVertices - 1 Dim pt As Point2d = poly.GetPoint2dAt(n) sb.AppendLine(String.Format(vbLf & "Vertex # {0} ---> {1:f4};{2:f4}", n, pt.X, pt.Y)) Next ed.WriteMessage(vbLf & "DXF name: " & id.ObjectClass().DxfName) ed.WriteMessage(vbLf & "ObjectID: " & id.ToString()) ed.WriteMessage(vbLf & "Handle: " & id.Handle.ToString()) ed.WriteMessage(vbLf & "Layer: " & poly.Layer.ToString()) ed.WriteMessage(vbLf & "Vertices: " & vbLf) ed.WriteMessage(vbLf & sb.ToString) ed.WriteMessage(vbLf) sb = Nothing End If 'cast object as Spline If TypeOf ent Is Spline Then Dim spline As Spline = ent ' do your stuffs here End If 'cast object as Ellipse If TypeOf ent Is Ellipse Then Dim elp As Ellipse = ent ' do your stuffs here End If ''ETC... Next Catch ex As System.Exception ed.WriteMessage(ex.Message + vbLf + ex.StackTrace) End Try tr.Commit() End Using End Sub
~'J'~
Hi,
I wrote something this way sometimes ago but I'm not fully satisfied.
The LOCKOSNAP command toogles between activatin or deactivating osnaps on locked layers. I didn't find no way to get it work with the INTersect osnap.
using System; using System.Collections.Generic; using System.Linq; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; namespace OsnapControl { public class LockOsnap { private LockOsnapOverrule _osnapOverrule; private static ObjectId[] _onLocked; [CommandMethod("LockOsnap")] public void LockOsnapCmd() { Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; if (_osnapOverrule == null) { ed.PromptingForPoint += OnPromptingForPoint; _osnapOverrule = new LockOsnapOverrule(); Overrule.AddOverrule(RXClass.GetClass(typeof(Entity)), _osnapOverrule, false); ed.WriteMessage("\nObject Snaps on locked layers deactivated."); } else { ed.PromptingForPoint -= OnPromptingForPoint; Overrule.RemoveOverrule(RXClass.GetClass(typeof(Entity)), _osnapOverrule); _osnapOverrule = null; ed.WriteMessage("\nObject Snaps on locked layers activated."); } } private void OnPromptingForPoint(object sender, PromptPointOptionsEventArgs e) { _onLocked = GetOnLocked(); _osnapOverrule.SetIdFilter(_onLocked); Overrule.Overruling = true; } private ObjectId[] GetOnLocked() { Database db = HostApplicationServices.WorkingDatabase; Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; using (Transaction tr = db.TransactionManager.StartTransaction()) { IEnumerable<string> layers = GetLocked(db); if (layers.Count() == 0) return null; return ((BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForRead)) .Cast<ObjectId>() .Where(id => layers.Contains(((Entity)tr.GetObject(id, OpenMode.ForRead)).Layer)) .ToArray(); } } private IEnumerable<string> GetLocked(Database db) { return ((LayerTable)db.LayerTableId.GetObject(OpenMode.ForRead)) .Cast<ObjectId>() .Select(id => (LayerTableRecord)id.GetObject(OpenMode.ForRead)) .Where(ltr => ltr.IsLocked) .Select(ltr => ltr.Name); } public class LockOsnapOverrule : OsnapOverrule { public override bool IsContentSnappable(Entity entity) { return !_onLocked.Contains(entity.ObjectId); } public override void GetObjectSnapPoints( Entity entity, ObjectSnapModes snapMode, IntPtr gsSelectionMark, Point3d pickPoint, Point3d lastPoint, Matrix3d viewTransform, Point3dCollection snapPoints, IntegerCollection geometryIds) { entity.UpgradeOpen(); base.GetObjectSnapPoints(entity, snapMode, gsSelectionMark, pickPoint, lastPoint, viewTransform, null, geometryIds); } } } }
Thanks for the reply Alfred,
I like customized object-snaps maybe a little bit working to get what I want.
Thanks again...
Thanks Hallex
I did not understand. I compile your code and yes it did it right you said I select locked layer object.
May be I did not clear, I want to "disable snap for objects in locked layers".
Sorry, I don't understand your task right, so ignore my post please
~'J'~
Thanks _gile,
It is nearly what I want. But I have very narrow knowledge about C#, maybe I converted to basic than working on it.
I don not know why I take a fatal error when extension snaps on.
Thank you very much again. I fallow your lead, I keep you inform about results.
@_gile wrote:
... I didn't find no way to get it work with the INTersect osnap.
I've just stumbled across this thread, and your post looks to be very useful, Gile - Thank you.
As I am just starting to researching this topic, and you may already be aware, Kean shows how to deal with INTersect osnap using GeometryOverrule here:
Cheers
"How we think determines what we do, and what we do determines what we get."
Thanks BlackBox_.
I saw Kean's thread sometimes ago. I rewrote the code to publish it on a French web site: CADxp.
Two toggle commands are defined. Both can be called transparently.
LOKO to (de)activate osnaps on locked layers.
XROS to (de)activate osnaps on xrefs.
Here's the code:
using System; using System.Collections.Generic; using System.Linq; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; using AcAp = Autodesk.AutoCAD.ApplicationServices.Application; [assembly: CommandClass(typeof(Gile.LockOsnap.CommandMethods))] namespace Gile.LockOsnap { public class CommandMethods { private OSOverrule lokoOSOverrule, xrosOSOverrule; private IntOverrule lokoIntOverrule, xrosIntOverrule; [CommandMethod("LOKO", CommandFlags.Modal | CommandFlags.Transparent)] public void LockOsnapCmd() { ToggleOsnaps(ref lokoOSOverrule, ref lokoIntOverrule, lokoPromptingForPoint, LockedUpdate, "calques verrouillés"); } [CommandMethod("XROS", CommandFlags.Modal | CommandFlags.Transparent)] public void XrefOsnapCmd() { ToggleOsnaps(ref xrosOSOverrule, ref xrosIntOverrule, xrosPromptingForPoint, XrefUpdate, "références externes"); } void lokoPromptingForPoint(object sender, PromptPointOptionsEventArgs e) { LockedUpdate(); } void xrosPromptingForPoint(object sender, PromptPointOptionsEventArgs e) { XrefUpdate(); } private void ToggleOsnaps( ref OSOverrule osOverrule, ref IntOverrule intOverrule, PromptPointOptionsEventHandler handler, Action update, string msg) { Editor ed = AcAp.DocumentManager.MdiActiveDocument.Editor; RXClass entityClass = RXClass.GetClass(typeof(Entity)); if (osOverrule == null) { ed.PromptingForPoint += handler; osOverrule = new OSOverrule(); Overrule.AddOverrule(entityClass, osOverrule, false); intOverrule = new IntOverrule(); Overrule.AddOverrule(entityClass, intOverrule, false); ed.WriteMessage(string.Format("\nAccrochages sur les {0} désactivés.", msg)); update(); Overrule.Overruling = true; } else { ed.PromptingForPoint -= xrosPromptingForPoint; Overrule.RemoveOverrule(entityClass, osOverrule); osOverrule = null; Overrule.RemoveOverrule(entityClass, intOverrule); intOverrule = null; ed.WriteMessage(string.Format("\nAccrochages sur les {0} activés.", msg)); } } private void LockedUpdate() { if (lokoOSOverrule != null) { Database db = HostApplicationServices.WorkingDatabase; using (Transaction tr = db.TransactionManager.StartOpenCloseTransaction()) { HashSet<string> layers = new HashSet<string>( ((LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead)) .Cast<ObjectId>() .Select(id => (LayerTableRecord)tr.GetObject(id, OpenMode.ForRead)) .Where(ltr => ltr.IsLocked) .Select(ltr => ltr.Name)); ObjectId[] onLocked = ((BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForRead)) .Cast<ObjectId>() .Where(id => layers.Contains(((Entity)tr.GetObject(id, OpenMode.ForRead)).Layer)) .ToArray(); lokoOSOverrule.SetIdFilter(onLocked); lokoIntOverrule.SetIdFilter(onLocked); tr.Commit(); } } } private void XrefUpdate() { if (xrosOSOverrule != null) { Database db = HostApplicationServices.WorkingDatabase; using (Transaction tr = db.TransactionManager.StartOpenCloseTransaction()) { ObjectId[] xrIds = ((BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead)) .Cast<ObjectId>() .Select(id => (BlockTableRecord)tr.GetObject(id, OpenMode.ForRead)) .Where(btr => btr.IsFromExternalReference) .SelectMany(btr => btr.GetBlockReferenceIds(true, false).Cast<ObjectId>()) .ToArray(); xrosOSOverrule.SetIdFilter(xrIds); xrosIntOverrule.SetIdFilter(xrIds); tr.Commit(); } } } class OSOverrule : OsnapOverrule { public override void GetObjectSnapPoints( Entity ent, ObjectSnapModes mode, IntPtr gsm, Point3d pick, Point3d last, Matrix3d view, Point3dCollection snap, IntegerCollection geomIds) { } public override void GetObjectSnapPoints( Entity ent, ObjectSnapModes mode, IntPtr gsm, Point3d pick, Point3d last, Matrix3d view, Point3dCollection snaps, IntegerCollection geomIds, Matrix3d insertion) { } public override bool IsContentSnappable(Entity entity) { return false; } } class IntOverrule : GeometryOverrule { public override void IntersectWith( Entity ent1, Entity ent2, Intersect intType, Plane proj, Point3dCollection points, IntPtr thisGsm, IntPtr otherGsm) { } public override void IntersectWith( Entity ent1, Entity ent2, Intersect intType, Point3dCollection points, IntPtr thisGsm, IntPtr otherGsm) { } } } }
@_gile wrote:Thanks BlackBox_.
I saw Kean's thread sometimes ago. I rewrote the code to publish it on a French web site: CADxp.
I suspected you would have, as I know you to be well informed, but had to take the chance at being of some small amount of help to one who has been so helpful to me in the past.
@_gile wrote:
Two toggle commands are defined. Both can be called transparently.
LOKO to (de)activate osnaps on locked layers.
XROS to (de)activate osnaps on xrefs.
While I have not yet tested for myself, your description, and a quick glance at the code leaves me with only one thought... Simply brilliant.
Separately, I often come across your posts when trying to accomplish a task, or learn how to go about something. Do you by chance have a website, etc. that I might be able to read tips & tutorials on the myriad facets of the AutoCAD .NET API?
Cheers
"How we think determines what we do, and what we do determines what we get."
Can't find what you're looking for? Ask the community or share your knowledge.