Author Topic: Rewriting program - opinions?  (Read 13734 times)

0 Members and 1 Guest are viewing this topic.

quamper

  • Guest
Rewriting program - opinions?
« on: November 14, 2007, 01:49:27 PM »
Currently I've got a VB COM app that I'm toying around with rewriting from the ground up using the .net api stuff as I've hit some limitations over time. I've already rewritten a few smaller ones with good success.

I've got a chance to change a few fundamental things and I'm wondering whether I should or not before I get too far into it.

One of the big components of my program is that it creates 3-4 different overall styles of Blocks based on a whole lot of different criteria, and inserts them into the drawing. Each of these blocks has a ton of attributes (most of the hidden/non-visible attributes). A typical drawing may have 5-30 of these "intelligent blocks". Alot of the reason for this program was previous to dynamic blocks, but it still does alot more than dynamic blocks do so thats not really an issue.

I'm mostly wondering at this point:

1. Currently using blocks if I create one and insert it into the drawing, then I delete the block, it's still in the database unless I do a purge. Ideally I don't want multiple references to the same block in the drawing, nor do I want a block not referenced at all. Is there another way to do that or should I have an event that watches for deletion of these blocks and purge them programatically, and also prevents multiple instances? The geometry in the blocks isn't terribly complicated. Are blocks the most efficient way to handle this?

2. Attributes vs. Xrecords? Is there any advantage to using xrecords? Are there limitations of using xrecords that I should be aware of, as I've not used them much at all, except in learning the basics of how to use them.  Currently the attributes never get edited via Autocad dialogs and strictly by the application.

Thanks :)


Draftek

  • Guest
Re: Rewriting program - opinions?
« Reply #1 on: November 14, 2007, 02:27:18 PM »
One question I would ask is - What are the limitations you've hit and will re-coding the thing in .Net actually eliminate those?

As far as using blocks or not and the worry of references vs inserts - it all depends - if your worried about the user manipulating the geometry then your either stuck with blocks or a custom object, I guess. If not then you could use primitives and attach xdata or xrecords / dictionaries. I've used these before along with handles to create kind of a poor mans custom object. I would avoid monitoring events at all cost...

LE

  • Guest
Re: Rewriting program - opinions?
« Reply #2 on: November 14, 2007, 02:54:20 PM »
I'm too would like to know what are those limitations (perhaps you refer about future compability or accessibility to the API's that might required in example C#?)


About those inserts - can they be anonymous - so in case they are deleted, they will be purge by acad once the drawing is closed ?

I am working in my first COM project but it is in C++ and ObjectARX - and the reason they want to have this, it is because it will be used in a VB or VBA application's [and for now it is easier to them to go this way, instead of porting or re-coding all what they have in VB to C++/ARX/or C#]. I use dictionaries to save some of the data too.

quamper

  • Guest
Re: Rewriting program - opinions?
« Reply #3 on: November 14, 2007, 03:14:35 PM »
"What are the limitations you've hit and will re-coding the thing in .Net actually eliminate those?"

The short answer is, yes. Some of it is because of performance, some of it is because Autocad seems to be heading away from supporting VB/COM stuff and more support for the .net api. I have run into a few specific instances where I just couldn't accomplish what I wanted to do. It's been a little while I'm sure I have some notes somewhere of what it was. And I've got the time to do it so I'm not really worried about that aspect.

"I've used these before along with handles to create kind of a poor mans custom object."

I guess thats in essence what I'm currently doing...and I guess creating my own custom object isn't really any option unless I dive into ObjectARX which isn't really an option. So since creating blocks and tying info to them is fairly easy and accomplishes what I'm needing. Is there any benefit then to tons of attributes vs xdata/dictionaries for all the extra data I'm associating with the block
 

 

quamper

  • Guest
Re: Rewriting program - opinions?
« Reply #4 on: November 14, 2007, 03:18:24 PM »
"About those inserts - can they be anonymous - so in case they are deleted, they will be purge by acad once the drawing is closed ?"

Right now they are all named, but theres no reason they couldn't be anonymous I suppose. So thats an acceptable solution.

Draftek

  • Guest
Re: Rewriting program - opinions?
« Reply #5 on: November 14, 2007, 04:32:28 PM »
Good point about the future of vb and vba. That is what drove me to C# a few years ago.

