Author Topic: create Layers, is there a better way  (Read 23044 times)

0 Members and 1 Guest are viewing this topic.

sinc

  • Guest
Re: create Layers, is there a better way
« Reply #30 on: January 03, 2008, 08:30:42 PM »
I would really recommend you don't do that.  If you try to use an erased layer for something, you might get some strange results.

It is far better to use the PInvoke solution Tony T. posted here.

Alternatively, you could use the Com object.  This works fine, as well:

Code: [Select]
        public static ObjectId GetLayerObjectId(LayerTable table, string name)
        {
            AcadLayers layerTable = table.AcadObject as AcadLayers;
            AcadLayer layer = layerTable.Item(name);
            if (layer == null)
                return ObjectId.Null;
            else
                return DBObject.FromAcadObject(layer);
        }
« Last Edit: January 03, 2008, 08:35:56 PM by sinc »

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: create Layers, is there a better way
« Reply #31 on: January 04, 2008, 04:21:09 PM »
Not to ask a dumb question, but here goes.  I thought we were trying to NOT use com?  Isn't it slower blah blah blah and stuff?
I never learned it b/c I have heard horror stories and the managed api is better.
« Last Edit: January 04, 2008, 04:44:06 PM by CmdrDuh »
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

Glenn R

  • Guest
Re: create Layers, is there a better way
« Reply #32 on: January 04, 2008, 04:28:06 PM »
I thought we were trying to NOT use com?  Isn't it slower blah blah blah and stuff?

Correct :)

sinc

  • Guest
Re: create Layers, is there a better way
« Reply #33 on: January 04, 2008, 08:17:53 PM »
Not to ask a dumb question, but here goes.  I thought we were trying to NOT use com?  Isn't it slower blah blah blah and stuff?
I never learned it b/c I have heard horror stories and the managed api is better.

Yeah, but this is to get around a bug in the managed API.

The REAL solution is for AUTODESK TO FIX THE API!!!!  But it's been like this for more than three years now, and it's a known problem, and they still haven't fixed it...    :ugly:

sinc

  • Guest
Re: create Layers, is there a better way
« Reply #34 on: January 04, 2008, 08:21:32 PM »
Isn't it slower blah blah blah and stuff?

And this isn't right.  COM is actually faster.

The .NET API is not a real framework.  Maybe someday.  But right now, it is simply a managed wrapper around the COM code.  So it's actually SLOWER.  Underneath, it amounts to using COM indirectly.  It's just much easier to program in, and the performance hit isn't noticeable for most things.  Or for areas where the performance hit of the managed API is not acceptable, you can write something in C++ and call it from your managed code, getting "the best of both worlds".

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8659
  • AKA Daniel
Re: create Layers, is there a better way
« Reply #35 on: January 04, 2008, 08:54:05 PM »
Isn't it slower blah blah blah and stuff?
it is simply a managed wrapper around the COM code.  So it's actually SLOWER.  ...

This is not a correct statement. Managed code wraps native code directly,
without the use of COM, I am fairly certain that well written .NET is faster than COM.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8659
  • AKA Daniel
Re: create Layers, is there a better way
« Reply #36 on: January 05, 2008, 06:42:47 AM »
So what we can do is drop down into C++/CLI and write our own managed wrapper for AcDbSymbolTable::GetAt()

Code: [Select]
ObjectId Utilities::SymbolTableGetAt(String ^name,SymbolTable ^table, bool getErased)
  {
   
    if(name == nullptr)
      throw gcnew System::ArgumentNullException("SymbolTableGetAt");

    if(table == nullptr)
      throw gcnew System::ArgumentNullException("SymbolTableGetAt");
   
    AcDbObjectId recordId;
    ObjectId id;

    pin_ptr<const ACHAR> _name = PtrToStringChars(name);
    pin_ptr<AcDbSymbolTable>_table = (AcDbSymbolTable*)table->UnmanagedObject.ToPointer();

    //Call the ObjectARX AcDbSymbolTable::GetAt();
    if(_table->getAt(_name,recordId,getErased)== Acad::eOk)
      id = (ObjectId)gcnew ObjectId(recordId.asOldId());
    else
      id = (ObjectId)gcnew ObjectId();

    return id;
  }

Then add an Extension Method to the SymbolTable class via C#
Code: [Select]
   public static ObjectId GetAt(this SymbolTable m_this, string name, bool getErased)
    {
      return AcMgdWrprs.Utilities.SymbolTableGetAt(name, m_this, getErased);//edited
    }


Now we can use this new method in our C# function.

