question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Geometry.from_dxf can only ever import one shape

See original GitHub issue

Describe the bug When importing shapes from a clean/well-formed DXF file, only one shape is ever found.

To Reproduce Steps to reproduce the behaviour:

  1. Import shapes with Geometry.from_dxf()
  2. Notice that only one shape exists

Expected behaviour When working with a clean/well-formed DXF file, .from_dxf() should be able to import multiple shapes for analysis.

Additional context I have a clean DXF file with some closed polylines in it, and all other entities purged/removed. I can import this DXF into shapely. I can also import this file into the cad_to_shapely shim. In both cases, the multiple-shape geometry is preserved.

However, when I do the same via Geometry.from_dxf() only one shape ever comes back. Digging deeper into the code in from_dxf I found this:

my_dxf = c2s.dxf.DxfImporter(dxf_filepath)
my_dxf.process()
my_dxf.cleanup()

polygons = my_dxf.polygons
new_polygons = c2s.utils.find_holes(polygons)
if isinstance(new_polygons, MultiPolygon):
    return CompoundGeometry(new_polygons)
elif isinstance(new_polygons, Polygon):
    return Geometry(new_polygons)
else:
    print(f"No shapely.Polygon objects found in file: {dxf_filepath}")

Looking into find_holes, we find that this behavior is by design:

def find_holes(polygons : List[sg.Polygon]) -> sg.Polygon:
    """
    Construct single polygon from imported CAD goemetry. 
    Assumes there is only one parent shape (the one with the largest gross area.)
    Access external perimeter with *polygon.exterior*
    Access holes perimeter(s, if there are any) with *polygon.interiors*
    Returns:
        Shapely Polygon with holes 
    """
    for p in polygons:
        if p.interiors:
            return p

    #sort by areas, largest first.
    polygons.sort(key=lambda x: x.area, reverse=True)
    parent = polygons.pop(0)

    keepers = []
    for p in polygons:
        if p.within(parent):
            valid = True
            for q in polygons:
                if (p.intersects(q) or p.within(q)) and p is not q:
                    valid = False
           
            if valid: keepers.append(p)


    new = sg.Polygon(parent,holes=keepers)
    return new

So by using this utility function, sectionproperties can never support more than one shape in a DXF. This is not a “bug” in cad_to_shapely, per-se, as its the desired behavior, but by using this utility function, we’re throwing out data.

I went through the analogous process by hand, NOT throwing out polygons and manually made a CompoundGeometry object, and it worked:

from cad_to_shapely.dxf import DxfImporter
from shapely.geometry.multipolygon import MultiPolygon

doc = DxfImporter('polylines.dxf')
doc.process()
doc.cleanup()
polys = MultiPolygon(doc.polygons)

g = CompoundGeometry(polys)
g.create_mesh(mesh_sizes=[0.1])

(this showed a little thumbnail of an object in a Jupyter Notebook)

Issue Analytics

  • State:open
  • Created a year ago
  • Comments:16 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
aegis1980commented, Nov 1, 2022

I added in dev branch of cad_to_shapely utils.py a function filter_polygons that’ll return a list of inferred “topographical surfaces” from closed curves (shapely polygons with/without holes/both). This ought to address various quandaries bought up in this thread & others. Aim is to depreciate find_holes.

Got some bits and bobs to sort out, then will try and tie in with section-properties from_dxf/load_dxf and make pull request.

@robbievanleeuwen At moment section-properties load_dxf calls c2s.utils.find_holes. This island-finding stuff is kind of in hinterland “upstream” of section-properties and “downstream” of cad-to-shapely (why it in c2s.utils module)

Also some complications arise when you consider if user wants to import multiple sections from a single dxf (list of Geometry objects; I recall someone wanting to do that), or a single compound section (CompoundGeometry). I am going to aim at the latter in pull request on the grounds that if you want to import and analyse multiple sections user can sort it out ‘upstream’ in CAD package (multiple DXF files), or programmatically-by-yourself (somehow!)

1reaction
mfeifcommented, Sep 23, 2022

Importing hatches, regions and/or blocks (in cad to shapely, @mfeif Thanks for that) might be a way to go - not excited about implementing myself! feel free to do so!! Or recursively calling find_holes maybe, for those too lazy to so hatches/regions/blocks.

I’m not following about the hatches and so on.

I think using the logic in .find_holes iteratively, preserving multiple geometries (except those that are holes) makes closer sense. I might even be able to tackle that since you’ve already done the hard part of figuring out how to do it.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Creating complex shapes and importing them from .DXF ino ...
This just works for me and always comes in based on the origin point so make sure that 0,0 in AutoCAD is set...
Read more >
Importing objects from DXF files - SprutCAM 12 All lang User ...
Currently, only geometrical objects can be imported from DXF files. Object geometry has considerable affect on the machining technology, and such features, as ......
Read more >
Cadence PCB Import Export DXF - YouTube
Here we explore the Cadence PCB Import Export DXF. ... try restarting your device. Your browser can 't play this video.
Read more >
Import Graphics and RF Geometries Using DXF Files - YouTube
Your browser can 't play this video. Learn more. Switch camera.
Read more >
Importing DXF Files - RISA
Generally, you would read in a DXF file to create the geometry for a new structural model, ... Only beams that are fully...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found