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

Can not snap locked layers

15 REPLIES 15
Reply
Message 1 of 16
truss_85
3899 Views, 15 Replies

Can not snap locked layers

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.

15 REPLIES 15
Message 2 of 16
Alfred.NESWADBA
in reply to: truss_85

Hi,

 

how did you disable object-snaps for geometry on locked layers?

Or do I misunderstand your question?

 

- alfred -

------------------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at ... blog.hollaus.at ... CDay 2024
------------------------------------------------------------------------------------
(not an Autodesk consultant)
Message 3 of 16
truss_85
in reply to: Alfred.NESWADBA

I want to disable object-snaps for geometry on locked layers

Message 4 of 16
Alfred.NESWADBA
in reply to: truss_85

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 -

------------------------------------------------------------------------------------
Alfred NESWADBA
Ingenieur Studio HOLLAUS ... www.hollaus.at ... blog.hollaus.at ... CDay 2024
------------------------------------------------------------------------------------
(not an Autodesk consultant)
Message 5 of 16
Hallex
in reply to: truss_85

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'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 6 of 16
_gile
in reply to: truss_85

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);
            }
        }
    }
}

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 7 of 16
truss_85
in reply to: Alfred.NESWADBA

Thanks for the reply Alfred,

I like customized object-snaps maybe a little bit working to get what I want.

Thanks again...

Message 8 of 16
truss_85
in reply to: Hallex

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". 

 

Message 9 of 16
Hallex
in reply to: truss_85

Sorry, I don't understand your task right, so ignore my post please

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Message 10 of 16
truss_85
in reply to: _gile

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.

Message 11 of 16
truss_85
in reply to: Hallex

No Problem

I think I did not express my self clearly.

Thanks again

Message 12 of 16
BlackBox_
in reply to: _gile


@_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:

 

http://through-the-interface.typepad.com/through_the_interface/2013/12/disabling-snapping-to-specifi...

 

 

 

Cheers



"How we think determines what we do, and what we do determines what we get."

Message 13 of 16
_gile
in reply to: BlackBox_

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) { }
        }
    }
}

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 14 of 16
BlackBox_
in reply to: _gile


@_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."

Message 15 of 16
_gile
in reply to: BlackBox_

I have a (very) little web site (gilecAD) but there're not so much tutos and all in French.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 16 of 16
BlackBox_
in reply to: _gile


@_gile wrote:

I have a (very) little web site (gilecAD) but there're not so much tutos and all in French.


You have more content on your site than I do; thanks for sharing. :thumbsup:



"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.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost