Author Topic: DrawingCompare - DwgFiler  (Read 8104 times)

0 Members and 1 Guest are viewing this topic.

Jeff H

  • Needs a day job
  • Posts: 6144
DrawingCompare - DwgFiler
« on: November 09, 2011, 04:14:36 AM »
This is messing around with DwgFiler for comparing what has changed in drawing.
For example when you have a large site or floor plan you have been working with then 6 months later you receive a update.
A way to see what has changed.
 
First off
  • This is just starting off to see how it worked
  • I understand that it will miss many entities for different situations
  • I am trying to get ideas before I proceed
  • If I would have known what little I learned from testing with this I would have implemented it completely different.

Things I have noticed
  • If one drawing is open and current in the editor then hatches will have more fields and number depends on the type of hatch. If both are read into a side database then they are equal.
  • If you compare what is written from WriteAddresss() regions will have different values
  • If using a WblockCloneFiler FilerType for example a Layer will write out as Harpointer then the next time for a different entity it will write out as SoftPointer
  • Many more that I can not think of right now
Questions or ideas for replies
  • Wondering if I should first run the SymbolTables and from there know what is new, changed , etc.... or follow references of each entity and if it has not been checked then keep follow each hard pointer etc...... 
  • Some ideas on how to look at this or how would you see the results returned. Different sets of Objectids for new entities, modified, deleted, ones with a reference's changed like a layer etc......
  • What ever you can come up with

I was using two files that were 28MB but i am not going to load them up but used a drawing that comes with in the sample folder with each installation.
 
About the download -- solution at bottom of  post
  • When you netload it should close all drawings and open a test drawing that is in bin/debug folder
  • This was for testing and used code from other dll but copied and pasted and made it basic.
  • I understand it needs work but is coded and while coding already know that it will be thrown away
  • There is a Sample_5-10-11.dwg then a Sample_8-11-11.dwg that is slightly modified.

To give you an idea and I do not like the way it is done and would like some others input and how they would look at it or see this from the different layers of complexity
Pic of original drawing that is closed

 
 
Pic of TestDrawing after 'runCompareFiler' command
Magenta = some reference was changed like it's layer
Yellow = It was modified
Green = It is new

 
Just For Testing
There is abstract class OutputFiler
Code: [Select]

    public abstract class OutputFiler: DrawingFiler
    {
           public OutputFiler(): base()
        {
        }
           public OutputFiler(FilerType filerType)
            : base(filerType)
        {
        }
           public abstract void writeInfo(string methodName);

           public abstract void writeInfo(string methodName, string value);

           public override void WriteAddress(System.IntPtr value)
           {
               writeInfo(MethodInfo.GetCurrentMethod().Name, value.ToString());
           }         
           public override void WriteHardOwnershipId(ObjectId value)
           {
               writeInfo(MethodInfo.GetCurrentMethod().Name, value.ToString()   "   "   value.Handle.ToString());
           }
           public override void WriteHardPointerId(ObjectId value)
           {
               writeInfo(MethodInfo.GetCurrentMethod().Name, value.ToString()   "   "   value.Handle.ToString());
           }
           public override void WriteInt16(short value)
           {
               writeInfo(MethodInfo.GetCurrentMethod().Name, value.ToString());
           }
           public override void WriteInt32(int value)
           {
               writeInfo(MethodInfo.GetCurrentMethod().Name, value.ToString());
           }
           public override void WritePoint3d(Point3d value)
           {
               writeInfo(MethodInfo.GetCurrentMethod().Name, value.ToString());
           }
 ////////////////etc..
 ////////////////etc..
    }

And a TextFilefiler(for writting info to a text file)  and a CommandLineFiler(writing to the command line) that override the writeInfo methods
 
 
Code: [Select]
public class CommandLineFiler: OutputFiler
    {
        private string fileType;
        private Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
        public override FilerType FilerType
        {
            get
            {
                if (fileType != Enum.GetName(this._filerType.GetType(), this._filerType))
                {
                    fileType = Enum.GetName(this._filerType.GetType(), this._filerType);
                    writeInfo(MethodInfo.GetCurrentMethod().Name, fileType);
                }
                return base.FilerType;
            }
        }
        public CommandLineFiler(): base()
        {
        }
        public CommandLineFiler(FilerType filerType)
            : base(filerType)
        {
        }
        public override void writeInfo(string methodName)
        {
            ed.WriteMessage(methodName   " = "   "\n");
        }
        public override void writeInfo(string methodName, string value)
        {
            ed.WriteMessage(methodName   " = ");
            ed.WriteMessage(value   "\n");
        }

    }