I guess I would say the main advantage of using xdata or xrecords in lieu of attributes would be security - you can only access them via the programming interface. savvy people can figure out how to get to attributes. Again, if you don't want the users stretching your lines out of whack a block might be best - you could still use xdata instead of attributes if you like.

I was going to suggest a custom object if you don't have to deploy outside of your realm and you have some c++ experience - that gives you the most control.
You should consider breaking your project up into a n-tier app so if you decide to wrap some autocad object in c# later you will be able to. If the graphics are simple, creating a custom entity is not that hard.

quamper

  • Guest
Re: Rewriting program - opinions?
« Reply #6 on: November 14, 2007, 04:45:05 PM »
"I was going to suggest a custom object if you don't have to deploy outside of your realm and you have some c++ experience - that gives you the most control."

From everything I've read about custom objects, I think that definitly would be a really nice solution/fit for what I'm doing. I don't need to deploy outside so thats not an issue, however I don't have c++ experience. Most everything I've been writing for Autocad has been in VB.NET. I think I could make the switch to C# relatively easily, but I've not done any C++ programming so I don't how different of a beast I would be tackling.

I know there was mention of the Autocad developers possibly allowing custom objects to be created with the .net api in the 2009 or 2010 release, but I haven't heard/read any updates about that coming to pass.

Nathan Taylor

  • Guest
Re: Rewriting program - opinions?
« Reply #7 on: November 14, 2007, 05:00:42 PM »
I've found 3 benefits of rewriting my VBA programs with .NET.

1. Revisting the logic of how the program works.

2. Extra capabilities of the AutoCAD .NET API, the .NET framework and .NET forms.

3. Better speed of the AutoCAD .NET API.


Regards - Nathan

LE

  • Guest
Re: Rewriting program - opinions?
« Reply #8 on: November 14, 2007, 05:20:51 PM »
"I was going to suggest a custom object if you don't have to deploy outside of your realm and you have some c++ experience - that gives you the most control."

From everything I've read about custom objects, I think that definitly would be a really nice solution/fit for what I'm doing. I don't need to deploy outside so thats not an issue, however I don't have c++ experience. Most everything I've been writing for Autocad has been in VB.NET. I think I could make the switch to C# relatively easily, but I've not done any C++ programming so I don't how different of a beast I would be tackling.

I know there was mention of the Autocad developers possibly allowing custom objects to be created with the .net api in the 2009 or 2010 release, but I haven't heard/read any updates about that coming to pass.


Custom Objects are not easy starting from scratch - I have done quite a few - and you required a strong knowledge of ARX among heavy background of C++. There are some step by step custom object sample(s) posted here in the ARX or was C++ forums by MickD and me.

C# can be your best choice.

quamper

  • Guest
Re: Rewriting program - opinions?
« Reply #9 on: November 14, 2007, 05:35:11 PM »
1. Revisting the logic of how the program works.

Thats exactly why I'm asking the questions :D

Along with the other reasons.

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: Rewriting program - opinions?
« Reply #10 on: November 14, 2007, 08:43:41 PM »
Custom objects at first glance seem like a great idea but they can get real complicated real quick and if you implement one - even only for internal use - you can find compatibility issues a real problem even between minor versions.
I would also suggest xdata/records and some custom tools to access/edit the data, if you need special methods called with normal acad commands you could use reactors or just create your own special methods, this is much easier to maintain and extend than custom objects IMO.
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

Glenn R

  • Guest
Re: Rewriting program - opinions?
« Reply #11 on: November 15, 2007, 04:26:01 AM »
As Luis has already stated and Mick reiterated, custom objects require a LOT of work to make a good one and a serious grounding in C++ and ARX.

From what you've mentioned, if it was me, I would do as Luis has suggested...anon blocks with an extension dictionary containing your xrecord - then you control everything.

You can also use the database Purge function and pass a list of ObjectIds of the block defs you want to nuke for any cleanup you require.

Just some thoughts.

Cheers,
Glenn.

Draftek

  • Guest
Re: Rewriting program - opinions?
« Reply #12 on: November 15, 2007, 08:05:14 AM »
Here is something I've been dying to code but just do not have the time - Wrap the AcDbEntity with a C++ mixed / managed project and expose it to .Net.
Wallah! - you have custom entities for .Net.

I realize that it's not easy to create custom objects but it's not rocket science either - especially if the graphics are simple. Hell, if I can do it.... But as I and everyone else mentioned, you must have some C++ experience first and I would definitely not recommend quamper attempting it at this time.

Anyway, I'm moving all my development projects to Inventor and 3D - I may never get to write any AutoCAD code again :(

quamper

  • Guest
Re: Rewriting program - opinions?
« Reply #13 on: November 15, 2007, 08:38:44 AM »
Yeah I don't think I want to tackle creating custom objects now. I know I have a working method for accomplishing what I want for the time being.

But that's good to know, if they ever do open up custom objects in the Autocad .net api, I may revisit that then.

Thanks for the advice/opinions :D

MickD

  • King Gator
  • Posts: 3636
  • (x-in)->[process]->(y-out) ... simples!
Re: Rewriting program - opinions?
« Reply #14 on: November 15, 2007, 04:04:26 PM »
Just off topic for a sec,

Here is something I've been dying to code but just do not have the time - Wrap the AcDbEntity with a C++ mixed / managed project and expose it to .Net.
Wallah! - you have custom entities for .Net.
...

In theory that sounds good but the problem is registering the new object with acad and there is also some callbacks etc. that need implementing, this all gets done with a macro (I can't think of it just now) so you never see what's going on.
I actually started to write a C# CE and I got all the way but for the callbacks, now I know a bit more about them I might have a better chance.
I'll see if I can dig up the code and I'll start a new thread for a bit of fun and learnin'
"Programming is really just the mundane aspect of expressing a solution to a problem."
- John Carmack

"Short cuts make long delays,' argued Pippin.”
- J.R.R. Tolkien

sinc

  • Guest
Re: Rewriting program - opinions?
« Reply #15 on: November 15, 2007, 06:19:45 PM »
Also note that Xdata is somewhat deprecated in favor of Xrecords.

The problem with Xdata is that it is limited to a total of 16KB of data per entity, and other applications besides yours may be trying to use some of that space.  This problem does not exist with Xrecords.

Glenn R

  • Guest
Re: Rewriting program - opinions?
« Reply #16 on: November 15, 2007, 08:07:12 PM »
Good point.

Draftek

  • Guest
Re: Rewriting program - opinions?
« Reply #17 on: November 16, 2007, 08:42:02 AM »
Just off topic for a sec,

Here is something I've been dying to code but just do not have the time - Wrap the AcDbEntity with a C++ mixed / managed project and expose it to .Net.
Wallah! - you have custom entities for .Net.
...

In theory that sounds good but the problem is registering the new object with acad and there is also some callbacks etc. that need implementing, this all gets done with a macro (I can't think of it just now) so you never see what's going on.
I actually started to write a C# CE and I got all the way but for the callbacks, now I know a bit more about them I might have a better chance.
I'll see if I can dig up the code and I'll start a new thread for a bit of fun and learnin'

Yeah, I remember some tricky coding required during the entry point of the unmanaged registration of the project - something to do with a factory, I think. I have some code somewhere that works but I don't have the time to try and find it out. All the work was in the wrapper conversion methods - not rocket science but a lot of work. I saw your other post on using pInvoke to get to the object. I never thought of doing that on an object level! I can't wrap my mind around it but I'd really like to see somebody try it.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: Rewriting program - opinions?
« Reply #18 on: December 26, 2007, 04:01:18 PM »
You can also use the database Purge function and pass a list of ObjectIds of the block defs you want to nuke for any cleanup you require.
Cheers,
Glenn.
OK, Im stuck trying to figure out what my are ObjectIDs.  Im trying to purge unused layers from a dwg.
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: Rewriting program - opinions?
« Reply #19 on: December 26, 2007, 04:30:48 PM »
this is what I found on net
Purge code from Through-The-Interface
Code: [Select]
using Autodesk.AutoCAD.ApplicationServices;

using Autodesk.AutoCAD.DatabaseServices;

using Autodesk.AutoCAD.EditorInput;

using Autodesk.AutoCAD.Runtime;

using System.IO;

using System;

namespace Purger

{

  public class Commands

  {

    [CommandMethod("PC")]

    public void PurgeCurrentDocument()

    {

      Document doc =

        Application.DocumentManager.MdiActiveDocument;

      Database db = doc.Database;

      Editor ed = doc.Editor;

      int count =

        PurgeDatabase(db);

      ed.WriteMessage(

        "\nPurged {0} object{1} from " +

        "the current database.",

        count,

        count == 1 ? "" : "s"

      );

    }

    private static int PurgeDatabase(Database db)

    {

      int idCount = 0;

      Transaction tr =

        db.TransactionManager.StartTransaction();

      using (tr)

      {

        // Create the list of objects to "purge"

        ObjectIdCollection idsToPurge =

          new ObjectIdCollection();

        // Add all the Registered Application names

        RegAppTable rat =

          (RegAppTable)tr.GetObject(

            db.RegAppTableId,

            OpenMode.ForRead

        );

        foreach (ObjectId raId in rat)

        {

          if (raId.IsValid)

          {

            idsToPurge.Add(raId);

          }

        }

        // Call the Purge function to filter the list

        db.Purge(idsToPurge);

        Document doc =

          Application.DocumentManager.MdiActiveDocument;

        Editor ed = doc.Editor;

        ed.WriteMessage(

          "\nRegistered applications being purged: "

        );

        // Erase each of the objects we've been

        // allowed to

        foreach (ObjectId id in idsToPurge)

        {

          DBObject obj =

            tr.GetObject(id, OpenMode.ForWrite);

          // Let's just add to me "debug" code

          // to list the registered applications

          // we're erasing

          RegAppTableRecord ratr =

            obj as RegAppTableRecord;

          if (ratr != null)

          {

            ed.WriteMessage(

              "\"{0}\" ",

              ratr.Name

            );

          }

          obj.Erase();

        }

        // Return the number of objects erased

        // (i.e. purged)

        idCount = idsToPurge.Count;

        tr.Commit();

      }

      return idCount;

    }

  }

}
 
Now to make this useable
« Last Edit: December 26, 2007, 04:35:07 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)

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Rewriting program - opinions?
« Reply #20 on: December 26, 2007, 05:19:06 PM »
You can also use the database Purge function and pass a list of ObjectIds of the block defs you want to nuke for any cleanup you require.
Cheers,
Glenn.
OK, Im stuck trying to figure out what my are ObjectIDs.  Im trying to purge unused layers from a dwg.
I think you will need to make a list/array to store the names of layers used.  You will have to step through all objects within the drawing, and all within the block table, so I would just step through the block table since that is where the layout blocks are stored.  Don't forget to step through all objects that can have sub entities.  Then step through the layer table and see if each layer table record is within the list/array.

That is how I do it in my lisp, and I didn't see any way with the layer table record to see if it's in use just from the record.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: Rewriting program - opinions?
« Reply #21 on: December 26, 2007, 05:21:33 PM »
I was thinking of trying to purge each entry in the LayerTable, thinking that if in use, autocad wont
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)

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Rewriting program - opinions?
« Reply #22 on: December 26, 2007, 05:37:49 PM »
I was thinking of trying to purge each entry in the LayerTable, thinking that if in use, autocad wont
I did that in Lisp, and the way I described was much quicker.  Maybe you won't notice the speed difference in .Net though.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Glenn R

  • Guest
Re: Rewriting program - opinions?
« Reply #23 on: December 26, 2007, 06:44:34 PM »
Create an ObjectIdCollection or whatever the database purge function wants. You do this by cycling thru the layer talbe and collect all layer objectid's.

Pass this to the purge function and whatever is left in your collection of id's after purge has finished is what you can safely delete.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: Rewriting program - opinions?
« Reply #24 on: December 27, 2007, 02:13:46 PM »
Wow, that was easier than I thought it would be  :-D :-D :-D :-D :-D :lol: :lol: :lol: :lol:

« Last Edit: December 27, 2007, 02:46:32 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)

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Rewriting program - opinions?
« Reply #25 on: December 27, 2007, 02:51:01 PM »
You can also use the database Purge function and pass a list of ObjectIds of the block defs you want to nuke for any cleanup you require.
Cheers,
Glenn.
OK, Im stuck trying to figure out what my are ObjectIDs.  Im trying to purge unused layers from a dwg.
I think you will need to make a list/array to store the names of layers used.  You will have to step through all objects within the drawing, and all within the block table, so I would just step through the block table since that is where the layout blocks are stored.  Don't forget to step through all objects that can have sub entities.  Then step through the layer table and see if each layer table record is within the list/array.

That is how I do it in my lisp, and I didn't see any way with the layer table record to see if it's in use just from the record.

