ixmilia / dxf

MIT License
221 stars 67 forks source link

ImageDefinition of DXFImage inside Blocks is null #173

Closed SoReinhard closed 2 years ago

SoReinhard commented 2 years ago

Hi,

It seems like the ImageDefinition of any DXFImage inside a Block stays null after reading. If I explode the Block the ImageDefinition is properly assigned. I have attached an example with one dxf that has its image directly in the file entities and one that is inside a block.

ImageBlockIssue.zip

After some investigation I have traced the issue back to the binding of pointers after reading. I have implemented the following workaround in DXFPointer locally but I'm not confident that this is ultimately the right solution so i have not opened a PR.

private static void BindPointers(IDxfItemInternal item, Dictionary<DxfHandle, IDxfItemInternal> handleMap, HashSet<IDxfItemInternal> visitedItems, HashSet<IDxfItemInternal> visitedChildren)
        {
            if (visitedItems.Add(item))
            {
                // set initial owners
                SetChildOwners(item, visitedChildren);

                // set explicit owners
                foreach (var child in item.GetPointers())
                {
                    if (handleMap.ContainsKey(child.Handle))
                    {
                        child.Item = handleMap[child.Handle];
                        BindPointers((IDxfItemInternal)child.Item, handleMap, visitedItems, visitedChildren);
                        SetOwner((IDxfItemInternal)child.Item, item, isWriting: false);
                    }
                }
                foreach (var child in item.GetChildItems())
                {
                    if (child == null)
                        continue;

                    foreach (var pointer in child.GetPointers())
                    {
                        if (pointer == null)
                            continue;

                        if (handleMap.ContainsKey(pointer.Handle))
                        {
                            pointer.Item = handleMap[child.Handle];
                            BindPointers((IDxfItemInternal)pointer.Item, handleMap, visitedItems, visitedChildren);
                            SetOwner((IDxfItemInternal)pointer.Item, item, isWriting: false);
                        }
                    }
                }
            }
        }

Best Regards

brettfo commented 2 years ago

Brilliant!

This was a scenario I totally missed and your fix is exactly how it should be done. I've pushed commit 25e2986d746454b4828ad4ae30ba3c5444718318 to main with only a slight refactoring to your code. I also added your GitHub username in the commit message to give credit where credit is due.