Author Topic: acedRegenLayers  (Read 3436 times)

0 Members and 1 Guest are viewing this topic.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8722
  • AKA Daniel
acedRegenLayers
« on: December 29, 2007, 10:09:40 PM »
For anyone following this thread here , and thanks to MJG we have a new function to play with :lol:

Code: [Select]
    //2007+
    [System.Security.SuppressUnmanagedCodeSecurity]
    [DllImport("acad.exe", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl,
    EntryPoint = "?acedRegenLayers@@YGXABV?$AcArray@VAcDbObjectId@@V?$AcArrayMemCopyReallocator@VAcDbObjectId@@@@@@H@Z")]
    private static extern void acedRegenLayers(IntPtr pointer, int num);

    //
    public static void RegenLayers(ObjectIdCollection objectids,int num)
    {
      acedRegenLayers(objectids.UnmanagedObject, num);
    }

    [CommandMethod("doit")]
    static public void toit()
    {
      Editor ed = acadApp.DocumentManager.MdiActiveDocument.Editor;
      try
      {
        ObjectIdCollection objectIds = new ObjectIdCollection();
        Database db = acadApp.DocumentManager.MdiActiveDocument.Database;
        using (Transaction tr = db.TransactionManager.StartTransaction())
        {
          LayerTable table = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead);
          foreach (ObjectId id in table)
          {
            objectIds.Add(id);
          }
        }
        RegenLayers(objectIds, 0);
      }
      catch (System.Exception ex)
      {
        ed.WriteMessage(ex.Message);
      }
    }

SomeCallMeDave

  • Guest
Re: acedRegenLayers
« Reply #1 on: December 30, 2007, 10:53:51 AM »
Daniel,
Very cool.  Thanks for sharing. 

The new function works with some of my routines but I have one that I can't get it work with.

Code: [Select]
        [CommandMethod("layoutfreeze")]
        static public void FreezeLayerInAllOtherViewPorts()
        {
            Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            ObjectIdCollection layList = new ObjectIdCollection();
            ObjectIdCollection vpList = new ObjectIdCollection();

           
            PromptEntityOptions opts = new PromptEntityOptions("\nSelect Object whose layer will be frozen in all Other Viewports: ");
            opts.AllowNone = true;
            opts.AllowObjectOnLockedLayer = true;

            //Select the object on-screen
            PromptEntityResult res = ed.GetEntity(opts);
            if (res.Status == PromptStatus.OK)
            {
                ObjectId ObjID = res.ObjectId;
                ObjectId currVPortID = ed.CurrentViewportObjectId;

                try
                {
                    using (Transaction trans = db.TransactionManager.StartTransaction())
                    {
                        Entity ent = (Entity)trans.GetObject(ObjID, OpenMode.ForRead, false);
                        Viewport vpEnt = (Viewport)trans.GetObject(currVPortID, OpenMode.ForWrite);
                        ViewportTable vpTbl = (ViewportTable)trans.GetObject(db.ViewportTableId, OpenMode.ForRead);
                        ObjectId layerId = ent.LayerId;
                        layList.Add(layerId);

                        ObjectId layoutDictID = db.LayoutDictionaryId;
                        DBDictionary layoutDict = (DBDictionary)trans.GetObject(layoutDictID, OpenMode.ForRead);

                        foreach(DBDictionaryEntry LayoutDictEntry  in layoutDict)
                        {
                            Layout testLayout = (Layout)trans.GetObject(LayoutDictEntry.Value, OpenMode.ForWrite);
                            ObjectIdCollection LayoutVPs = testLayout.GetViewports();

                            foreach (ObjectId testVpEntID in LayoutVPs)
                                {
                                    Viewport testVpEnt = (Viewport)trans.GetObject(testVpEntID, OpenMode.ForWrite);
                                    testVpEnt.FreezeLayersInViewport(layList.GetEnumerator());
                                //test it here
                                  //  RegenLayers(layList, 0);
                                }
                        }
                        //thaw the layer in the current viewport
                        vpEnt.ThawLayersInViewport(layList.GetEnumerator());
                        trans.Commit();
                    }//using

                    //Test the new function here
                    RegenLayers(layList, 0);
                }//end try
                catch (System.Exception ex)
                {
                    ed.WriteMessage("\nError Freezing Layers: " + ex.Message);
                }
            }// if
        }//FreezeLayerInAllOtherViewPorts


