TheSwamp

Code Red => .NET => Topic started by: cnicho on March 01, 2013, 07:28:55 AM

Title: Layer IsUsed
Post by: cnicho on March 01, 2013, 07:28:55 AM
Hello,
I want to set the visibility according to whether or not a layer has objects.
I am finding IsUsed to be unreliable. For example, if SHOWLAYERUSAGE=0, IsUsed seems to be of no use and if SHOWLAYERUSAGE=1, new objects don't seem to immediately cause IsUsed to be updated.
Is there an alternative to IsUsed to determine if a layer has objects?
Thanks
Title: Re: Layer IsUsed
Post by: BlackBox on March 01, 2013, 07:40:15 AM
Have you considered using Editor.SelectAll()?

Code - C#: [Select]
  1.         public static bool _LayerIsUsed(Editor ed, string layerName)
  2.         {
  3.             bool layerIsUsed = false;
  4.  
  5.             TypedValue[] tvs = new TypedValue[]
  6.             {
  7.                 new TypedValue((int)DxfCode.LayerName, layerName)
  8.             };
  9.  
  10.             SelectionFilter filter = new SelectionFilter(tvs);
  11.  
  12.             PromptSelectionResult psr = ed.SelectAll(filter);
  13.  
  14.             if (psr.Status == PromptStatus.OK)
  15.                 layerIsUsed = true;
  16.  
  17.             return layerIsUsed;
  18.         }
  19.  
Title: Re: Layer IsUsed
Post by: cnicho on March 01, 2013, 08:33:00 AM
That works nicely. Thanks.
Title: Re: Layer IsUsed
Post by: BlackBox on March 01, 2013, 10:19:45 AM
That works nicely. Thanks.

You're welcome; I'm happy to help.

Separately, I should have thought of this first, but I still think in LISP 'sub-function' terms as I'm still a student of .NET, but you might find this Extension Method preferable:

Code - C#: [Select]
  1. namespace Autodesk.AutoCAD.DatabaseServices.MyExtensions
  2. {
  3.     public static class LayerTableRecordExtensionMethods
  4.     {
  5.         public static bool HasObjects(this LayerTableRecord ltr, Editor ed)
  6.         {
  7.             bool hasObjects= false;
  8.  
  9.             TypedValue[] tvs = new TypedValue[]
  10.             {
  11.                 new TypedValue((int)DxfCode.LayerName, ltr.Name)
  12.             };
  13.  
  14.             SelectionFilter filter = new SelectionFilter(tvs);
  15.  
  16.             PromptSelectionResult psr = ed.SelectAll(filter);
  17.  
  18.             if (psr.Status == PromptStatus.OK)
  19.                 hasObjects= true;
  20.  
  21.             return hasObjects;
  22.         }
  23.     }
  24. }
  25.  

... So now, you simply add a using directive:

Code - C#: [Select]
  1. using Autodesk.AutoCAD.DatabaseServices.MyExtensions;
  2.  

... And your LayerTableRecord type can now call the HasObjects() Extension Method.
Title: Re: Layer IsUsed
Post by: Gasty on March 01, 2013, 10:44:45 AM
Hi,


I think this test is not the correct one, just check with a block with entities in "LayerA" , but inserted in "LayerB", this test will wrongly show that "LayerA" "Has no Objects".

Gaston Nunez
Title: Re: Layer IsUsed
Post by: BlackBox on March 01, 2013, 10:47:56 AM
Thanks for pointing that out (haven't tested)... I was only trying to come up with an alternative to the Properties mentioned in the OP, and Editor.SelectAll() is the best I could come up with.

** Edit - Although, technically, that is 'normal' (not to be mistaken with correct) behavior... Same holds true in LISP using SSGET.
Title: Re: Layer IsUsed
Post by: cnicho on March 01, 2013, 11:30:08 AM
Yes thanks for that spanner Gasty :)
The layer with the block reference in layerB is considered in use but layerA is not.
Title: Re: Layer IsUsed
Post by: BlackBox on March 01, 2013, 11:44:26 AM
My next thought was to change the Extension Method to filter if it were available for purge from the Database... I recently did something similar for Registry Applications, where calling the Purge() Method removed those that could not be purged... So in my hunting, I stumbled upon this blog post (http://adndevblog.typepad.com/autocad/2012/05/generate-layer-usage-data-before-purgedelete.html).

In that post, they also call IsUsed, which leads me back to the OP, as there must be something more to do for your 'new objects'... Perhaps another Transaction wrapper, etc.? Cannot be certain without more information, and perhaps posting your code.
Title: Re: Layer IsUsed
Post by: cnicho on March 01, 2013, 12:22:54 PM
Thanks Renderman, that blog post had the answer.

If I call GenerateUsageData() before LayerTableRecord IsUsed I can reliably set the visibility, even if SHOWLAYERUSAGE=0 and blocks exist with entities on different layers to the insertion layer.

Title: Re: Layer IsUsed
Post by: BlackBox on March 01, 2013, 07:20:32 PM
Thanks Renderman, that blog post had the answer.

You're welcome; I learned something too.  ;-)
Title: Re: Layer IsUsed
Post by: Chumplybum on March 01, 2013, 09:45:36 PM
You could also use database.purge(ids) and the result would be layers that can be purged... hence, layers that have no objects
Title: Re: Layer IsUsed
Post by: BlackBox on March 01, 2013, 10:18:54 PM
I suggested that in post #7, no?
Title: Re: Layer IsUsed
Post by: Chumplybum on March 01, 2013, 10:20:43 PM
I suggested that in post #7, no?

should've read the whole thread before posting... sorry RenderMan :oops:
Title: Re: Layer IsUsed
Post by: BlackBox on March 02, 2013, 01:41:16 AM
No worries; just wanted to make sure I didn't miscommunicate the thought somehow. I'm still very much a student of .NET development, despite my attempts to bend the universe to my will.