Author Topic: Reading and Saving Attribute values. ala DBX..  (Read 10732 times)

0 Members and 1 Guest are viewing this topic.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Reading and Saving Attribute values. ala DBX..
« on: August 23, 2009, 01:06:15 AM »
Reading and Saving Attribute values.

I've been locked away in the bedroom for a couple of days with nothing better to do than sleep, consume cough syrup, read, and think about attribute extraction.

I've been using some VLisp code that does the job at a rate of about  30,000 drawings per hour for 5 or 6 blocks in each drawing.
... pretty reasonable I thought, and hard to beat time wise.

The C# code posted beats it hands down !  :)
I've purposely NOT used the dataExtraction API so this should be transportable.

for this test I've re-used the same drawing for 500 open, extract, write values, close cycles ....

These are the test times.
TEST0823A is the Vlisp
Doit is the c#
Quote
Command: vlide

Command:
Command: TEST0823A

  This will take a couple of minutes...

  Files completed in 39.203 seconds.
Command:
Command: TEST0823A

  This will take a couple of minutes...

  Files completed in 37.766 seconds.
Command:
Command: netload

Command: doit

 This will take a couple of minutes...

End eval...Process time: 29.171875 Seconds for 500 files.

Command: Doit

 This will take a couple of minutes...

End eval...Process time: 28.828125 Seconds for 500 files.


I'm still a little fuzzy in the head, so the code may need another set of eyes ...
and keep in mind that this is just proof of concept code.

This is the data saved, one line per block, saved as an association list of Tag . Value pairs. :
The C# could have been saved in several formats, but I've used the same format as my VLisp code.
Quote
((BBL_DATA .  )(BBL_MARK . 121D)(BBL_LOC . EACH END)(BBL_QTY . 4)(BBL_DESC . M20x50 B.N.W.)(BBL_GRADE . 8.8)(BBL_TENSION . S)(BBL_FINISH . GALV)(BBL_GRIP .  10 10)(BBL_NOTE1 . )(BBL_NOTE2 . ))
((BBL_DATA .  )(BBL_MARK . 121A)(BBL_LOC . EACH END)(BBL_QTY . 1)(BBL_DESC . M20x50 B.N.W.)(BBL_GRADE . 8.8)(BBL_TENSION . S)(BBL_FINISH . GALV)(BBL_GRIP .  10 10)(BBL_NOTE1 . )(BBL_NOTE2 . ))
((BBL_DATA .  )(BBL_MARK . 121E)(BBL_LOC . EACH END)(BBL_QTY . 5)(BBL_DESC . M20x60 B.N.W.)(BBL_GRADE . 8.8)(BBL_TENSION . S)(BBL_FINISH . GALV)(BBL_GRIP .  10 10 10)(BBL_NOTE1 . )(BBL_NOTE2 . ))
((BBL_DATA .  )(BBL_MARK . 121B)(BBL_LOC . EACH END)(BBL_QTY . 2)(BBL_DESC . M20x60 B.N.W.)(BBL_GRADE . 8.8)(BBL_TENSION . S)(BBL_FINISH . GALV)(BBL_GRIP .  10 10 10)(BBL_NOTE1 . )(BBL_NOTE2 . ))
((BBL_DATA .  )(BBL_MARK . 121F)(BBL_LOC . EACH END)(BBL_QTY . 5)(BBL_DESC . M20x70 B.N.W.)(BBL_GRADE . 8.8)(BBL_TENSION . S)(BBL_FINISH . GALV)(BBL_GRIP .  10 10 20)(BBL_NOTE1 . )(BBL_NOTE2 . ))
((BBL_DATA .  )(BBL_MARK . 121C)(BBL_LOC . EACH END)(BBL_QTY . 3)(BBL_DESC . M20x70 B.N.W.)(BBL_GRADE . 8.8)(BBL_TENSION . S)(BBL_FINISH . GALV)(BBL_GRIP .  10 20 10)(BBL_NOTE1 . )(BBL_NOTE2 . ))


The VLisp Code :
Code: [Select]

