Persisting Changes To DWG File

Persisting Changes To DWG File

jeremyperna7254
Contributor Contributor
367 Views
4 Replies
Message 1 of 5

Persisting Changes To DWG File

jeremyperna7254
Contributor
Contributor

I am developing a plugin that communicates with an ASP.NET WebApi to track the presence and position of certain block references within a drawing, and persists that data to a MySQL database in the cloud. The issue I have been trying to solve for weeks now is exactly when to fire the requests to the WebApi and persist the data to the MySQL database. Consider the following two scenarios to understand my dilemma.

 

- User places/moves/deletes a block reference into the current drawing. The user does not manually save the drawing and no autosave event occurs, but they click the "X" of the AutoCAD window to close the program. The "Would you like to save your pending changes?" dialog shows and they click "No".

- User places/moves/deletes a block reference into the current drawing. The user does not manually save the drawing and no autosave event occurs. Some error occurs that crashes AutoCAD. The user restarts AutoCAD but does not retrieve the backup drawing file and decides to use the version of the drawing that does not have the block that they just placed.

 

In both of these scenarios the block reference that I would like to track was inserted into/modified/deleted from the drawing, and then the user makes some choices that result in the current version of the drawing file not matching the list of changes that have been previously created by the user's actions in the drawing.

 

I have gone through multiple different strategies to attempt to cover my bases when tracking these block references, including the following.

 

- Send a request to the server whenever the block is inserted into/modified/deleted from the drawing, regardless of file save events.

