TheSwamp

Code Red => .NET => Topic started by: RoSiNiNo on September 12, 2017, 07:00:12 am

Title: Freezing Layer in Layouts
Post by: RoSiNiNo on September 12, 2017, 07:00:12 am
Hi,
I'm trying to freeze the layer of a selected item in every other viewport of every layouts.
This code seems to work in the active layout but not in all other layouts.
Any ideas?
How do I get only the viewports in the layout and not the layout itself?
Code: [Select]
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Colors;


[assembly: CommandClass(typeof(RSNNGrundbeanspruchung.Commands))]
namespace RSNNGrundbeanspruchung
{
    public class Commands
    {
        [CommandMethod("AFLayerfrierenTest")]
        public static void AFFrierenTest()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = HostApplicationServices.WorkingDatabase;
            var ed = doc.Editor;

            PromptEntityOptions peo = new PromptEntityOptions("\nObjekt zeigen: ");
            peo.SetRejectMessage("\nKein gültiges Objekt gewählt. Objekt zeigen: ");
            peo.AddAllowedClass(typeof(Entity), false);
            do
            {
                PromptEntityResult per = ed.GetEntity(peo);

                if (per.Status != PromptStatus.OK)
                    return;

                ObjectId objId = per.ObjectId;

                using (var tr = db.TransactionManager.StartTransaction())
                {
                    Entity ent = (Entity)tr.GetObject(objId, OpenMode.ForRead);
                    LayerTable Layers = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);
                    LayerTableRecord Layer = (LayerTableRecord)tr.GetObject(ent.LayerId, OpenMode.ForWrite);

                    peo.Message = string.Format("\nLayer: \"{0}\" wird in anderen Fenstern ausgeschaltet.\nObjekt zeigen: ", Layer.Name);

                    // Freeze "Test" layer in all viewports
                    ObjectId[] ids = new ObjectId[1] { ent.LayerId };
                    DBDictionary layoutDict = (DBDictionary)tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead);
                    foreach (DBDictionaryEntry entry in layoutDict)
                    {
                        if (entry.Key != "Model")
                        {
                            Layout lay = (Layout)tr.GetObject(entry.Value, OpenMode.ForRead);
                            foreach (ObjectId vpId in lay.GetViewports())
                            {
                                Viewport vp = (Viewport)tr.GetObject(vpId, OpenMode.ForWrite);

                                if (ed.CurrentViewportObjectId != vpId)
                                    vp.FreezeLayersInViewport(ids.GetEnumerator());
                               
                            }
                        }
                    }
                   tr.Commit();
                }
            } while (true);
        }
    }
}
Title: Re: Freezing Layer in Layouts
Post by: RoSiNiNo on September 12, 2017, 07:22:43 am
OK, I've found the solution to both questions.
You have to use Database.GetViewports(false).
Code: [Select]
        [CommandMethod("AFLayerfrierenTest2")]
        public static void AFFrierenTest2()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = HostApplicationServices.WorkingDatabase;
            var ed = doc.Editor;

            PromptEntityOptions peo = new PromptEntityOptions("\nObjekt zeigen: ");
            peo.SetRejectMessage("\nKein gültiges Objekt gewählt. Objekt zeigen: ");
            peo.AddAllowedClass(typeof(Entity), false);
            do
            {
                PromptEntityResult per = ed.GetEntity(peo);

                if (per.Status != PromptStatus.OK)
                    return;

                ObjectId objId = per.ObjectId;

                using (var tr = db.TransactionManager.StartTransaction())
                {
                    Entity ent = (Entity)tr.GetObject(objId, OpenMode.ForRead);
                    LayerTable Layers = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);
                    LayerTableRecord Layer = (LayerTableRecord)tr.GetObject(ent.LayerId, OpenMode.ForWrite);

                    peo.Message = string.Format("\nLayer: \"{0}\" wird in anderen Fenstern ausgeschaltet.\nObjekt zeigen: ", Layer.Name);

                    // Freeze "Test" layer in all viewports
                    ObjectId[] ids = new ObjectId[1] { ent.LayerId };
                    ObjectIdCollection layerIds = new ObjectIdCollection();
                    layerIds.Add(ent.LayerId);

                    foreach (ObjectId vpId in db.GetViewports(false))
                    {
                        Viewport vp = (Viewport)tr.GetObject(vpId, OpenMode.ForWrite);

                        if (ed.CurrentViewportObjectId != vpId)
                            vp.FreezeLayersInViewport(layerIds.GetEnumerator());

                    }

                    tr.Commit();
                }
            } while (true);

        }
Title: Re: Freezing Layer in Layouts
Post by: RoSiNiNo on September 12, 2017, 07:33:32 am
OK, this one doesn't work, too.
I just tried one layer in the first layout and switched to the next and it seemed to work, but then I tried it again in another viewport and it didn't work.
Title: Re: Freezing Layer in Layouts
Post by: RoSiNiNo on September 13, 2017, 01:13:37 am
After a little bit of testing I can see that only the first time I use this command it works fine. Then it does not work anymore.
Also if I change the layout before the first use, it does not work.
Title: Re: Freezing Layer in Layouts
Post by: gile on September 13, 2017, 06:34:47 am
Hi,

This seems to work for me:

Code - C#: [Select]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.DatabaseServices;
  3. using Autodesk.AutoCAD.EditorInput;
  4. using Autodesk.AutoCAD.Runtime;
  5.  
  6. [assembly: CommandClass(typeof(VpFreezeBySelection.Commands))]
  7.  
  8. namespace VpFreezeBySelection
  9. {
  10.    public class Commands
  11.    {
  12.        [CommandMethod("TEST", CommandFlags.NoTileMode | CommandFlags.NoPaperSpace)]
  13.        public void Test()
  14.        {
  15.            var doc = Application.DocumentManager.MdiActiveDocument;
  16.            var db = doc.Database;
  17.            var ed = doc.Editor;
  18.  
  19.            var per = ed.GetEntity("\nSelect an entity: ");
  20.            if (per.Status != PromptStatus.OK)
  21.                return;
  22.  
  23.            using (var tr = db.TransactionManager.StartTransaction())
  24.            {
  25.                var lt = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);
  26.                var ent = (Entity)tr.GetObject(per.ObjectId, OpenMode.ForRead);
  27.                var ids = new[] { lt[ent.Layer] };
  28.                var dic = (DBDictionary)tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead);
  29.                foreach (DBDictionaryEntry entry in dic)
  30.                {
  31.                    if (entry.Key == "Model")
  32.                        continue;
  33.                    var layout = (Layout)tr.GetObject(entry.Value, OpenMode.ForRead);
  34.                    foreach (ObjectId id in layout.GetViewports())
  35.                    {
  36.                        if (id != ed.CurrentViewportObjectId)
  37.                        {
  38.                            var vp = (Viewport)tr.GetObject(id, OpenMode.ForWrite);
  39.                            vp.FreezeLayersInViewport(ids.GetEnumerator());
  40.                        }
  41.                    }
  42.                }
  43.                tr.Commit();
  44.            }
  45.        }
  46.    }
  47. }
  48.