(vl-load-com)
(defun kdub:DBX:GetInterface (/ AcadVer IAxDbDocument)
  (setq AcadVer       (atoi (getvar "acadver"))
        IAxDbDocument (if (< AcadVer 16)
                        (vla-getinterfaceobject
                          (vlax-get-acad-object)
                          "ObjectDBX.AxDbDocument"
                        )
                        (vla-getinterfaceobject
                          (vlax-get-acad-object)
                          (strcat "ObjectDBX.AxDbDocument." (itoa AcadVer))
                        )
                      )
  )
)


;;;-------------------------------------------------------------------
;;;-------------------------------------------------------------------
;;;  
(defun c:test0823a (/ BlockName FileName start finish IAxDbDocument )
  (setq BlockName "BBL_V8"
        FileName      "C:\\Test20090823.dwg"
  )
  (prompt "\n  This will take a couple of minutes...\n")
  ;; -----------------
  ;;
  ;; (dos_waitcursor t)
  (setq start (getvar "millisecs"))
  ;;
  (repeat 500
    (setq IAxDbDocument (kdub:DBX:getInterface))

    (if (vl-catch-all-error-p
          (vl-catch-all-apply 'vla-open (list IAxDbDocument FileName))
        )
      (setq IAxDbDocument nil)
    )
    (if IAxDbDocument
      (kdub:BDX:GetAttributes_0823a FileName BlockName IAxDbDocument)
    )
    (if (and IAxDbDocument
             (not (vlax-object-released-p IAxDbDocument)))
      (vlax-release-object IAxDbDocument)
    )

  )
  (setq finish (getvar "millisecs"))
  (prompt (strcat "\n  Files completed in "
                  (rtos (/ (- finish start) 1000.0) 2 4)
                  " seconds."
          )
  )
  ;; -----------------
  ;;
  ;;(dos_waitcursor)
  (princ)
)
;;;-------------------------------------------------------------------
;;;-------------------------------------------------------------------
;;;

(defun kdub:BDX:GetAttributes_0823a (dwgFileName      BlockNamesPattern
                                     dbx-iacaddocument                 /
                                     att              attlst           dbx-iacaddocument
                                     Obj              fdesc_id         blockName
                                    )
  ;;
  (vl-catch-all-apply
    '(lambda ()
       (vlax-for Obj (vla-get-modelspace dbx-iacaddocument)
         (if (and (= (vla-get-objectname Obj) "AcDbBlockReference")
                  (wcmatch (vla-get-name Obj) BlockNamesPattern)
             )
           (progn (setq AttLst
                         (cons
                           (mapcar
                             '(lambda (Att)
                                (cons (vla-get-tagstring Att)
                                      (vla-get-textstring Att)
                                )
                              )
                             (vlax-invoke Obj 'GetAttributes)
                           )
                           AttLst
                         )
                  )
           )
         )
       )
     )
  )
  (or AttLst (setq AttLst '(" ")))
  ;;
  ;;
  ;; Write data to file.
  (setq fdesc_id (open (strcat dwgFileName ".txt") "W"))
  (foreach item AttLst
    (write-line (vl-princ-to-string item) fdesc_id)
  )
  (setq fdesc_id (close fdesc_id))
  ;;
  ;;
)
;;;-------------------------------------------------------------------
;;;-------------------------------------------------------------------
;;;

The C# Code
Code: [Select]
// (C) CodeHimBelonga kdub@home.
// 20090823.

using System;
using System.IO;
using System.Text;
using System.Collections.Generic;


using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;

using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;

[assembly: CommandClass(typeof(Kdub.Testing.DBX_Block.MyCommands))]

namespace Kdub.Testing.DBX_Block
{
    public class MyCommands
    {
        [CommandMethod("Doit", CommandFlags.Modal | CommandFlags.Session)]
        public void MyCommand20090823()
        {
            Document doc = AcadApp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            ed.WriteMessage("{0} This will take a couple of minutes... {0}", Environment.NewLine);

            DateTime TimeStart = DateTime.Now;
            Dictionary<string, string> attributePairs = new Dictionary<string, string>();

            string drawingFileName = @"C:\\Test20090823.dwg";
            string blockName = "BBL_V8";
            string outputFileName = @"C:\\Test20090823.txt";
            StreamWriter logFileWriter = null;
            
            int fileCounter = 0;
            int TotalFileCount = 500;

            //show the progress of the function
            ProgressMeter pm = new ProgressMeter();
            pm.Start("Extracting Attributes");
            pm.SetLimit(TotalFileCount);
          
            try
            {
                while (fileCounter < TotalFileCount)
                {
                    try
                    {
                        //did user press ESCAPE?
                        if (HostApplicationServices.Current.UserBreak())
                        {
                            throw new Autodesk.AutoCAD.Runtime.Exception(ErrorStatus.UserBreak, "ESCAPE pressed");
                        }
                        //update progress bar
                        AcadApp.UpdateScreen();
                        pm.MeterProgress();
                        fileCounter++;

                        // use a NEW file  ( overwrite existing file)
                        logFileWriter = new StreamWriter(outputFileName, false, System.Text.Encoding.ASCII);
                        logFileWriter.AutoFlush = true;

                        // Create a new database with no document window
                        using (Database acDbxDb = new Database(false, true))
                        {
                            try
                            {
                                acDbxDb.ReadDwgFile(drawingFileName, System.IO.FileShare.None, false, "");

                                using (Transaction tr = acDbxDb.TransactionManager.StartTransaction())
                                {
                                    BlockTable bt = tr.GetObject(acDbxDb.BlockTableId, OpenMode.ForRead) as BlockTable;

                                    if (!bt.Has(blockName)) return;
                                    ObjectId btrId = bt[blockName];
                                    BlockTableRecord btr = tr.GetObject(btrId, OpenMode.ForRead, false) as BlockTableRecord;

                                    ObjectIdCollection blkRefIds = btr.GetBlockReferenceIds(false, false);
                                    if (blkRefIds == null || blkRefIds.Count == 0) return;
                                    foreach (ObjectId blkRefId in blkRefIds)
                                    {
                                        attributePairs.Clear();
                                        //
                                        BlockReference blkRef = tr.GetObject(blkRefId, OpenMode.ForRead, false) as BlockReference;
                                        AttributeCollection attRefIds = blkRef.AttributeCollection;
                                        if (attRefIds == null || attRefIds.Count == 0)
                                        {
                                            ed.WriteMessage("{0}F.U.B.B. : Failed getting AttributeCollection! Continuing...", Environment.NewLine);
                                            continue;
                                        }
                                        //instanceCount++;
                                        foreach (ObjectId attRefId in attRefIds)
                                        {
                                            AttributeReference attRef = tr.GetObject(attRefId, OpenMode.ForRead, false) as AttributeReference;
                                            if (attRef == null)
                                            {
                                                ed.WriteMessage("{0}F.U.B.B. : Failed to open an AttributeReference! Continuing...", Environment.NewLine);
                                                continue;
                                            }                                            
                                            attributePairs.Add(attRef.Tag.ToString(), attRef.TextString.ToString());
                                        }

                                        logFileWriter.Write("(");
                                        foreach (var pair in attributePairs)
                                        {
                                            logFileWriter.Write("(" + pair.Key + " . " + pair.Value + ")");
                                        }
                                        logFileWriter.Write(")" + Environment.NewLine);
                                    }
                                }
                            }
                            catch (Autodesk.AutoCAD.Runtime.Exception Ex)
                            {
                                Application.ShowAlertDialog("The following exception was caught:\n" +
                                                            Ex.Message);
                            }
                        }
                    }
                    catch (Autodesk.AutoCAD.Runtime.Exception acEx)
                    {
                        ed.WriteMessage("{0}AutoCAD Runtime Exception: {1}", Environment.NewLine, acEx.Message);
                        return;
                    }
                    catch (System.Exception ex)
                    {
                        ed.WriteMessage("{0}System Runtime Exception: {1}", Environment.NewLine, ex.ToString());
                        return;
                    }
                    finally
                    {
                        if (logFileWriter != null)
                            logFileWriter.Close();
                    }

                }
                TimeSpan TimeDuration = (DateTime.Now - TimeStart); ;

                ed.WriteMessage("\nEnd eval...Process time: "
                        + (TimeDuration.TotalSeconds + " Seconds for "                        
                        + TotalFileCount.ToString() + " files.\n")
                        );
            }
            catch (Autodesk.AutoCAD.Runtime.Exception acEx)
            {
                ed.WriteMessage("{0}AutoCAD Runtime Exception: {1}", Environment.NewLine, acEx.Message);
                return;
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("{0}System Runtime Exception: {1}", Environment.NewLine, ex.ToString());
                return;
            }
            finally
            {
                if (pm != null)
                    pm.Stop();

                if (logFileWriter != null)
                    logFileWriter.Close();
            }
        }

    }
        
}


PS: The .NET code uses a ProgressMeter and behaves nicely if the user gets impatient and bashes the ESC key  :|

I look forward to comments :)

/// kdub






« Last Edit: August 23, 2009, 01:13:10 AM by Kerry Brown »
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.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8728
  • AKA Daniel
Re: Reading and Saving Attribute values. ala DBX..
« Reply #1 on: August 23, 2009, 05:17:21 AM »
Nice coding!

and now for the nitpick ,
there is no need to call ToString on a string ( attRef.TextString.ToString());   ;-)

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Reading and Saving Attribute values. ala DBX..
« Reply #2 on: August 23, 2009, 06:08:30 AM »
Thanks Dan.