- Create a queue for staged changes whenever blocks are added/modified/deleted, then send requests to the server when the drawing is saved (only event available was Database.SaveComplete which doesn't help with the dropping of pending changes)

- Subscribe to the Database events like ObjectAppended, ObjectModified, ObjectErased and send requests to the server when triggered.

 

No matter what I keep thinking of scenarios where the data in the drawing file can become different than the data in the cloud database. I am wondering if anyone here has done similar work with maintaining a cloud database that tracks the data within the user's local drawing files? Any suggestions are greatly appreciated. Maybe I just have to resign to developing a "sync" operation and indicator that tells the user the data between the server and the drawing don't match and have them choose to synchronize them?

0 Likes
Accepted solutions (1)
368 Views
4 Replies
Replies (4)
Message 2 of 5

ActivistInvestor
Mentor
Mentor

@jeremyperna7254 wrote:

 

- User places/moves/deletes a block reference into the current drawing. The user does not manually save the drawing and no autosave event occurs, but they click the "X" of the AutoCAD window to close the program. The "Would you like to save your pending changes?" dialog shows and they click "No".

- User places/moves/deletes a block reference into the current drawing. The user does not manually save the drawing and no autosave event occurs. Some error occurs that crashes AutoCAD. The user restarts AutoCAD but does not retrieve the backup drawing file and decides to use the version of the drawing that does not have the block that they just placed.

 

In both of these scenarios the block reference that I would like to track was inserted into/modified/deleted from the drawing, and then the user makes some choices that result in the current version of the drawing file not matching the list of changes that have been previously created by the user's actions in the drawing.

 

I have gone through multiple different strategies to attempt to cover my bases when tracking these block references, including the following.

 

- Send a request to the server whenever the block is inserted into/modified/deleted from the drawing, regardless of file save events.

- Create a queue for staged changes whenever blocks are added/modified/deleted, then send requests to the server when the drawing is saved (only event available was Database.SaveComplete which doesn't help with the dropping of pending changes)

- Subscribe to the Database events like ObjectAppended, ObjectModified, ObjectErased and send requests to the server when triggered.

 

No matter what I keep thinking of scenarios where the data in the drawing file can become different than the data in the cloud database. I am wondering if anyone here has done similar work with maintaining a cloud database that tracks the data within the user's local drawing files? Any suggestions are greatly appreciated. Maybe I just have to resign to developing a "sync" operation and indicator that tells the user the data between the server and the drawing don't match and have them choose to synchronize them?


 

You should look at a drawing file that's open in the Editor as being a copy of the DWG file that was opened, that is in a volatile state. Anything done could be discarded if the user chooses to simply close the drawing and answer no to the question of whether they want to save changes, and in that case, any synchronization done while the drawing was open would have to be rolled-back or discarded. Your post identifies some, but not all of the possible conditions that complicate what you're trying to do.

 

Within the editing session, the user can UNDO any change they made, possibly undoing everything done since they opened the drawing, which rolls the drawing back to the point when it was opened, and which could be before any number of saves occurred. If they do that, they could then close the drawing without saving, with the end result being that the DWG file is in state it has when last saved in the editor. 

 

So, what you really need to do is act on the .DWG file after it has been closed in the drawing editor (because it could have been saved any number of times, and then had more changes made to it that were subsequently discarded if the user closes without saving). Doing that would allow you to avoid multiple, incremental updates each time the file is saved.

 

I've seen various approaches to the actual implementation of this, and have used a few myself. One approach involves checking the file's timestamp and comparing it to the timestamp the file had when it was last synchronized with the external data source, and if the comparison indicates the file was modified after it was last synchronized, opening the file in AutoCAD Core Console; processing it; and exporting the data to the external data source. There are similar approaches that involve accessing the just-closed DWG file using Database.ReadDwgFile() and processing it that way, in the same AutoCAD session from which it was opened in. Some of the approaches I've seen involved using a daemon process or windows service that assumes the responsibility for synchronizing modified DWG files with external data sources, having a role that's not much different than a print-spooler.

 

In the case of the scenario where AutoCAD crashes and the drawing file is not recovered, comparing the file's timestamp to the timestamp it had when its data was last synchronized with the external data is all that needs to be done to determine if another synchronization is needed. Exactly how that post-processing/synchronization happens is an implementation detail, but what matters is that it does not happen while the DWG file is open in the drawing editor.

 

I guess what I'm trying to get across here is that trying to keep external data in sync with an opened DWG file that's being edited is essentially an immensely over-complicated exercise in futility, that can in some cases, resemble the proverbial dog chasing its own tail.

 

 

0 Likes
Message 3 of 5

norman.yuan
Mentor
Mentor
Accepted solution

Depending on how closely the backend need to get the latest changes in drawings, you would need to decide when the capture the changes. Capturing the data whenever it changes in opened drawing of an AutoCAD session would be the worst thing to do: you can can undo/abandon the changes at will.

 

You could do it whenever a drawing is to be saved/closed by handling Database.BeginSave, Document.BeginDocumentClose. Handling Database.BeginSave might be too much/unnecessary, because you can hit Ctrl+S at anytime and between the savings, the data change could be reversed.

 

You could also simply set up a batch process to run at given time/night to collect all the changes to update the backend;

 

If the drawing is managed by a document management system and has to be checked out to work with, the data changes in the drawing would only be considered committed changes when the drawing file is checked back in. Then, you would run a data extracting and backend updating against the document management system, not the checked-out drawing.

 

 

 

 

Norman Yuan

Drive CAD With Code

EESignature

0 Likes
Message 4 of 5

jeremyperna7254
Contributor
Contributor

It seems like one option is to persist the relevant data in the dwg file to my cloud database upon the Database.SaveComplete event. That way I know that the data in the current DWG file has been persisted to the file on the user's disk. My the purposes of my project I believe this is sufficient, unless people can think of scenarios where this would not be good enough.

0 Likes
Message 5 of 5

ActivistInvestor
Mentor
Mentor

@jeremyperna7254 wrote:

It seems like one option is to persist the relevant data in the dwg file to my cloud database upon the Database.SaveComplete event. That way I know that the data in the current DWG file has been persisted to the file on the user's disk. My the purposes of my project I believe this is sufficient, unless people can think of scenarios where this would not be good enough.


You can do that, but it can be redundant if the user saves frequently unless you track changes made to linked objects since the most-recent save, which might allow you to do an incremental update. 

 

Just keep in mind that even saves can be 'undone' and 'redone'.

0 Likes