libredwg icon indicating copy to clipboard operation
libredwg copied to clipboard

Issue with load_dwg example: AutoCAD reports "the drawing file requires recovery"

Open timoria21 opened this issue 8 months ago • 22 comments

Hello,

I've tested the dwgrewrite and load_dwg examples using the attached empty_v2000.dwg file.

  • dwgrewrite works fine.
  • load_dwg produces a new file that, when opened in AutoCAD, triggers the warning: "The drawing file requires recovery."

Could you check this behavior and let me know if there's a potential issue?

Thanks!

empty_v2000.zip


Tasks:

  • [ ] GH #1127
  • [ ] fix the "first entity" handle in the Model_Space BLOCK_HEADER
  • [ ] add "prev_entity”: [4,0,0,0], "next_entity": [4,0,0,0] to the added entity, change nolinks to 0

timoria21 avatar Mar 27 '25 09:03 timoria21

@timoria21 Heh, interesting. Nice simple example to fix.

michal-josef-spacek avatar Mar 30 '25 13:03 michal-josef-spacek

There is bad Template address in origin DWG file. a) Main header

section[4].number:         4 [RC] AcDb:Template
section[4].address:    21659 [RL]
section[4].size:           4 [RL]

b) Second header:

Template
sections[4].address: 21950 [BL 0]
sections[4].size: 88 [BL 0]
sections[5].nr: 5 [RCd 0]

@timoria21 What is creator app of the original DWG file? (From the header it is AutoCAD 2000i)

But this is not a problem with bad DWG file.

michal-josef-spacek avatar Mar 30 '25 13:03 michal-josef-spacek

The difference between (original and rewrite DWGs) AND (bad DWG) is in last_entity handle in model space block header: I don't know if this is a issue.

Original file:

Next object: 23 Handleoff: 0x5 [UMC] Offset: -1741 [MC] @18695
==========================================
Object number: 23/17, Size: 37 [MS], Type: 49 [BS], Address: 18697
Add table record BLOCK_HEADER [23] Decode table record BLOCK_HEADER
bitsize: 197 [RL] @3.2
 Hdlsize: 0x63, hdl_dat: @24.5 - @37.0 (37)
handle: 0.1.1F [H 5]
EED[0] size: 0 (end)
num_eed: 0
num_reactors: 0 [BL 0]
ownerhandle: (4.1.1) abs:1 [H 330]
xdicobjhandle: (3.0.0) abs:0 [H 360]
--common_size: 52
name: "*Model_Space" [T 2]
is_xref_ref: 1 [B 0]
is_xref_resolved: 0 [BS 0]
is_xref_dep: 0 [B 0]
xref: (5.0.0) abs:0 [H 0]
anonymous: 0 [B 0]
hasattrs: 0 [B 0]
blkisxref: 0 [B 0]
xrefoverlaid: 0 [B 0]
loaded_bit: 0 [B 0]
base_pt: (0, 0, 0) [3BD 10]
xref_pname: "" [T 1]
num_inserts: 0 [RC* 0]
description: "" [T 4]
preview_size: 0 [BL 0]
preview: "" [TF 0 310]
block_entity: (3.1.20) abs:32 [H 0]
first_entity: (4.0.0) abs:0 [H 0]
last_entity: (4.0.0) abs:0 [H 0]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
endblk_entity: (3.1.21) abs:33 [H 0]
layout: (5.1.22) abs:34 [H 340]
 padding: +3
 object_map{1F} = 23
 padding: 17/7 (3 bits)
crc: FE06 [RSx]
 check_CRC 18695-18734 = 39: FE06 == FE06

Bad file:

Next object: 23 Handleoff: 0x5 [UMC] Offset: 53 [MC] @18988
==========================================
Object number: 23/17, Size: 39 [MS], Type: 49 [BS], Address: 18990
Add table record BLOCK_HEADER [23] Decode table record BLOCK_HEADER
bitsize: 205 [RL] @3.2
 Hdlsize: 0x6B, hdl_dat: @25.5 - @39.0 (39)