Yeah, the ToString() sort of is a reflex .. :)


PS:
hell's bells, that's a superfluous 6000 method calls in my test routine, just on that one line    :oops: 
« Last Edit: August 23, 2009, 06:32:29 AM by Kerry Brown »
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.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Reading and Saving Attribute values. ala DBX..
« Reply #3 on: August 23, 2009, 06:16:48 AM »

and to answer my mail ...

Some of the pairs have an empty string value .. or nil besause the attrubute value is not assigned
... so therefore the ((BBL_DATA .  ) etc entry in the extracted data.

/// kdub
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.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8728
  • AKA Daniel
Re: Reading and Saving Attribute values. ala DBX..
« Reply #4 on: August 23, 2009, 06:41:35 AM »
They sure do add up don't they.

Are you converting the big lisp library to C#? that's going to be a lot of work.. but fun work  :laugh:

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Reading and Saving Attribute values. ala DBX..
« Reply #5 on: August 23, 2009, 07:51:05 AM »

I've decided to take my programming seriously again Dan.

I can't imagine replacing all my Lispy stuff though .. it has it's place, and still works really well.
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.

Lee Mac

  • Seagull
  • Posts: 12915
  • London, England
Re: Reading and Saving Attribute values. ala DBX..
« Reply #6 on: August 23, 2009, 08:03:36 AM »
Can't believe that C# shaves 10secs off the processing time... unbelievably quicker  8-)

I can't comment much on the C# but nice LISP code though Kerry - I used a similar code here

Lee

gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: Reading and Saving Attribute values. ala DBX..
« Reply #7 on: August 23, 2009, 12:16:31 PM »
Thanks for sharing Kerry.
This may help me in my C# learning.
Speaking English as a French Frog

SomeCallMeDave

  • Guest
Re: Reading and Saving Attribute values. ala DBX..
« Reply #8 on: August 23, 2009, 01:03:45 PM »
Very Nice Kerry.  Thanks for sharing.

Just for giggles I ran Kerry's C# and LISP versions and my Ruby version on my machine with a mocked-up file.

Results:
      C# 45.3 seconds
   LISP  50.1 seconds
   Ruby 54.9 seconds

Ruby performed better than I thought it would

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Reading and Saving Attribute values. ala DBX..
« Reply #9 on: August 23, 2009, 04:25:35 PM »

You're welcome, guys.


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.

Glenn R

  • Guest
Re: Reading and Saving Attribute values. ala DBX..
« Reply #10 on: August 24, 2009, 04:56:53 AM »
Nicely done Kerry.

Nice coding!

and now for the nitpick ,
there is no need to call ToString on a string ( attRef.TextString.ToString());   ;-)