This is what I was talking about here.  Use/abuse/ignore as you like.  :-)
Code: [Select]
public ArrayList FindUsedLayers (Database db) {
ArrayList LayNameList = new ArrayList();
using (Transaction Trans = db.TransactionManager.StartTransaction()) {
foreach (ObjectId ObjId in (BlockTable)Trans.GetObject(db.BlockTableId, OpenMode.ForRead)) {
BlockTableRecord BlkTblRec = (BlockTableRecord)Trans.GetObject(ObjId, OpenMode.ForRead);
if (!BlkTblRec.IsFromExternalReference || !BlkTblRec.IsFromOverlayReference) {
foreach (ObjectId NestedId in BlkTblRec) {
Entity tempEnt = Trans.GetObject(NestedId, OpenMode.ForRead) as Entity;
string tempLayName = tempEnt.Layer;
if (!LayNameList.Contains(tempLayName))
LayNameList.Add(tempLayName);
BlockReference BlkRef = Trans.GetObject(NestedId, OpenMode.ForRead) as BlockReference;
if (BlkRef != null) {
foreach (ObjectId AttId in BlkRef.AttributeCollection) {
tempEnt = Trans.GetObject(AttId, OpenMode.ForRead) as Entity;
tempLayName = tempEnt.Layer;
if (!LayNameList.Contains(tempLayName))
LayNameList.Add(tempLayName);
}
}
}
}
}
}
return LayNameList;
}
[CommandMethod("TestDelLayers")]
public void DeleteLayers () {
Document Doc = acadApp.DocumentManager.MdiActiveDocument;
Editor Ed = Doc.Editor;
Database Db = Doc.Database;
ArrayList LayNameList = FindUsedLayers(Db);
using (Transaction Trans = Db.TransactionManager.StartTransaction()) {
foreach (ObjectId ObjId in (LayerTable)Trans.GetObject(Db.LayerTableId, OpenMode.ForRead)) {
LayerTableRecord LayTblRec = Trans.GetObject(ObjId, OpenMode.ForRead) as LayerTableRecord;
string LayName = LayTblRec.Name;
if (!LayNameList.Contains(LayName) && !LayName.Contains("|") && !string.Compare(LayName, "0").Equals(0)) {
LayTblRec.UpgradeOpen();
Ed.WriteMessage("\n Erasing layer: {0}", LayName);
LayTblRec.Erase();
}
}
Trans.Commit();
}
}

Quote
Command: testdellayers

 Erasing layer: DAYSTAMP
 Erasing layer: KEYHATCH
 Erasing layer: ETEXT
 Erasing layer: NOTES
 Erasing layer: E-16--SDWK-SLAB-DIKE
 Erasing layer: E-12B---BK-CRB-ED-GUT
Command: u
LAYER CONTROL
Command:
U TESTDELLAYERS
Command: purge*Cancel*

Command: -purge