handle: 0.1.1F [H 5]
EED[0] size: 0 (end)
num_eed: 0
num_reactors: 0 [BL 0]
ownerhandle: (4.1.1) abs:1 [H 330]
xdicobjhandle: (3.0.0) abs:0 [H 360]
--common_size: 52
name: "*Model_Space" [T 2]
is_xref_ref: 1 [B 0]
is_xref_resolved: 0 [BS 0]
is_xref_dep: 0 [B 0]
xref: (5.0.0) abs:0 [H 0]
anonymous: 0 [B 0]
hasattrs: 0 [B 0]
blkisxref: 0 [B 0]
xrefoverlaid: 0 [B 0]
loaded_bit: 0 [B 0]
base_pt: (0, 0, 0) [3BD 10]
xref_pname: "" [T 1]
num_inserts: 0 [RC* 0]
description: "" [T 4]
preview_size: 0 [BL 0]
preview: "" [TF 0 310]
block_entity: (3.1.20) abs:32 [H 0]
first_entity: (4.0.0) abs:0 [H 0]
last_entity: (4.1.72) abs:114 [H 0]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
endblk_entity: (3.1.21) abs:33 [H 0]
layout: (5.1.22) abs:34 [H 340]
 padding: +3
 object_map{1F} = 23
 padding: 10/0 (3 bits)
crc: 99CC [RSx]
 check_CRC 18988-19029 = 41: 99CC == 99CC

michal-josef-spacek avatar Mar 30 '25 14:03 michal-josef-spacek

Ahh. The last_entity is fine. But missing first_entity with the same value.

michal-josef-spacek avatar Mar 31 '25 09:03 michal-josef-spacek