Funny...I was going to comment on the same thing ;)

I find the results not as good as I would have thought. I expected C# to be much faster than that.

Be interesting to see if applying some LINQage like TonyT has been doing lately, would make and difference to speed and readability in this case.

I must get back into this more as well...damn Microstation. :D

Glenn R

  • Guest
Re: Reading and Saving Attribute values. ala DBX..
« Reply #11 on: August 24, 2009, 05:53:24 AM »
Also, this:

Code: [Select]
string drawingFileName = @"C:\\Test20090823.dwg";

doesn't need the double backslashes, as you've specified it as a verbatim string using the @, so it could look like this:

Code: [Select]
string drawingFileName = @"C:\Test20090823.dwg";

Kerry, I have an idea that I want to test - can you post some sample data that I can work with please?

Hope you feel better.

Glenn.

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Reading and Saving Attribute values. ala DBX..
« Reply #12 on: August 24, 2009, 06:48:32 AM »

Kerry, I have an idea that I want to test - can you post some sample data that I can work with please?

Hope you feel better.

Glenn.

Here ya go as Ac2000 .
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.

Glenn R

  • Guest
Re: Reading and Saving Attribute values. ala DBX..
« Reply #13 on: August 24, 2009, 06:56:13 AM »
Ta muchly. Back in a bit after I set some tests...:D