Code: [Select]
public class TextFileFiler: OutputFiler
    {
       private string dllPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
       private StringBuilder sb = new StringBuilder();

       public TextFileFiler() : base()
       {
           
       }
       public TextFileFiler(FilerType filerType)
           : base(filerType)
       {
           
       }
       public override void writeInfo(string methodName)
       {
           sb.AppendLine(methodName   " = ");
       }
       public override void writeInfo(string methodName, string value)
       {
           sb.AppendLine(methodName   " = "   value);
       }
       public void WriteToTextFile(string file)
       {
           using (StreamWriter sw = new StreamWriter(PlugInData.DllPath   file   ".txt"))
           {
               sw.Write(sb.ToString());
           }
       }
    }



 
 
 
 
 

MexicanCustard

  • Swamp Rat
  • Posts: 705
Re: DrawingCompare - DwgFiler
« Reply #1 on: November 09, 2011, 01:12:40 PM »
Do we care if anything other than visual entities have changed?
Revit 2019, AMEP 2019 64bit Win 10

pedroantonio

  • Guest
Re: DrawingCompare - DwgFiler
« Reply #2 on: November 11, 2011, 01:10:53 AM »
Interestingly good idea to make drawing comparison. I have needed such tool so many times that I have stoped counting it.
Thumbs up. I will testing it in next couple of days

Jeff H

  • Needs a day job
  • Posts: 6144
Re: DrawingCompare - DwgFiler
« Reply #3 on: November 11, 2011, 09:08:44 AM »
Do we care if anything other than visual entities have changed?

Maybe?
 
Trying to decide and get ideas how to handle that or how to 'interface' it. 

M-dub

  • Guest
Re: DrawingCompare - DwgFiler
« Reply #4 on: November 11, 2011, 10:28:54 AM »

pedroantonio

  • Guest
Re: DrawingCompare - DwgFiler
« Reply #5 on: November 12, 2011, 08:04:56 AM »
TO make it work on my sistem I have done this: lower it down to framework 3.5, remove reference to Csharp.
Marvelously! I am really impressed how you have done this with so little coding.

I have tested it on few of my files and i find it superb. It works with big files (10mb or more) but it takes time.
Timing on bigger drawing: 13.0mb vs 12.9mb acad 2010 format, amd x2 6000+  32bits ram4mb, release mode dll => 62sec

============================
CORE PROBLEMS:
**in big file comparison (13mb) - older has a closed polyline entitiy (Sample_5-10-11), newer not (Sample_8-11-11)=> NOT DETECTED - empty in TestDrawing (nothing of 3 possibilityes: not equal, eqal, new? I expect 'deleted' or similar?)

**in big file comparison (13mb) - older has a Text multiline entitiy (Sample_5-10-11), newer not (Sample_8-11-11)=> NOT DETECTED - empty in TestDrawing (nothing of 3 possibilityes: not equal, equal, new? I expect 'deleted' or similar?)

++ I think that DELETED state must also be shown on separate layer

============================
SUGGESTIONS:
**Show deleted state

**I suggest adding a ProgressBar...

**I suggest adding small dialog form where user can select file path 1, file path 2, output file path - (disable posibly overwriting)

**Create TestDwg form scratch,
Hmmm, or better, add TestDwg to solution and "extract" it when you need it (let say: to TEMP folder),
   populate it with differences and copy it to destination output folder from DialogForm - or something along this lines
 
**possibility to do it without closing currently opened drawings/dwg's

============================
ERRORS:
**it throws error if one of files is password protected
Autodesk.AutoCAD.Runtime.Exception: eSecErrorDecryptingData
   at Autodesk.AutoCAD.DatabaseServices.Database.ReadDwgFile(String fileName, FileOpenMode mode, Boolean allowCPConversion, String password)
   at DwgComparer.Commands.runCompareFiler() in *\DwgCompaer\DwgCompaer\Commands.cs:line 44
   at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorker(MethodInfo mi, Object commandObject, Boolean bLispFunction)
   at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter(MethodInfo mi, Object commandObject, Boolean bLispFunction)
   at Autodesk.AutoCAD.Runtime.PerDocumentCommandClass.Invoke(MethodInfo mi, Boolean bLispFunction)
   at Autodesk.AutoCAD.Runtime.CommandClass.CommandThunk.Invoke()

**it throws error if one of layers is locked
Autodesk.AutoCAD.Runtime.Exception: eOnLockedLayer
   at Autodesk.AutoCAD.DatabaseServices.TransactionManager.GetObjectInternal(AcDbTransactionManager* pTM, ObjectId id, OpenMode mode, Boolean openErased, Boolean forceOpenOnLockedLayer)
   at Autodesk.AutoCAD.DatabaseServices.Transaction.GetObject(ObjectId id, OpenMode mode)
   at DwgComparer.Commands.runCompareFiler() in *\DwgCompaer\DwgCompaer\Commands.cs:line 124
   at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorker(MethodInfo mi, Object commandObject, Boolean bLispFunction)
   at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter(MethodInfo mi, Object commandObject, Boolean bLispFunction)
   at Autodesk.AutoCAD.Runtime.PerDocumentCommandClass.Invoke(MethodInfo mi, Boolean bLispFunction)
   at Autodesk.AutoCAD.Runtime.CommandClass.CommandThunk.Invoke()