Enter type of unused objects to purge
[Blocks/Dimstyles/LAyers/LTypes/Plotstyles/SHapes/textSTyles/Mlinestyles/Tablest
yles/Regapps/All]: la
Enter name(s) to purge <*>:
Verify each name to be purged? [Yes/No] <Y>: n
Deleting layer "DAYSTAMP".
Deleting layer "E-12B---BK-CRB-ED-GUT".
Deleting layer "E-16--SDWK-SLAB-DIKE".
Deleting layer "ETEXT".
Deleting layer "KEYHATCH".
Deleting layer "NOTES".
6 layers deleted.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: Rewriting program - opinions?
« Reply #26 on: December 27, 2007, 03:06:36 PM »
Code: [Select]
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using System.IO;
using System;
namespace Purger
{
    public class Commands
    {
        [CommandMethod("PC")]
        public void PurgeCurrentDocument()
        {
            Document doc =
              Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;
            int count =
              PurgeDatabase(db);
            ed.WriteMessage(
  "\nPurged {0} object{1} from " +
  "the current database.",
  count,
  count == 1 ? "" : "s"
);
        }
        private static int PurgeDatabase(Database db)
        {
            int idCount = 0;
            Transaction tr =
              db.TransactionManager.StartTransaction();
            using (tr)
            {
                // Create the list of objects to "purge"
                ObjectIdCollection idsToPurge =
                  new ObjectIdCollection();
                // Add all the Registered Application names
                LayerTable LT =
                  (LayerTable)tr.GetObject(
                    db.LayerTableId,
                    OpenMode.ForRead
                );
                foreach (ObjectId LtId in LT)
                {
                    if (LtId.IsValid)
                    {
                        idsToPurge.Add(LtId);
                    }
                }
                // Call the Purge function to filter the list
                db.Purge(idsToPurge);
                Document doc =
                  Application.DocumentManager.MdiActiveDocument;
                Editor ed = doc.Editor;
                ed.WriteMessage(
                  "\nLayers being purged: "
                );
                // Erase each of the objects we've been
                // allowed to
                foreach (ObjectId id in idsToPurge)
                {
                    DBObject obj =
                      tr.GetObject(id, OpenMode.ForWrite);
                    // Let's just add to me "debug" code
                    // to list the registered applications
                    // we're erasing
                    LayerTableRecord LTR =
                      obj as LayerTableRecord;
                    if (LTR != null)
                    {
                        ed.WriteMessage(
                          "\"{0}\" ",
                          LTR.Name
                        );
                    }
                    obj.Erase();
                }
                // Return the number of objects erased
                // (i.e. purged)
                idCount = idsToPurge.Count;
                tr.Commit();
            }
            return idCount;
        }
    }
}
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: Rewriting program - opinions?
« Reply #27 on: December 27, 2007, 03:10:14 PM »
T.W. give my code a whirl and see if it compares speed-wise.  I purged 106 layers in my test file, and it was done in a blink of the eye.
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: Rewriting program - opinions?
« Reply #28 on: December 27, 2007, 03:11:10 PM »
Duh,

That's what I was talking about :)

However, you can further refine that to be more generic and work on ANY table record by opening them as SymbolTableRecords as this is the base calss for all tables ie blocks, layers, linetypes etc.

You've used the base class of all objects (DBObject) but it's better to narrow it to the least common demoninator if you will...

Cheers,
Glenn.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: Rewriting program - opinions?
« Reply #29 on: December 27, 2007, 03:18:03 PM »
Glenn, whilst what you are saying makes sense in my head, Im not sure how to do that.  Can you give me a nudge in the right direction?  :-)
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)

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Rewriting program - opinions?
« Reply #30 on: December 27, 2007, 03:40:09 PM »
They seem to be about the same speed wise, but yours also purged out xref layers, while I make sure I don't.  Don't know if that matters or not, but I noticed it did on my little drawing, and a drawing that purged out 162 layers.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Rewriting program - opinions?
« Reply #31 on: December 27, 2007, 03:49:01 PM »
Glenn, whilst what you are saying makes sense in my head, Im not sure how to do that.  Can you give me a nudge in the right direction?  :-)
Maybe something like this.
Code: [Select]
public ObjectIdCollection GetPurgableIds (Database db, ObjectId TabId) {
ObjectIdCollection idsToPurge = new ObjectIdCollection();
using (Transaction Trans = db.TransactionManager.StartTransaction()) {
SymbolTable SymTbl = Trans.GetObject(TabId, OpenMode.ForRead) as SymbolTable;
foreach (ObjectId ObjId in SymTbl) {
idsToPurge.Add(ObjId);
}
db.Purge(idsToPurge);
}
return idsToPurge;
}
Then called like
Code: [Select]
ObjectIdCollection PurgableIds = GetPurgableIds (Db, Db.LayerTableId);

Edit:  Show complete code to erase layers.
Edit3:  Made it show it won't try and erase items that are dependent on xrefs.  Shown in the code in red.