This little function freezes the layers correctly, but the I still must close and re-open the drawing to make the changes apparent.
(The  code currently freezes the layer in the layout itsself (paperspace), which is not exactly the intent.  I will tackle that next)

I have tried the RegenLayers in several places both inside and outside the transaction but still no glory.

Any ideas?

Thanks again for sharing.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8722
  • AKA Daniel
Re: acedRegenLayers
« Reply #2 on: December 30, 2007, 01:36:07 PM »
please give this a shot

Code: [Select]
    [CommandMethod("layoutfreeze")]
    static public void FreezeLayerInAllOtherViewPorts()
    {
      //added by Dan
      int oldsetting = Convert.ToInt32(AcadApp.GetSystemVariable("LAYOUTREGENCTL"));
      AcadApp.SetSystemVariable("LAYOUTREGENCTL", (object)0);

      Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
      Database db = doc.Database;
      Editor ed = doc.Editor;

      ObjectIdCollection layList = new ObjectIdCollection();
      ObjectIdCollection vpList = new ObjectIdCollection();

      PromptEntityOptions opts = new PromptEntityOptions("\nSelect Object whose layer will be frozen in all Other Viewports: ");
      opts.AllowNone = true;
      opts.AllowObjectOnLockedLayer = true;

      //Select the object on-screen
      PromptEntityResult res = ed.GetEntity(opts);
      if (res.Status == PromptStatus.OK)
      {
        ObjectId ObjID = res.ObjectId;
        ObjectId currVPortID = ed.CurrentViewportObjectId;

        try
        {
          using (Transaction trans = db.TransactionManager.StartTransaction())
          {
            Entity ent = (Entity)trans.GetObject(ObjID, OpenMode.ForRead, false);
            Viewport vpEnt = (Viewport)trans.GetObject(currVPortID, OpenMode.ForWrite);
            ViewportTable vpTbl = (ViewportTable)trans.GetObject(db.ViewportTableId, OpenMode.ForRead);
            ObjectId layerId = ent.LayerId;
            layList.Add(layerId);

            ObjectId layoutDictID = db.LayoutDictionaryId;
            DBDictionary layoutDict = (DBDictionary)trans.GetObject(layoutDictID, OpenMode.ForRead);

            foreach (DBDictionaryEntry LayoutDictEntry in layoutDict)
            {
              Layout testLayout = (Layout)trans.GetObject(LayoutDictEntry.Value, OpenMode.ForWrite);
              ObjectIdCollection LayoutVPs = testLayout.GetViewports();

              foreach (ObjectId testVpEntID in LayoutVPs)
              {
                Viewport testVpEnt = (Viewport)trans.GetObject(testVpEntID, OpenMode.ForWrite);
                testVpEnt.FreezeLayersInViewport(layList.GetEnumerator());
                testVpEnt.UpdateDisplay();//added by Dan
              }
            }
            //thaw the layer in the current viewport
            vpEnt.ThawLayersInViewport(layList.GetEnumerator());
            trans.Commit();
          }//using
        }//end try
        catch (System.Exception ex)
        {
          ed.WriteMessage("\nError Freezing Layers: " + ex.Message);
        }
        finally
        {
          AcadApp.SetSystemVariable("LAYOUTREGENCTL", (object)oldsetting);
        }
           
      }// if
    }//FreezeLayerInAllOtherViewPorts
« Last Edit: December 30, 2007, 09:33:53 PM by Daniel »

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8722
  • AKA Daniel
Re: acedRegenLayers
« Reply #3 on: December 30, 2007, 10:51:15 PM »
Sorry SCMD, it seems that this new function does not update cached viewports as I first thought  :oops:

SomeCallMeDave

  • Guest
Re: acedRegenLayers
« Reply #4 on: December 30, 2007, 11:11:45 PM »
Dan,

No need to apologize to me, mate :)   I appreciate all your efforts and your willingness to share your findings.

I had followed along in the other thread and was able to get the desired results using the LAYOUTREGENCTL sysvar but was hopeful that the new RegenLayers command would update the viewports.


So what does it do?  Have you found any impact of changing the second argument?

Thanks again,
Dave