Glenn R

  • Guest
Re: Reading and Saving Attribute values. ala DBX..
« Reply #14 on: August 24, 2009, 07:40:17 AM »
Times on a machine I'm using at the moment:

Lisp = 44.594 secs.
C# Original = 27.140625 secs
C# New = 22.203125 secs

New code:

Code: [Select]
// (C) CodeHimBelonga kdub@home.
// 20090823.

using System;
using System.IO;
using System.Text;
using System.Collections.Generic;


using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;

using AcadApp = Autodesk.AutoCAD.ApplicationServices.Application;

[assembly: CommandClass(typeof(Kdub.Testing.DBX_Block.MyCommands))]

namespace Kdub.Testing.DBX_Block
{
    public class MyCommands
    {
        [CommandMethod("Doit", CommandFlags.Modal | CommandFlags.Session)]
        public void MyCommand20090823()
        {
            Document doc = AcadApp.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            Editor ed = doc.Editor;

            ed.WriteMessage("{0} This will take a couple of minutes... {0}", Environment.NewLine);

            DateTime TimeStart = DateTime.Now;
            StringBuilder sb = new StringBuilder();

            string drawingFileName = @"C:\Temp\Test20090823.dwg";
            string blockName = "BBL_V8";
            string outputFileName = @"C:\Temp\Test20090823.txt";
            StreamWriter logFileWriter = null;

            int fileCounter = 0;
            int TotalFileCount = 500;

            //show the progress of the function
            ProgressMeter pm = new ProgressMeter();
            pm.Start("Extracting Attributes");
            pm.SetLimit(TotalFileCount);

            try
            {
                while (fileCounter < TotalFileCount)
                {
                    try
                    {
                        //did user press ESCAPE?
                        if (HostApplicationServices.Current.UserBreak())
                        {
                            throw new Autodesk.AutoCAD.Runtime.Exception(ErrorStatus.UserBreak, "ESCAPE pressed");
                        }
                        //update progress bar
                        AcadApp.UpdateScreen();
                        pm.MeterProgress();
                        fileCounter++;

                        // use a NEW file  ( overwrite existing file)
                        logFileWriter = new StreamWriter(outputFileName, false, System.Text.Encoding.ASCII);
                        logFileWriter.AutoFlush = true;

                        // Create a new database with no document window
                        using (Database acDbxDb = new Database(false, true))
                        {
                            try
                            {
                                acDbxDb.ReadDwgFile(drawingFileName, System.IO.FileShare.None, false, "");

                                using (Transaction tr = acDbxDb.TransactionManager.StartTransaction())
                                {
                                    BlockTable bt = tr.GetObject(acDbxDb.BlockTableId, OpenMode.ForRead) as BlockTable;

                                    if (!bt.Has(blockName)) return;
                                    ObjectId btrId = bt[blockName];
                                    BlockTableRecord btr = tr.GetObject(btrId, OpenMode.ForRead, false) as BlockTableRecord;

                                    ObjectIdCollection blkRefIds = btr.GetBlockReferenceIds(false, false);
                                    if (blkRefIds == null || blkRefIds.Count == 0) return;
                                    foreach (ObjectId blkRefId in blkRefIds)
                                    {
                                        BlockReference blkRef = tr.GetObject(blkRefId, OpenMode.ForRead, false) as BlockReference;
                                        AttributeCollection attRefIds = blkRef.AttributeCollection;
                                        if (attRefIds == null || attRefIds.Count == 0)
                                        {
                                            ed.WriteMessage("{0}F.U.B.B. : Failed getting AttributeCollection! Continuing...", Environment.NewLine);
                                            continue;
                                        }
                                        //instanceCount++;
                                        foreach (ObjectId attRefId in attRefIds)
                                        {
                                            AttributeReference attRef = tr.GetObject(attRefId, OpenMode.ForRead, false) as AttributeReference;
                                            if (attRef == null)
                                            {
                                                ed.WriteMessage("{0}F.U.B.B. : Failed to open an AttributeReference! Continuing...", Environment.NewLine);
                                                continue;
                                            }
                                            sb.AppendFormat("{0}{1} . {2}{3}", "(", attRef.Tag, attRef.TextString, ")");
                                        }

                                        logFileWriter.Write("(");
                                        sb.ToString();
                                        sb.Remove(0, sb.Length);
                                        logFileWriter.Write(")" + Environment.NewLine);
                                    }
                                }
                            }
                            catch (Autodesk.AutoCAD.Runtime.Exception Ex)
                            {
                                Application.ShowAlertDialog("The following exception was caught:\n" +
                                                            Ex.Message);
                            }
                        }
                    }
                    catch (Autodesk.AutoCAD.Runtime.Exception acEx)
                    {
                        ed.WriteMessage("{0}AutoCAD Runtime Exception: {1}", Environment.NewLine, acEx.Message);
                        return;
                    }
                    catch (System.Exception ex)
                    {
                        ed.WriteMessage("{0}System Runtime Exception: {1}", Environment.NewLine, ex.ToString());
                        return;
                    }
                    finally
                    {
                        if (logFileWriter != null)
                            logFileWriter.Close();
                    }

                }
                TimeSpan TimeDuration = (DateTime.Now - TimeStart); ;

                ed.WriteMessage("\nEnd eval...Process time: "
                        + (TimeDuration.TotalSeconds + " Seconds for "
                        + TotalFileCount.ToString() + " files.\n")
                        );
            }
            catch (Autodesk.AutoCAD.Runtime.Exception acEx)
            {
                ed.WriteMessage("{0}AutoCAD Runtime Exception: {1}", Environment.NewLine, acEx.Message);
                return;
            }
            catch (System.Exception ex)
            {
                ed.WriteMessage("{0}System Runtime Exception: {1}", Environment.NewLine, ex.ToString());
                return;
            }
            finally
            {
                if (pm != null)
                    pm.Stop();

                if (logFileWriter != null)
                    logFileWriter.Close();
            }
        }

    }

}