============================
OVERALL:
**it works beautifully with acad files. It's definetly under category of "The Add-In of Year"- TWO THUMBS UP :)

**it does not work wery well with drawing what we get from external architects (probably not created in acad;
  or as autodesk says it: Non Autodesk DWG. This DWG file was saved by a software application that was not developed or licensed by Autodesk.
  Autodesk cannot guarantee the application compatibility or integrity of this file.)

Hope it helps.
Z
« Last Edit: November 12, 2011, 09:06:09 AM by pedroantonio »

Jeff H

  • Needs a day job
  • Posts: 6144
Re: DrawingCompare - DwgFiler
« Reply #6 on: November 14, 2011, 06:27:19 PM »
It is still in its infancy and I knew problems would arise but I was trying to get ideas on how its public interface should look like.

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: DrawingCompare - DwgFiler
« Reply #7 on: December 19, 2012, 02:11:40 PM »
Where can I read detailed info about the DwgFiler class?

Jeff H

  • Needs a day job
  • Posts: 6144
Re: DrawingCompare - DwgFiler
« Reply #8 on: December 19, 2012, 03:16:22 PM »
Where can I read detailed info about the DwgFiler class?

Sorry my friend,
I do not know where to find any detailed information on any aspect of the API.
 

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: DrawingCompare - DwgFiler
« Reply #9 on: December 19, 2012, 11:56:37 PM »

Sorry my friend,
I do not know where to find any detailed information on any aspect of the API.
But you use it in your code. Where did you learn it? If in ADN resources, then can you give me the link? I not found it in ADN resources for the "DwgFiler" keyword searching.

Jeff H

  • Needs a day job
  • Posts: 6144
Re: DrawingCompare - DwgFiler
« Reply #10 on: December 20, 2012, 12:51:53 AM »
When I played around with that it was what I normally do which is probably not the best way but do not know what else to do.
 
Just basically from debugging and stepping through and looking at state of objects, printing out results, making assumptions then making changes that would effect its output and see if they line up etc.........
 
I think that's why there are the commandline and textfile filers to dump out the different results using the different filertypes and comparing them.
 
There is a sample in the SDK depending on where you placed on your system C:\ObjectARX 2013\samples\dotNet has a FilerSample
 and that is all I found.
 
 
 
Of course since the documentation suc#s huge, old, wrinkly, veiny, herpes infected balls and I got irritated and quit.
 
I think you can just override
WriteSoftOwnershipId
WriteSoftPointerId
WriteHardOwnershipId
WriteHardPointerId
 
and do whatever you need with results.

TheMaster

  • Guest
Re: DrawingCompare - DwgFiler
« Reply #11 on: December 24, 2012, 03:03:00 AM »
Where can I read detailed info about the DwgFiler class?

In Visual Studio, declare a variable of type DwgFiler.

Right click on the variable and choose Goto Definition.

Visual Studio opens a file showing the declaration of the class (from reflection)

Notice the [Wrapper("AcDbDwgFiler")] attribute applied to the class.

The string in the wrapper attribute is the name of the native ObjectARX class that is wrapped by the managed object.

Open the native ObjectARX documentation and search for AcDbDwgFiler

In most cases, the only detailed information for a managed type that wraps a native ObjectARX class, is the native ObjectARX docs, and the instructions above can be used to find out what the wrapped native class is.

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: DrawingCompare - DwgFiler
« Reply #12 on: December 24, 2012, 03:05:14 AM »
Thank you

thenndral

  • Guest
Re: DrawingCompare - DwgFiler
« Reply #13 on: March 30, 2014, 10:53:42 PM »
Hello,

Thanks for this awesome compare drawing code.

I'm doing comparing drawing's project in C# with AutoCAD 2013. I need help to achieve my task successfully.

In this code, after comparing not equal will be change to another Layer name called "Not equal".
I need to modify some code as per my requirements.
let me explain,
In routine, If "Not Equal" Entity is Circle then I want to insert block[on/above the circle] from another file. for ex. say filename "Block_circle". If it is Line, filename "Block_Line" block have to insert on/above the line entity.

If "NewId" found, I want to Insert another Block say filename "Block_NewID".

Please check the attachement image to more easy to understand.In image red box is "Block".

Thanks in advance,
thenndral

thenndral

  • Guest
Re: DrawingCompare - DwgFiler
« Reply #14 on: April 01, 2014, 05:07:54 AM »
Hello,

I don't know how to make it.
I'm looking for someone's help.


Thanks in advance,
thenndral