Code: [Select]
[CommandMethod("PC2")]
public void PurgeCurrentDocument2() {
Document Doc = acadApp.DocumentManager.MdiActiveDocument;
Database Db = Doc.Database;
Editor Ed = Doc.Editor;
using (Transaction Trans = Db.TransactionManager.StartTransaction()) {
ObjectIdCollection PurgeIds = GetPurgableIds(Db, Db.LayerTableId);
[color=red] int CountIds = PurgeIds.Count;[/color]
foreach (ObjectId ObjId in PurgeIds) {
SymbolTableRecord SymTblRec = Trans.GetObject(ObjId, OpenMode.ForWrite) as SymbolTableRecord;
[color=red] if (SymTblRec.IsDependent)
--CountIds;
else {
Ed.WriteMessage("\n Deleted layer: {0}", SymTblRec.Name);
SymTblRec.Erase();
}[/color]
}
[color=red] Ed.WriteMessage("\n {0} total number of layers deleted.", CountIds);[/color]
}
}

I learned something new.  Now to go read up on the Purge method.  :-)

Edit2:  Glenn beat me to the punch.  See code below.  Thanks Glenn.
« Last Edit: December 27, 2007, 05:35:28 PM by T.Willey »
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Glenn R

  • Guest
Re: Rewriting program - opinions?
« Reply #32 on: December 27, 2007, 03:58:24 PM »
Tim,

Spot on, but you can also apply that to the foreach loop you would use to delete the id's as well.

Writing this in line off the top of my head without testing:

foreach (objectId symbolTableRecordId in SomeSymbolTable) {
  SymbolTableRecord symbolTableRecord = tr.Getobject(symbolTableRecordId, openMode.ForWrite, true) as SymbolTableRecord;
  symbolTableRecord.Erase();
}

Cheers,
Glenn.

BeanBag

  • Guest
Re: Rewriting program - opinions?
« Reply #33 on: December 28, 2007, 08:13:35 AM »
T Willey I got your first program to work but seems to be a problem when using symboltablerecord.

Your program runs through and tells me its deleted the expected layers but the layers still exist.

It would seem this line is not doing what it should:

Code: [Select]
SymTblRec.Erase();
Using Express 2008 and Autocad 2008 - only learning  .Net for Cad right now so can't be much help.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: Rewriting program - opinions?
« Reply #34 on: December 28, 2007, 10:52:01 AM »
I am a little confused on this piece here.
Code: [Select]
using (Transaction Trans = Db.TransactionManager.StartTransaction())
        {
            ObjectIdCollection PurgeIds = GetPurgableIds(Db, Db.BlockTableId );
            //ObjectIdCollection PurgeIds = GetPurgableIds(Db, Db.LayerTableId);
            int CountIds = PurgeIds.Count;
            foreach (ObjectId ObjId in PurgeIds)
            {
                SymbolTableRecord SymTblRec = Trans.GetObject(ObjId, OpenMode.ForWrite) as SymbolTableRecord;
                if (SymTblRec.IsDependent)
                    --CountIds;
                else
                {
                    Ed.WriteMessage("\n Deleted block: {0}", SymTblRec.Name);
                    SymTblRec.Erase();
                }
            }
            Ed.WriteMessage("\n {0} total number of layers deleted.", CountIds);
        }

from Acad
Command: PC2
 Deleted block: 3D-TTL-A


I swapped the LayerTableId for BlockTableId.  As I step through the code, I see the SymTblRec.Erase() work, yet when its done, the block definition is not purged.  Any 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)

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Rewriting program - opinions?
« Reply #35 on: December 28, 2007, 10:57:05 AM »
David, I haven't looked at the code, but ..

Are the blocks/layers still there if you save and re-open the drawing ?

As I understand it ;
The table entries are not actually erased, they are marked as 'to be erased' ( or somesuch ) and don't actually get removed till the drawing is closed. ... think about 'UNDO' capability. 

added:
They should not show in the blocks/layers dialog however ... they are still accessable if you iterate the table.
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.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: Rewriting program - opinions?
« Reply #36 on: December 28, 2007, 10:59:46 AM »
I just tried, and its a no-go.  I wonder if the Layer/Block Table Ids have to be cast back to their "proper" Ids not generic SymbolTableId.  Ill try that next
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)

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8702
  • AKA Daniel
Re: Rewriting program - opinions?
« Reply #37 on: December 28, 2007, 11:07:07 AM »
                SymbolTableRecord SymTblRec = Trans.GetObject(ObjId, OpenMode.ForWrite) as SymbolTableRecord;


this?