Interesting huh?

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8728
  • AKA Daniel
Re: Reading and Saving Attribute values. ala DBX..
« Reply #15 on: August 24, 2009, 08:39:59 AM »
here is an ARX version, probably not any faster since IO is the time consuming item.

Code: [Select]
  static void ArxBlockEx_doit(void)
  {
    clock_t start, end;
    double diff;
    start = clock();

    for(int i = 0 ; i < 500; i++)
    {   
      std::auto_ptr<AcDbDatabase> pDb (new AcDbDatabase(false , true));
      pDb->readDwgFile(_T("C:\\Test20090823.dwg"),  _SH_DENYNO ,false);
      GetAttributesBench_doit(&(*pDb), _T("BBL_V8"));
      pDb->closeInput(true);
    }
    end = clock();
    diff = ((double)(end - start)) / CLOCKS_PER_SEC;
    acutPrintf( _T("\n%2.3f seconds\n"), diff);
  }


  static void GetAttributesBench_doit(AcDbDatabase *pDatabase, const CString &name)
  {
    Acad::ErrorStatus es;
    std::wofstream out(_T("C:\\Test20090823.txt"));

    AcDbBlockTablePointer pBlockTable(pDatabase,AcDb::kForRead);

    if(pBlockTable.openStatus() != eOk) return;
    if(!pBlockTable->has(name)) return;

    AcDbObjectId blkid;
    if(pBlockTable->getAt(name,blkid) != eOk) return;

    AcDbBlockTableRecordPointer pTableRecord(blkid,AcDb::kForRead);
    if(pTableRecord.openStatus() != eOk) return;

    if (pTableRecord->hasAttributeDefinitions() == Adesk::kTrue)
    {
      AcDbObjectIdArray blockReferenceIds;
      pTableRecord->getBlockReferenceIds(blockReferenceIds);

      for(int i = 0 ; i < blockReferenceIds.length() ; i++)
      {
        AcDbObjectPointer<AcDbBlockReference> pBlockReference
          (blockReferenceIds[i] , AcDb::kForRead,Adesk::kFalse);

        out << "\n";
        std::auto_ptr<AcDbObjectIterator>
          pAttributeIterator(pBlockReference->attributeIterator());

        for (pAttributeIterator->start();
            !pAttributeIterator->done();
            pAttributeIterator->step())
        {

          AcDbObjectPointer<AcDbAttribute> pAttribute
            (pAttributeIterator->objectId(),AcDb::kForRead);

          if(pAttribute.openStatus() == eOk)
            out << "("<<  pAttribute->tag() << "." << pAttribute->textString() << ")";
        }
      }
    }
    out.close();
  }

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Reading and Saving Attribute values. ala DBX..
« Reply #16 on: August 24, 2009, 06:11:25 PM »
Times on a machine I'm using at the moment:

