.NET

Reply
Mentor
truss_85
Posts: 173
Registered: ‎02-13-2011
Message 1 of 16 (765 Views)

Can not snap locked layers

765 Views, 15 Replies
05-12-2012 03:23 AM

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.

*Expert Elite*
Alfred.NESWADBA
Posts: 9,099
Registered: ‎06-29-2007
Message 2 of 16 (761 Views)

Re: Can not snap locked layers

05-12-2012 04:08 AM 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
-------------------------------------------------------------------------
Mentor
truss_85
Posts: 173
Registered: ‎02-13-2011
Message 3 of 16 (760 Views)

Re: Can not snap locked layers

05-12-2012 04:51 AM in reply to: Alfred.NESWADBA

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

*Expert Elite*
Alfred.NESWADBA
Posts: 9,099
Registered: ‎06-29-2007
Message 4 of 16 (755 Views)

Re: Can not snap locked layers

05-12-2012 05:57 AM in reply to: truss_85

Hi,

 

sorry, I understood it in the other way, you have no object snaps and want to activate them :smileywink:

 

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
-------------------------------------------------------------------------
*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 5 of 16 (737 Views)

Re: Can not snap locked layers

05-13-2012 12:27 AM 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
*Expert Elite*
_gile
Posts: 2,091
Registered: ‎04-29-2006
Message 6 of 16 (729 Views)

Re : Can not snap locked layers

05-13-2012 06:26 AM 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
Mentor
truss_85
Posts: 173
Registered: ‎02-13-2011
Message 7 of 16 (710 Views)

Re: Can not snap locked layers

05-14-2012 01:54 AM 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...

Mentor
truss_85
Posts: 173
Registered: ‎02-13-2011
Message 8 of 16 (709 Views)

Re: Can not snap locked layers

05-14-2012 01:58 AM 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". 

 

*Expert Elite*
Hallex
Posts: 1,569
Registered: ‎10-08-2008
Message 9 of 16 (707 Views)

Re: Can not snap locked layers

05-14-2012 02:01 AM in reply to: truss_85

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

 

~'J'~

_____________________________________
C6309D9E0751D165D0934D0621DFF27919
Mentor
truss_85
Posts: 173
Registered: ‎02-13-2011
Message 10 of 16 (705 Views)

Re : Can not snap locked layers

05-14-2012 02:04 AM 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.

Need installation help?

Start with some of our most frequented solutions or visit the Installation and Licensing Forum to get help installing your software.