Code: [Select]
SymbolTableRecord SymTblRec = Trans.GetObject(ObjId, OpenMode.ForWrite,false) as SymbolTableRecord;


edit ...DoH Sorry I should have read the post
« Last Edit: December 28, 2007, 11:11:06 AM by Daniel »

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Rewriting program - opinions?
« Reply #38 on: December 28, 2007, 11:07:37 AM »
T Willey I got your first program to work but seems to be a problem when using symboltablerecord.

Your program runs through and tells me its deleted the expected layers but the layers still exist.

It would seem this line is not doing what it should:

Code: [Select]
SymTblRec.Erase();
Using Express 2008 and Autocad 2008 - only learning  .Net for Cad right now so can't be much help.
I am a little confused on this piece here.
Code: [Select]
using (Transaction Trans = Db.TransactionManager.StartTransaction())
        {
            ObjectIdCollection PurgeIds = GetPurgableIds(Db, Db.BlockTableId );
            //ObjectIdCollection PurgeIds = GetPurgableIds(Db, Db.LayerTableId);
            int CountIds = PurgeIds.Count;
            foreach (ObjectId ObjId in PurgeIds)
            {
                SymbolTableRecord SymTblRec = Trans.GetObject(ObjId, OpenMode.ForWrite) as SymbolTableRecord;
                if (SymTblRec.IsDependent)
                    --CountIds;
                else
                {
                    Ed.WriteMessage("\n Deleted block: {0}", SymTblRec.Name);
                    SymTblRec.Erase();
                }
            }
            Ed.WriteMessage("\n {0} total number of layers deleted.", CountIds);
        }

from Acad
Command: PC2
 Deleted block: 3D-TTL-A


I swapped the LayerTableId for BlockTableId.  As I step through the code, I see the SymTblRec.Erase() work, yet when its done, the block definition is not purged.  Any ideas?
That is because I forgot to 'commit' the transaction.  Sorry.   :cry:  After the 'Ed.WriteMessage....' line add 'Trans.Commit()' and all should be fine again.   :-)
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Rewriting program - opinions?
« Reply #39 on: December 28, 2007, 11:11:46 AM »
>>>>>>>>>>>>>  add 'Trans.Commit()' and all should be fine again.   :-)

just came back to ask about that possibility :-)
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.

David Hall

  • Automatic Duh Generator
  • King Gator
  • Posts: 4075
Re: Rewriting program - opinions?
« Reply #40 on: December 28, 2007, 11:14:56 AM »
DUH!!!!!!!!!!
I was so wrapped up in trying to switch to the BlockTable and LayerTable at same time, I didn't read all the way down, I just copied and pasted.
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: Rewriting program - opinions?
« Reply #41 on: December 28, 2007, 11:15:53 AM »
That did it
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)

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Rewriting program - opinions?
« Reply #42 on: December 28, 2007, 11:18:41 AM »
That did it
Good to hear!  :-)


ps.  BeanBag  Welcome to theSwamp.  :-)  I'm just starting with .Net also, and this is a great place to be to learn.
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.

T.Willey

  • Needs a day job
  • Posts: 5251
Re: Rewriting program - opinions?
« Reply #43 on: December 28, 2007, 11:23:08 AM »
DUH!!!!!!!!!!
I was so wrapped up in trying to switch to the BlockTable and LayerTable at same time, I didn't read all the way down, I just copied and pasted.
On a side note, you might want to read the Arx doc's about the 'purge' method and the two ways in which it can be called.  It says that if you want to purge something that can reference something within the same table, ie. blocks, then you want to pass it something besides an ObjectIdCollection.

Quote from: Arx Docs
<snip>

purge(

AcDbObjectIdGraph& idGraph);

idGraph Input graph of objects in the database. The graph will be returned containing only those objects that may safely be removed from the database.

This version of the purge() method works in one pass. The method looks for references between the objects passed in so that it does not need to be called multiple times. In other words, if a Layer and a Linetype are passed in, and the only reference to the Linetype is from the Layer, then the graph returned will indicate that both the Layer and the Linetype can be purged. (The older AcDbObjectIdArray version of purge() would first indicate that only the Layer could be purged. Then a second call, after erasing the Layer, would say that the Linetype could be purged.)

<snip>
Tim

I don't want to ' end-up ', I want to ' become '. - Me

Please think about donating if this post helped you.