Ejemplo n.º 1
0
def test_three_polygons_from_one_hatch():
    hatch = factory.new('HATCH')
    paths = hatch.paths
    paths.add_polyline_path(square(1), flags=1)
    paths.add_polyline_path(translate(square(1), (3, 1)), flags=1)
    paths.add_polyline_path(translate(square(1), (6, 2)), flags=1)
    mapping = geo.proxy(hatch).__geo_interface__
    assert mapping['type'] == 'MultiPolygon'
    assert len(mapping['coordinates']) == 3
Ejemplo n.º 2
0
def test_polygon_from_hatch_hole_in_hole():
    hatch = factory.new('HATCH')
    paths = hatch.paths
    paths.add_polyline_path(square(10), flags=1)
    paths.add_polyline_path(translate(square(8), (1, 1)), flags=0)
    paths.add_polyline_path(translate(square(6), (2, 2)), flags=0)
    mapping = geo.proxy(hatch).__geo_interface__
    assert mapping['type'] == 'Polygon'
    assert len(mapping['coordinates']) == 2, 'inner hole should be removed'

    mapping = geo.proxy(hatch, force_line_string=True).__geo_interface__
    assert mapping['type'] == 'MultiLineString'
    assert len(mapping['coordinates']) == 3, 'inner hole should not be removed'
Ejemplo n.º 3
0
def test_polygon_from_hatch_hole_in_hole():
    hatch = factory.new("HATCH")
    paths = hatch.paths
    paths.add_polyline_path(square(10), flags=1)
    paths.add_polyline_path(translate(square(8), (1, 1)), flags=0)
    paths.add_polyline_path(translate(square(6), (2, 2)), flags=0)
    mapping = geo.proxy(hatch).__geo_interface__
    assert mapping["type"] == "Polygon"
    assert len(mapping["coordinates"]) == 2, "inner hole should be removed"

    mapping = geo.proxy(hatch, force_line_string=True).__geo_interface__
    assert mapping["type"] == "MultiLineString"
    assert len(mapping["coordinates"]) == 3, "inner hole should not be removed"
Ejemplo n.º 4
0
def test_valid_hatch():
    hatch = factory.new('HATCH')
    paths = hatch.paths
    paths.add_polyline_path(square(10), flags=const.BOUNDARY_PATH_EXTERNAL)
    paths.add_polyline_path(translate(square(3), (1, 1)),
                            flags=const.BOUNDARY_PATH_DEFAULT)
    paths.add_polyline_path(translate(square(3), (5, 1)),
                            flags=const.BOUNDARY_PATH_DEFAULT)
    p = geo.proxy(hatch)
    polygon = shapely_geometry.shape(p)
    assert polygon.is_valid is True

    p.filter(validate)
    assert p.root != {}
Ejemplo n.º 5
0
def test_invalid_hatch_with_intersecting_holes():
    hatch = factory.new('HATCH')
    paths = hatch.paths
    paths.add_polyline_path(square(10),
                            flags=const.BOUNDARY_PATH_EXTERNAL)
    paths.add_polyline_path(translate(square(3), (1, 1)),
                            flags=const.BOUNDARY_PATH_DEFAULT)
    paths.add_polyline_path(translate(square(3), (2, 2)),
                            flags=const.BOUNDARY_PATH_DEFAULT)
    p = geo.proxy(hatch)
    polygon = shapely_geometry.shape(p)
    assert polygon.is_valid is False

    p.filter(validate)
    assert p.root == {}
Ejemplo n.º 6
0
def test_resolved_hatch_with_intersecting_holes():
    hatch = factory.new('HATCH')
    paths = hatch.paths
    paths.add_polyline_path(square(10), flags=const.BOUNDARY_PATH_EXTERNAL)
    paths.add_polyline_path(translate(square(3), (1, 1)),
                            flags=const.BOUNDARY_PATH_DEFAULT)
    paths.add_polyline_path(translate(square(3), (2, 2)),
                            flags=const.BOUNDARY_PATH_DEFAULT)
    p = geo.proxy(hatch)
    # Overlapping holes already resolved by fast_bbox_detection()
    polygon = shapely_geometry.shape(p)
    assert polygon.is_valid is True

    p.filter(validate)
    assert p.root['type'] == 'Polygon'
    assert len(p.root['coordinates']) == 2
 def test_intersecting_squares(self):
     square1 = forms.close_polygon(forms.square(2.0))
     square2 = forms.translate(square1, (1, 1))
     res = intersect_polylines_2d(Vec2.list(square1), Vec2.list(square2))
     assert len(res) == 2
     res.sort()
     assert res[0].isclose(Vec2(1, 2))
     assert res[1].isclose(Vec2(2, 1))
