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

0 Members and 1 Guest are viewing this topic.

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)