Beispiel #1
0
def update_extents(doc: "Drawing") -> BoundingBox:
    """Calculate the extents of the model space, update the HEADER variables
    $EXTMIN and $EXTMAX and returns the result as :class:`ezdxf.math.BoundingBox`.
    Note that this function uses the :mod:`ezdxf.bbox` module to calculate the
    extent of the model space. This module is not very fast and not very
    accurate for text and ignores all :term:`ACIS` based entities.

    The function updates only the values in the HEADER section, to zoom the
    active viewport to this extents, use this recipe::

        import ezdxf
        from ezdxf import zoom, appsettings

        doc = ezdxf.readfile("your.dxf")
        extents = appsettings.update_extents(doc)
        zoom.center(doc.modelspace(), extents.center, extents.size)

    .. seealso::

        - the :mod:`ezdxf.bbox` module to understand the limitations of the
          extent calculation
        - the :mod:`ezdxf.zoom` module

    """
    extents = bbox.extents(doc.modelspace(), flatten=0)
    doc.header[EXTMIN] = extents.extmin
    doc.header[EXTMAX] = extents.extmax
    return extents
Beispiel #2
0
def zoom_to_entities(layout: Layout, entities: Iterable[DXFEntity], factor):
    if layout.is_any_paperspace:  # filter main viewport
        main_viewport = layout.main_viewport()
        if main_viewport is not None:
            entities = (e for e in entities if e is not main_viewport)
    extents = bbox.extents(entities, flatten=0)
    if extents.has_data:
        center(layout, extents.center, extents.size * factor)
Beispiel #3
0
 def test_bbox_of_main_viewport(self, psp):
     psp.reset_main_viewport()
     vp = psp.main_viewport()
     box = bbox.extents([vp])
     assert box.has_data is True
     assert box.center == vp.dxf.center
     assert box.size.x == pytest.approx(vp.dxf.width)
     assert box.size.y == pytest.approx(vp.dxf.height)
def main(rows: int, cols: int):
    doc = ezdxf.new()
    msp = doc.modelspace()
    create_content(msp)

    # Detecting the drawing extents by ezdxf:
    # The bounding box cache can be reused for entity filtering.
    # This cache is a lightweight object, which is compatible to the pickle
    # module, DXF entities are referenced by handle strings. (multiprocessing!)
    cache = bbox.Cache()

    # The bounding box calculation can take along time for big DXF files!
    # If flatten=0 the bounding box calculation for curves (SPLINE, ELLIPSE, ...)
    # is based on the control points of the Path class, this is less precise but
    # can speed up the calculation and for this task is a precise bounding box
    # not required.
    # This has no impact on this example which uses only straight lines
    extents = bbox.extents(msp, cache=cache, flatten=0)

    ctx = RenderContext(doc)
    for tile, render_area in enumerate(render_areas(extents, (rows, cols))):
        # Setup drawing add-on:
        fig = plt.figure(dpi=DPI)
        ax = fig.add_axes([0, 0, 1, 1])
        out = MatplotlibBackend(ax)

        ax.set_xlim(render_area.extmin.x, render_area.extmax.x)
        ax.set_ylim(render_area.extmin.y, render_area.extmax.y)

        # Disable rendering of entities outside of the render area:
        def is_intersecting_render_area(entity):
            """Returns True if entity should be rendered. """
            entity_bbox = bbox.extents([entity], cache=cache, flatten=0)
            return render_area.has_intersection(entity_bbox)

        # Finalizing invokes auto-scaling!
        Frontend(ctx, out).draw_layout(msp,
                                       finalize=False,
                                       filter_func=is_intersecting_render_area)

        # Set output size in inches:
        # width = 6 inch x 300 dpi = 1800 px
        # height = 3 inch x 300 dpi = 900 px
        fig.set_size_inches(6, 3, forward=True)

        filename = f"tile-{tile:02d}.png"
        print(f'saving tile #{tile} to "{filename}"')
        fig.savefig(DIR / filename, dpi=DPI)
        plt.close(fig)
Beispiel #5
0
def test_cache_usage_with_uuids(points1):
    # Entities in VirtualLayouts have no handles:
    cache = bbox.Cache(uuid=True)
    for _ in range(10):
        bbox.extents(points1, cache=cache)
    assert cache.hits == 18
Beispiel #6
0
def test_extend(points1):
    box = bbox.extents(points1)
    assert box.extmin == (-1, -2, -3)
    assert box.extmax == (4, 5, 6)
Beispiel #7
0
def test_bbox_from_precise_flattening(circle):
    box = bbox.extents(circle, flatten=0.0001)
    assert box.extmin.isclose((-100, -100),
                              abs_tol=0.0001), "expected a very close result"
    assert box.extmax.isclose((+100, +100),
                              abs_tol=0.0001), "expected a very_close result"
Beispiel #8
0
def test_bbox_from_rough_flattening(circle):
    box = bbox.extents(circle, flatten=5)
    assert box.extmin != (-100, -100), "did not expect a precise result"
    assert box.extmax != (+100, +100), "did not expect a precise result"
Beispiel #9
0
def test_bbox_from_control_points(circle):
    box = bbox.extents(circle, flatten=0)
    assert box.extmin == (-100, -100)
    assert box.extmax == (+100, +100)
Beispiel #10
0
def get_hatches_bbox(text):
    hatches = text2path.make_hatches_from_entity(text)
    return bbox.extents(hatches, flatten=0)
 def is_intersecting_render_area(entity):
     """Returns True if entity should be rendered. """
     entity_bbox = bbox.extents([entity], cache=cache, flatten=0)
     return render_area.has_intersection(entity_bbox)
Beispiel #12
0
        except ezdxf.DXFStructureError:
            if args.verbose:
                print("Regular loading function failed, using recover mode.")
            t_start = time.perf_counter()
            doc, auditor = recover.readfile(name)
            t_read = time.perf_counter()
            t_audit = t_read
        if auditor.has_errors and args.verbose:
            print(f"Found {len(auditor.errors)} unrecoverable error(s).")
        if auditor.has_fixes and args.verbose:
            print(f"Fixed {len(auditor.fixes)} error(s).")

        ex_run = 0
        if args.extends:
            ex_start = time.perf_counter()
            extends = bbox.extents(doc.modelspace())
            ex_run = time.perf_counter() - t_start
            if args.verbose:
                extmin = doc.header.get("$EXTMIN")
                extmax = doc.header.get("$EXTMAX")
                if extmin is not None:
                    e1 = Vec3(extmin).round(3)
                    e2 = Vec3(extmax).round(3)
                    print(f"Header var $EXTMIN/$EXTMAX: {e1}; {e2}")
                if extends.has_data:
                    e1 = extends.extmin.round(3)
                    e2 = extends.extmax.round(3)
                    print(f"Calculated $EXTMIN/$EXTMAX: {e1}; {e2}")

        if args.verbose:
            print("Timing: ", end="")