@rurban There is code (https://github.com/LibreDWG/libredwg/blob/master/src/dwg_api.c#L23150)

else if (owner->fixedtype == DWG_TYPE_BLOCK_HEADER
               && !_owner->first_entity && !_owner->num_owned
               && !dwg_obj_is_subentity (obj))
        {
          BITCODE_H ref;
          _owner->first_entity = _owner->last_entity
              = dwg_add_handleref (dwg, 4, obj->handle.value, NULL);
          LOG_TRACE ("%s.{first,last}_entity = " FORMAT_REF "\n", owner->name,
                     ARGS_REF (_owner->first_entity));
          ref = dwg_add_handleref (dwg, 3, obj->handle.value, NULL);
          LOG_TRACE ("%s.entities[%d] = " FORMAT_REF "\n", owner->name,
                     _owner->num_owned, ARGS_REF (ref));
          PUSH_HV (_owner, num_owned, entities, ref)
          // ent->nolinks = 1;
          LOG_TRACE ("%s.num_owned = %u\n", owner->name, _owner->num_owned);
        }

When _owner->first_entity is set to 4.0.0, then not processed this block, which is expected.

michal-josef-spacek avatar Mar 31 '25 09:03 michal-josef-spacek

Hello, any news on this?

timoria21 avatar Apr 07 '25 12:04 timoria21

@timoria21 @rurban I have no idea about the concept of these things, I can't fix this by myself.

michal-josef-spacek avatar Apr 07 '25 13:04 michal-josef-spacek

Hi,

I compared Json of files created with dwgrewrite and load_dwg, and there are just a couple of lines that differ, but, I have no idea how to fix them. I've attached the JSON files in the hope that they’ll help identify the issue. Being able to create DWG files from scratch is really important, so I really hope a solution can be found.

load_dwg.json rewrite.json

timoria21 avatar Apr 11 '25 13:04 timoria21

Diff: diff load_dwg.json rewrite.json

659c659
<       "size": 39,
---
>       "size": 38,
678c678
<       "last_entity": [4,1,114,114],
---
>       "last_entity": [4,0,0,0],
1440,1474d1439
<     },
<     {
<       "entity": "TEXT",
<       "index": 45,
<       "type": 1,
<       "handle": [0,1,114],
<       "size": 125,
<       "bitsize": 954,
<       "_subclass": "AcDbEntity",
<       "layer": [5,1,16,16],
<       "preview_exists": 0,
<       "entmode": 2,
<       "nolinks": 1,
<       "color": 256,
<       "ltype_scale": 1.0,
<       "ltype_flags": 0,
<       "plotstyle_flags": 0,
<       "invisible": 0,
<       "linewt": 29,
<       "_subclass": "AcDbText",
<       "dataflags": 0,
<       "elevation": 0.0,
<       "ins_pt": [ 12.0, 9.0 ] ,
<       "alignment_pt": [ 0.0, 0.0 ] ,
<       "extrusion": [ 0.0, 0.0, 1.0 ] ,
<       "thickness": 0,
<       "oblique_angle": 0.0,
<       "rotation": 0.0,
<       "height": 0.2,
<       "width_factor": 0.0,
<       "text_value": "Last updated: 04/10/25 16:37:51",
<       "generation": 0,
<       "horiz_alignment": 2,
<       "vert_alignment": 0,
<       "style": [5,1,17,17]
1494c1459
<     "address": 21303,
---
>     "address": 21167,
1513,1514c1478,1479
<         "address": 20996,
<         "size": 254
---
>         "address": 20866,
>         "size": 248
1518c1483
<         "address": 21250,
---
>         "address": 21114,

Hm, interesting. This IMHO means that issue could be in TEXT entity.

michal-josef-spacek avatar Apr 11 '25 18:04 michal-josef-spacek

I don't think the issue is in the entity, or at least not in the entity type. I've added a Line (which I think is the simplest entity) instead of the Text, but the problems remain.

timoria21 avatar Apr 15 '25 08:04 timoria21

@timoria21 I see that encoding to DWG with text entity in AC1015 is different than from AutoCAD. dataflags = 0 vs dataflags > 0. As I understand that could be same in Line entity.

michal-josef-spacek avatar Apr 15 '25 08:04 michal-josef-spacek

I could create C code that tests these dataflags.

michal-josef-spacek avatar Apr 16 '25 13:04 michal-josef-spacek

This:

#include <dwg.h>
#include <dwg_api.h>
#include <stdio.h>

/* Main. */
int
main(int argc, char **argv) {
        Dwg_Data *dwg;
        static int tracelevel = 0;
        char *filename = "ex1.dwg";
        int ret;

        dwg = dwg_new_Document(
                R_2000,
                0, /* metric/iso */
                tracelevel
        );

        ret = dwg_write_file(filename, dwg);
        if (ret) {
                printf("Write status: %d\n", ret);
                return 1;
        }

        /* Free memory. */
        dwg_free(dwg);

        return 0;
}

produces DWG file which is bad

michal-josef-spacek avatar Apr 16 '25 15:04 michal-josef-spacek

I found this crazy situation: JSON 1: from_acad_2000-1.json.gz dwgwrite from_acad_2000-1.json creates DWG file which is incompatible with AutoCAD 2000

JSON 2: from_acad_2000-2.json.gz dwgwrite from_acad_2000-1.json creates DWG file which is compatible with AutoCAD 2000

Difference between:

> diff from_acad_2000-1.json from_acad_2000-2.json 
6c6
<     "zero_one_or_three": 0,
---
>     "zero_one_or_three": 1,

michal-josef-spacek avatar Apr 17 '25 12:04 michal-josef-spacek

When I set zero_one_or_three to 1 in defaults, there are issue still. :-/

michal-josef-spacek avatar Apr 17 '25 12:04 michal-josef-spacek

Seem that this zero_one_or_three flag is related to the presence of the thumbnail in the DWG file somehow.

michal-josef-spacek avatar Apr 17 '25 12:04 michal-josef-spacek

This PR (https://github.com/LibreDWG/libredwg/pull/1125) could fix the issue.

BTW: We need to remove hardcoded default handles.

michal-josef-spacek avatar Apr 22 '25 11:04 michal-josef-spacek

Heh, I know what is the problem of this issue.

@rurban There is no update of HANDSEED after adding of TEXT entity. The result of load_dwg is DWG file with the same value of HANDSEED as the handle of a TEXT entity.

michal-josef-spacek avatar Apr 22 '25 12:04 michal-josef-spacek

Yes, HANDSEED needs to be computed always

rurban avatar Apr 22 '25 13:04 rurban

I was able to create a valid file with the following manual fixes to the previously shared load_dwg.json

  • Increased the HANDSEED
  • fixed the "first entity" handle in the Model_Space BLOCK_HEADER
  • added "prev_entity”: [4,0,0,0], "next_entity": [4,0,0,0] to the Text entity
  • changed the value of "nolinks" to zero in the Text entity

The new fixed json is attached. I hope this helps to solve the problem.

load_dwg_fixed.json

timoria21 avatar May 08 '25 10:05 timoria21

@timoria21 Yes, thank you. This is the way how to detect issues without programming :-)

michal-josef-spacek avatar May 08 '25 10:05 michal-josef-spacek

  • added "prev_entity”: [4,0,0,0], "next_entity": [4,0,0,0] to the Text entity

I thought this was easier fixed by nolinks: 1, but apparently it is not

I'll have time soon to fix this linking issue

rurban avatar May 13 '25 11:05 rurban