Lisp = 44.594 secs.
C# Original = 27.140625 secs
C# New = 22.203125 secs

New code:

Code: [Select]
///.>>
            StringBuilder sb = new StringBuilder();

 //..<<
}

Interesting huh?

yep .. I'll have a look tonight at home Glenn.

Thanks for the input.

//.......

Dan,
Which arx build is that for ?
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.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8728
  • AKA Daniel
Re: Reading and Saving Attribute values. ala DBX..
« Reply #17 on: August 24, 2009, 06:13:36 PM »
Sorry, for 07 - 09  x32

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Reading and Saving Attribute values. ala DBX..
« Reply #18 on: August 24, 2009, 08:33:04 PM »
Sorry,  ...

:)

Don't be.

[geek]
I have the technology.
[/geek]

would have liked to test in 2010, but heh !  :wink:
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.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8728
  • AKA Daniel
Re: Reading and Saving Attribute values. ala DBX..
« Reply #19 on: August 24, 2009, 08:42:35 PM »
Sorry,  ...

:)

Don't be.

[geek]
I have the technology.
[/geek]

would have liked to test in 2010, but heh !  :wink:


64 or 32 bit?   :laugh:

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Reading and Saving Attribute values. ala DBX..
« Reply #20 on: August 24, 2009, 08:43:14 PM »

32 this week :)
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.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8728
  • AKA Daniel
Re: Reading and Saving Attribute values. ala DBX..
« Reply #21 on: August 24, 2009, 08:54:35 PM »
here is both and the solution.

What is interesting is that 2010x64 is a third slower than 07x32 at this operation

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Reading and Saving Attribute values. ala DBX..
« Reply #22 on: August 25, 2009, 06:27:35 AM »
Thanks Dan, I'll have a play on the weekend.
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.