def add_predefined_hatch_pattern(msp, cols, size, gap, scale):
    for index, name in enumerate(pattern.ISO_PATTERN.keys()):
        x = (index % cols) * (size + gap)
        y = (index // cols) * (size + gap)
        boundary = list(translate(square(size), (x, HEIGHT - y)))
        msp.add_lwpolyline(boundary, close=True, dxfattribs={"layer": "LINE"})
        hatch = msp.add_hatch(dxfattribs={"layer": "HATCH"})
        hatch.set_pattern_fill(name=name, scale=scale)
        hatch.paths.add_polyline_path(boundary, is_closed=True)
Ejemplo n.º 9
0
    def add_rectangle(self,
                      rectangle: Rectangle,
                      start_from_x: float = 0.0,
                      start_from_y: float = 0.0) -> None:
        # Rectangle with evenly spaced holes
        rect_coordinates = translate(box(rectangle.width, rectangle.height),
                                     (start_from_x, start_from_y))
        self.msp.add_lwpolyline(rect_coordinates,
                                close=True,
                                dxfattribs=self.attribs)

        space_minus_offsets_from_side = rectangle.width - (
            2 * rectangle.offset_from_side)
        space_remaining = space_minus_offsets_from_side - rectangle.holes_total_width
        if len(rectangle.holes) <= 1:
            raise ValueError("Need to have at least two holes")
        space_between_holes = space_remaining / (len(rectangle.holes) - 1)

        for i, hole in enumerate(rectangle.holes):
            hole_center_x = (start_from_x + rectangle.offset_from_side +
                             (i * hole.width +
                              (hole.width / 2)) + (i * space_between_holes))
            hole_center_y = (start_from_y + rectangle.offset_from_bottom +
                             (hole.height / 2))
            if isinstance(hole, Circle):
                self.msp.add_circle(
                    (hole_center_x, hole_center_y),
                    radius=hole.radius,
                    dxfattribs=self.attribs,
                )
            elif isinstance(hole, Slot):
                # TODO doesn't work correctly yet
                # TODO add lines connecting circles
                left_x = hole_center_x - (
                    (hole.length / 2) * math.cos(hole.angle))
                left_y = hole_center_y + (
                    (hole.length / 2) * math.sin(hole.angle))
                self.msp.add_circle(
                    (left_x, left_y),
                    radius=hole.radius,
                    dxfattribs=self.attribs,
                )
                right_x = hole_center_x + (
                    (hole.length / 2) * math.cos(hole.angle))
                right_y = hole_center_y - (
                    (hole.length / 2) * math.sin(hole.angle))
                self.msp.add_circle(
                    (right_x, right_y),
                    radius=hole.radius,
                    dxfattribs=self.attribs,
                )
Ejemplo n.º 10
0
def polylines(filename):
    with r12writer(filename) as r12:
        r12.add_polyline_2d(circle(8), color=1, closed=False)
        r12.add_polyline_2d(
            translate(circle(8), vec=(3, 0)), color=3, closed=True
        )
        r12.add_polyline_2d(
            [(0, 4), (4, 4, 1), (8, 4, 0, 0.2, 0.000001), (12, 4)],
            format="xybse",
            start_width=0.1,
            end_width=0.1,
            color=5,
        )
    print(f'saved as "{filename}".')
Ejemplo n.º 11
0
def solid_entities():
    lay = VirtualLayout()
    lay.add_solid(translate(square(1), (-10, -10)))
    lay.add_solid(translate(square(1), (10, 10)))
    return lay
Ejemplo n.º 12
0
def test_translate():
    p = [(1, 2, 3), (4, 5, 6)]
    r = list(translate(p, (3, 2, 1)))
    assert is_close_points(r[0], (4, 4, 4))
    assert is_close_points(r[1], (7, 7, 7))
 def test_squares_with_common_corner_vertex(self):
     square1 = forms.close_polygon(forms.square(2.0))
     square2 = forms.translate(square1, (2, 2))
     res = intersect_polylines_2d(Vec2.list(square1), Vec2.list(square2))
     assert len(res) == 1
     assert res[0].isclose(Vec2(2, 2))
import ezdxf
from ezdxf.render import forms

DIR = Path("~/Desktop/Outbox").expanduser()

doc = ezdxf.new(setup=True)
msp = doc.modelspace()

# Create a special DIMSTYLE for "vertical" centered measurement text:
dimstyle = doc.dimstyles.duplicate_entry("EZDXF", "ORD_CENTER")
dimstyle.dxf.dimtad = 0  # "vertical" centered measurement text

# Add a rectangle: width=4, height = 2.5, lower left corner is WCS(x=2, y=3),
# rotated about 30 degrees:
origin = Vec3(2, 3)
msp.add_lwpolyline(forms.translate(forms.rotate(forms.box(4, 2.5), 30),
                                   origin),
                   close=True)

# Define the rotated local render UCS.
# The origin is the lower-left corner of the rectangle and the axis are
# aligned to the rectangle edges:
# The y-axis "uy" is calculated automatically by the right-hand rule.
ucs = UCS(origin, ux=Vec3.from_deg_angle(30), uz=(0, 0, 1))

# Add a x-type ordinate DIMENSION with local feature locations:
# the origin is now the origin of the UCS, which is (0, 0) the default value of
# "origin" and the feature coordinates are located in the UCS:
msp.add_ordinate_x_dim(
    # lower left corner
    feature_location=(0, 0),  # feature location in the UCS
    offset=(0.25, -2),  # # leader with a "knee"
Ejemplo n.º 15
0
from pathlib import Path
from ezdxf.math import Vec3
import ezdxf
from ezdxf.render import forms

DIR = Path("~/Desktop/Outbox").expanduser()

# Use argument setup=True to setup the default dimension styles.
doc = ezdxf.new(setup=True)

# Add new entities to the modelspace:
msp = doc.modelspace()
# Add a rectangle: width=4, height = 2.5, lower left corner is WCS(x=2, y=3)
origin = Vec3(2, 3)
msp.add_lwpolyline(forms.translate(forms.box(4, 2.5), origin), close=True)

# Add a x-type ordinate DIMENSION with global feature locations:
msp.add_ordinate_x_dim(
    # lower left corner
    feature_location=origin + (0, 0),  # feature location in the WCS
    offset=(0, -2),  # end of leader, relative to the feature location
    origin=origin,
).render()
msp.add_ordinate_x_dim(
    # lower right corner
    feature_location=origin + (4, 0),  # feature location in the WCS
    offset=(0, -2),
    origin=origin,
).render()
Ejemplo n.º 16
0
doc = ezdxf.new()
doc.layers.new("FORMS", dxfattribs={"color": 1})
doc.layers.new("HATCHES")

msp = doc.modelspace()
attribs = {"layer": "FORMS"}

# Create DXF primitives:
msp.add_circle((2, 3), radius=2, dxfattribs=attribs)

# Ellipse with hole:
msp.add_ellipse((5, 0), major_axis=(3, 1), ratio=0.5, dxfattribs=attribs)
msp.add_circle((5, 0), radius=1.5, dxfattribs=attribs)

# Rectangle with a hole
rect = translate(box(3, 2), (3, 6))
msp.add_lwpolyline(rect, close=True, dxfattribs=attribs)
hole = translate(box(2, 1), (3.4, 6.4))
msp.add_lwpolyline(hole, close=True, dxfattribs=attribs)

# Convert entities to primitives
primitives = disassemble.to_primitives(msp)

# Collect paths from primitives:
paths = [p.path for p in primitives if p.path]

# Render this paths as HATCH entities
path.render_hatches(msp, paths, dxfattribs={"layer": "HATCHES", "color": 2})

doc.set_modelspace_vport(15, (4, 4))
doc.saveas(DIR / "hatches_from_entities.dxf")
Ejemplo n.º 17
0
def test_translate():
    p = [(1, 2, 3), (4, 5, 6)]
    r = list(translate(p, (3, 2, 1)))
    assert r[0].isclose((4, 4, 4))
    assert r[1].isclose((7, 7, 7))
Ejemplo n.º 18
0
#  Copyright (c) 2020, Manfred Moitzi
#  License: MIT License

import pytest
from ezdxf.render.forms import square, translate
from ezdxf.path import Path, nesting, from_vertices

EXTERIOR = list(translate(square(10), (-5, -5)))
EXT1_PATH = from_vertices(EXTERIOR)
EXT2_PATH = from_vertices(translate(EXTERIOR, (11, 0)))

CENTER_HOLE1 = list(translate(square(8), (-4, -4)))
CH1_PATH = from_vertices(CENTER_HOLE1)

CENTER_HOLE2 = list(translate(square(6), (-3, -3)))
CH2_PATH = from_vertices(CENTER_HOLE2)

LEFT_HOLE = list(translate(square(2.1), (-3, -1)))
LH_PATH = from_vertices(LEFT_HOLE)

RIGHT_HOLE = list(translate(square(2.0), (3, -1)))
RH_PATH = from_vertices(RIGHT_HOLE)

DETECTION_DATA = [
    pytest.param(
        # Each polygon is a list of paths
        [EXT1_PATH],
        [[EXT1_PATH]],
        id="1 path",
    ),
    pytest.param(