Code: [Select]
   [CommandMethod("doit")]
    static public void OpenThePodBayDoorsHal()
    {
      Editor ed = AcAp.Application.DocumentManager.MdiActiveDocument.Editor;
      Database db = AcDb.HostApplicationServices.WorkingDatabase;

      string MyNewLayerName = "OhDannyBoy";

      LayerTableRecord newLTR = new LayerTableRecord();
      newLTR.Name = MyNewLayerName;

      using (Transaction tr = db.TransactionManager.StartTransaction())
      {
        try
        {
          DBObject dbObject = tr.GetObject(db.LayerTableId, OpenMode.ForRead, false);

          if (dbObject != null && dbObject is LayerTable)
          {
            LayerTable lt = (LayerTable)dbObject;

            if (lt.GetAt(MyNewLayerName, false).IsNull) //<---------
            {
              lt.UpgradeOpen();
              lt.Add(newLTR);

              tr.AddNewlyCreatedDBObject(newLTR, true);
              tr.Commit();
            }
            else
            {
              ed.WriteMessage("Sorry Dave, I can't do that");
            }
          }
        }
        catch (System.Exception ex)
        {
          ed.WriteMessage(ex.Message);
        }
      }
    }

w00ty w00ty w00ty w00ty  :lol:

« Last Edit: January 05, 2008, 06:49:33 AM by Daniel »

Glenn R

  • Guest
Re: create Layers, is there a better way
« Reply #37 on: January 05, 2008, 06:46:47 AM »
Heh...nice one Dan.

sinc

  • Guest
Re: create Layers, is there a better way
« Reply #38 on: January 05, 2008, 10:42:36 AM »
Isn't it slower blah blah blah and stuff?
it is simply a managed wrapper around the COM code.  So it's actually SLOWER.  ...

This is not a correct statement. Managed code wraps native code directly,
without the use of COM, I am fairly certain that well written .NET is faster than COM.


Hmmm.....  Maybe I'm just getting thrown again by the fact that there is no .NET API for Civil-3D, so everything I do is a horrible mish-mash of .NET and COM.... 

sinc

  • Guest
Re: create Layers, is there a better way
« Reply #39 on: January 05, 2008, 10:44:40 AM »
So what we can do is drop down into C++/CLI and write our own managed wrapper for AcDbSymbolTable::GetAt()

You've seen that PInvoke solution from Tony T, right?

It's basically the same thing, but the whole thing is done in C#.NET, with no need to compile a C++ class.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8659
  • AKA Daniel
Re: create Layers, is there a better way
« Reply #40 on: January 05, 2008, 12:30:31 PM »
Hi Sinc,
Yes, I have seen Tony’s code. I just prefer to write wrappers in C++/CLI as it helps me learn what’s going on behind the scenes.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: create Layers, is there a better way
« Reply #41 on: January 15, 2008, 03:53:40 PM »
Next part of the question on creating layers.  What would be the best way to keep up with the list of layers and their respective properties?  As I see it, there are 2 ways I can do this.
  • Hard code all the layer information into the .Net DLL
  • Keep an external file full of the information.
If I go with option 2, what is the best type of file to maintain?  I'm thinking XML file or TXT file.  XML has its advantages in that when editing, all the properties are delineated by the XML tags.  If I use a TXT file, should I use comma delimited or tab delimited file?  Ideas? Other pros or cons I haven't thought of?

Edit:
Hard coding has obvious disadvantages in that I have to redistribute the DLL everytime there is an update.  Are there other disadvantages you can think of?
« Last Edit: January 15, 2008, 03:57:20 PM by CmdrDuh »
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: create Layers, is there a better way
« Reply #42 on: January 15, 2008, 03:55:15 PM »
And to add to my previous post, I have some routines that freeze and thaw layers.  I currently use a TXT file to tell computer what layers to thaw.  The routine sets 0 current, freezes everything else, and thaws the layers on the TXT file list.  Ideas?
Everyone has a photographic memory, Some just don't have film.
They say money can't buy happiness, but it can buy Bacon and that's a close second.
Sometimes the question is more important than the answer. (Thanks Kerry for reminding me)

Glenn R

  • Guest
Re: create Layers, is there a better way
« Reply #43 on: January 15, 2008, 03:56:25 PM »
XML - no question.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: create Layers, is there a better way
« Reply #44 on: January 15, 2008, 04:07:03 PM »

David, I'd use XML as well.
The 'Linq' technology provided by .NET3.5 is worth spending a couple of days playing with.

kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.