コード例 #1
0
class Image(ModernGraphicEntity):
    __slots__ = ()
    TEMPLATE = ExtendedTags.from_text(_IMAGE_TPL)
    CLASS = ExtendedTags.from_text(_IMAGE_CLS)
    DXFATTRIBS = DXFAttributes(none_subclass, entity_subclass, image_subclass)
    # flags for IMAGE
    SHOW_IMAGE = 1
    SHOW_IMAGE_WHEN_NOT_ALIGNED = 2
    USE_CLIPPING_BOUNDARY = 4
    USE_TRANSPARENCY = 8

    def post_new_hook(self):
        self.reset_boundary_path()

    def set_boundary_path(self, vertices):
        vertices = list(vertices)
        if len(vertices) > 2 and vertices[-1] != vertices[0]:
            vertices.append(vertices[0])  # close path, else AutoCAD crashes
        self._set_path_tags(vertices)
        self.set_flag_state(self.USE_CLIPPING_BOUNDARY, state=True)
        self.dxf.clipping = 1
        self.dxf.clipping_boundary_type = 1 if len(vertices) < 3 else 2

    def _set_path_tags(self, vertices):
        boundary = [DXFVertex(14, value) for value in vertices]
        subclasstags = Tags(tag for tag in self.tags.subclasses[2]
                            if tag.code != 14)
        subclasstags.extend(boundary)
        self.tags.subclasses[2] = subclasstags
        self.dxf.count_boundary_points = len(vertices)

    def reset_boundary_path(self):
        lower_left_corner = (-.5, -.5)
        upper_right_corner = Vector(self.dxf.image_size) + lower_left_corner
        self._set_path_tags([lower_left_corner, upper_right_corner[:2]])
        self.set_flag_state(Image.USE_CLIPPING_BOUNDARY, state=False)
        self.dxf.clipping = 0
        self.dxf.clipping_boundary_type = 1

    def get_boundary_path(self):
        image_subclass = self.tags.subclasses[2]
        return [tag.value for tag in image_subclass if tag.code == 14]

    def get_image_def(self):
        return self.dxffactory.wrap_handle(self.dxf.image_def)

    def destroy(self):
        super(Image, self).destroy()
        # remove rectors
        image_def = self.get_image_def()
        reactor_handle = self.get_dxf_attrib('image_def_reactor', None)
        if reactor_handle is None:
            return
        image_def.remove_reactor_handle(reactor_handle)
        if self.drawing is not None:
            reactor = self.dxffactory.wrap_handle(reactor_handle)
            self.drawing.objects.delete_entity(reactor)
コード例 #2
0
class ImageDefReactor(DXFEntity):
    TEMPLATE = ExtendedTags.from_text(_IMAGE_DEF_REACTOR_TPL)
    CLASS = ExtendedTags.from_text(_IMAGE_DEF_REACTOR_CLS)
    DXFATTRIBS = DXFAttributes(
        none_subclass,
        DefSubclass(
            'AcDbRasterImageDef',
            {
                'image': DXFAttr(330),  # handle to image
            }))
コード例 #3
0
class PdfDefinition(DXFEntity):
    __slots__ = ()
    TEMPLATE = ExtendedTags.from_text(_PDF_DEF_TPL)
    CLASS = ExtendedTags.from_text(_PDF_DEF_CLS)
    DXFATTRIBS = DXFAttributes(none_subclass, underlay_def_subclass)

    @property
    def entity_name(self):
        return self.dxftype()[:3] + "UNDERLAY"

    def post_new_hook(self):
        self.set_reactors([self.dxf.owner])
コード例 #4
0
class RasterVariables(DXFEntity):
    TEMPLATE = ExtendedTags.from_text(_RASTER_VARIABLES_TPL)
    CLASS = ExtendedTags.from_text(_RASTER_VARIABLES_CLS)
    DXFATTRIBS = DXFAttributes(
        none_subclass,
        DefSubclass('AcDbRasterVariables', {
            'version': DXFAttr(90, default=0),
            'frame': DXFAttr(70, default=0),  # 0 = no frame; 1= show frame
            'quality': DXFAttr(71, default=1),  # 0=draft; 1=high
            'units': DXFAttr(72, default=3),  # 0 = None; 1 = mm; 2 = cm 3 = m; 4 = km; 5 = in 6 = ft; 7 = yd; 8 = mi
        }),
    )
コード例 #5
0
class Linetype(DXFEntity):
    __slots__ = ()
    TEMPLATE = ExtendedTags.from_text(_LTYPETEMPLATE)
    DXFATTRIBS = DXFAttributes(
        DefSubclass(
            None, {
                'handle': DXFAttr(5),
                'name': DXFAttr(2),
                'description': DXFAttr(3),
                'length': DXFAttr(40),
                'items': DXFAttr(73),
            }))

    @classmethod
    def new(cls,
            handle: str,
            dxfattribs: dict = None,
            dxffactory: 'DXFFactoryType' = None) -> DXFEntity:
        if dxfattribs is not None:
            pattern = dxfattribs.pop('pattern', [0.0])
            length = dxfattribs.pop('length', 0.)
        else:
            pattern = [0.0]
            length = 0.
        entity = super(Linetype, cls).new(handle, dxfattribs, dxffactory)
        entity._setup_pattern(pattern, length)
        return entity

    def _setup_pattern(self, pattern: Sequence[float], length: float) -> None:
        # length parameter is required for complex line types
        # pattern: [2.0, 1.25, -0.25, 0.25, -0.25] - 1. element is total pattern length
        # pattern elements: >0 line, <0 gap, =0 point
        self.tags.noclass.append(DXFTag(73, len(pattern) - 1))
        self.tags.noclass.append(DXFTag(40, float(pattern[0])))
        self.tags.noclass.extend((DXFTag(49, float(p)) for p in pattern[1:]))
コード例 #6
0
ファイル: solid3d.py プロジェクト: soldocode/ezdxf
class Body(ModernGraphicEntity):
    __slots__ = ()
    TEMPLATE = ExtendedTags.from_text(_BODY_TPL)
    DXFATTRIBS = DXFAttributes(none_subclass, entity_subclass,
                               modeler_geometry_subclass)

    def get_acis_data(self):
        modeler_geometry = self.tags.subclasses[2]
        text_lines = convert_tags_to_text_lines(tag for tag in modeler_geometry
                                                if tag.code in (1, 3))
        return crypt.decode(text_lines)

    def set_acis_data(self, text_lines):
        def cleanup(lines):
            for line in lines:
                yield line.rstrip().replace('\n', '')

        modeler_geometry = self.tags.subclasses[2]
        # remove existing text
        modeler_geometry[:] = (tag for tag in modeler_geometry
                               if tag.code not in (1, 3))
        modeler_geometry.extend(
            convert_text_lines_to_tags(crypt.encode(cleanup(text_lines))))

    @contextmanager
    def edit_data(self):
        data = ModelerGeometryData(self)
        yield data
        self.set_acis_data(data.text_lines)
コード例 #7
0
 def test_set_flag_state(self):
     tags = ExtendedTags.from_text("70\n7\n10\n1.0\n20\n2.0\n30\n3.0\n")
     point = PointAccessor(tags)
     point.set_flag_state(1, state=False, name='flags')
     assert point.dxf.flags == 6
     point.set_flag_state(1, state=True, name='flags')
     assert point.dxf.flags == 7
コード例 #8
0
def test_packed_points_to_dxf_tags():
    tags = ExtendedTags.from_text(LWPOLYLINE1)
    packed_points = LWPolylinePoints.from_tags(tags)
    tags = list(packed_points.dxftags())
    assert len(tags) == 2  # just the points
    assert tags[0] == (10, (-.5, -.5))
    assert tags[1] == (10, (.5, .5))
コード例 #9
0
 def test_get_flag_state(self):
     tags = ExtendedTags.from_text("70\n7\n10\n1.0\n20\n2.0\n30\n3.0\n")
     point = PointAccessor(tags)
     assert point.get_flag_state(1, name='flags') is True
     assert point.get_flag_state(2) is True
     assert point.get_flag_state(4) is True
     assert point.get_flag_state(16) is False
コード例 #10
0
 def test_callback(self):
     tags = ExtendedTags.from_text("10\n1.0\n20\n2.0\n30\n3.0\n")
     point = PointAccessor(tags)
     assert point.dxf.counter == 0
     point.dxf.counter = 7
     assert point.dxf.counter == 7
     assert point.has_dxf_default_value('counter') is False
コード例 #11
0
 def test_error_set_point_with_wrong_axis_count(self):
     tags = ExtendedTags.from_text("13\n1.0\n23\n2.0\n40\n0.0\n")
     point = PointAccessor(tags)
     with pytest.raises(DXFValueError):
         point.dxf.flex = (3., 4., 5., 6.)
     with pytest.raises(DXFValueError):
         point.dxf.flex = (3., )
コード例 #12
0
ファイル: test_105_xdata.py プロジェクト: Rahulghuge94/ezdxf
def test_safe_init():
    tags = ExtendedTags.from_text("""0
DXFENTITY
1001
MOZMAN
1000
DataStr1
1000
DataStr2
1007
XXX
1040
3.14
1001
ACAD
1000
AutoDesk
1000
Revit""")

    xdata = XData.safe_init(tags.xdata)
    data = xdata.get("MOZMAN")
    assert (any(tag.code == 1007 for tag in data) is
            False), "invalid group code 1007 should be removed"
    assert "ACAD" in xdata
コード例 #13
0
class Linetype(legacy.Linetype):
    __slots__ = ()
    TEMPLATE = ExtendedTags.from_text(_LTYPETEMPLATE)
    DXFATTRIBS = DXFAttributes(none_subclass, symbol_subclass, linetype_subclass)

    def _setup_pattern(self, pattern, length):
        complex_line_type = True if isstring(pattern) else False
        if complex_line_type:  # a .lin like line type definition string
            self._setup_complex_pattern(pattern, length)
        else:
            # pattern: [2.0, 1.25, -0.25, 0.25, -0.25] - 1. element is total pattern length
            # pattern elements: >0 line, <0 gap, =0 point
            subclass = self.tags.get_subclass('AcDbLinetypeTableRecord')
            subclass.append(DXFTag(73, len(pattern) - 1))
            subclass.append(DXFTag(40, float(pattern[0])))
            for element in pattern[1:]:
                subclass.append(DXFTag(49, float(element)))
                subclass.append(DXFTag(74, 0))

    def _setup_complex_pattern(self, pattern, length):
        tokens = lin_compiler(pattern)
        subclass = self.tags.get_subclass('AcDbLinetypeTableRecord')
        subclass.append(DXFTag(73, 0))  # temp length of 0
        subclass.append(DXFTag(40, length))
        count = 0
        for token in tokens:
            if isinstance(token, DXFTag):
                if subclass[-1].code == 49:  # useless 74 only after 49 :))
                    subclass.append(DXFTag(74, 0))
                subclass.append(token)
                count += 1
            else:  # TEXT or SHAPE
                subclass.extend(token.complex_ltype_tags(self.drawing))
        subclass.append(DXFTag(74, 0))  # useless 74 at the end :))
        subclass.update(DXFTag(73, count))
コード例 #14
0
ファイル: graphics.py プロジェクト: soldocode/ezdxf
class Line(GraphicEntity):
    __slots__ = ()
    TEMPLATE = ExtendedTags.from_text(_LINE_TPL)
    DXFATTRIBS = make_attribs({
        'start': DXFAttr(10, xtype='Point2D/3D'),
        'end': DXFAttr(11, xtype='Point2D/3D'),
    })
コード例 #15
0
ファイル: graphics.py プロジェクト: soldocode/ezdxf
class Circle(GraphicEntity):
    __slots__ = ()
    TEMPLATE = ExtendedTags.from_text(_CIRCLE_TPL)
    DXFATTRIBS = make_attribs({
        'center': DXFAttr(10, xtype='Point2D/3D'),
        'radius': DXFAttr(40),
    })
コード例 #16
0
 def test_set_flag_state_none_existing_flags(self):
     tags = ExtendedTags.from_text("10\n1.0\n20\n2.0\n30\n3.0\n")
     point = PointAccessor(tags)
     point.set_flag_state(1, state=True, name='flags')
     assert point.dxf.flags == 1
     with pytest.raises(DXFAttributeError):
         point.set_flag_state(1, state=True, name='plot_flags')
コード例 #17
0
ファイル: mtext.py プロジェクト: soldocode/ezdxf
class MText(ModernGraphicEntity
            ):  # MTEXT will be extended in DXF version AC1021 (ACAD 2007)
    __slots__ = ()
    TEMPLATE = ExtendedTags.from_text(_MTEXT_TPL)
    DXFATTRIBS = DXFAttributes(none_subclass, entity_subclass, mtext_subclass)

    def get_text(self):
        tags = self.tags.get_subclass('AcDbMText')
        tail = ""
        parts = []
        for tag in tags:
            if tag.code == 1:
                tail = tag.value
            if tag.code == 3:
                parts.append(tag.value)
        parts.append(tail)
        return "".join(parts)

    def set_text(self, text):
        tags = self.tags.get_subclass('AcDbMText')
        tags.remove_tags(codes=(1, 3))
        str_chunks = split_string_in_chunks(text, size=250)
        if len(str_chunks) == 0:
            str_chunks.append("")
        while len(str_chunks) > 1:
            tags.append(DXFTag(3, str_chunks.pop(0)))
        tags.append(DXFTag(1, str_chunks[0]))
        return self

    def get_rotation(self):
        try:
            vector = self.dxf.text_direction
        except DXFValueError:
            rotation = self.get_dxf_attrib('rotation', 0.0)
        else:
            radians = math.atan2(vector[1], vector[0])  # ignores z-axis
            rotation = math.degrees(radians)
        return rotation

    def set_rotation(self, angle):
        del self.dxf.text_direction  # *text_direction* has higher priority than *rotation*, therefore delete it
        self.dxf.rotation = angle
        return self

    def set_location(self, insert, rotation=None, attachment_point=None):
        self.dxf.insert = Vector(insert)
        if rotation is not None:
            self.set_rotation(rotation)
        if attachment_point is not None:
            self.dxf.attachment_point = attachment_point
        return self

    @contextmanager
    def edit_data(self):
        buffer = MTextData(self.get_text())
        yield buffer
        self.set_text(buffer.text)

    buffer = edit_data  # alias
コード例 #18
0
class Layer(DXFEntity):
    __slots__ = ()
    TEMPLATE = ExtendedTags.from_text(_LAYERTEMPLATE)
    DXFATTRIBS = DXFAttributes(
        DefSubclass(
            None,
            {
                'handle': DXFAttr(5),
                'name': DXFAttr(2),
                'flags': DXFAttr(70),
                'color': DXFAttr(62),  # dxf color index, if < 0 layer is off
                'linetype': DXFAttr(6),
            }))
    FROZEN = 0b00000001
    THAW = 0b11111110
    LOCK = 0b00000100
    UNLOCK = 0b11111011

    def post_new_hook(self) -> None:
        if not is_valid_layer_name(self.dxf.name):
            raise DXFInvalidLayerName("Invalid layer name '{}'".format(
                self.dxf.name))

    def is_frozen(self) -> bool:
        return self.dxf.flags & Layer.FROZEN > 0

    def freeze(self) -> None:
        self.dxf.flags = self.dxf.flags | Layer.FROZEN

    def thaw(self) -> None:
        self.dxf.flags = self.dxf.flags & Layer.THAW

    def is_locked(self) -> bool:
        return self.dxf.flags & Layer.LOCK > 0

    def lock(self) -> None:
        self.dxf.flags = self.dxf.flags | Layer.LOCK

    def unlock(self) -> None:
        self.dxf.flags = self.dxf.flags & Layer.UNLOCK

    def is_off(self) -> bool:
        return self.dxf.color < 0

    def is_on(self) -> bool:
        return not self.is_off()

    def on(self) -> None:
        self.dxf.color = abs(self.dxf.color)

    def off(self) -> None:
        self.dxf.color = -abs(self.dxf.color)

    def get_color(self) -> int:
        return abs(self.dxf.color)

    def set_color(self, color: int) -> None:
        color = abs(color) if self.is_on() else -abs(color)
        self.dxf.color = color
コード例 #19
0
 def test_set_2d_point(self):
     point = PointAccessor(
         ExtendedTags.from_text("11\n1.0\n21\n2.0\n40\n3.0\n"))
     point.dxf.flat = (4, 5)
     assert 2 == len(
         point.tags.noclass
     ), 'points represented by just one tag since v0.6 (code, (x, y[, z]))'
     assert (4., 5.) == point.dxf.flat
コード例 #20
0
 def test_set_point(self):
     tags = ExtendedTags.from_text("10\n1.0\n20\n2.0\n30\n3.0\n")
     point = PointAccessor(tags)
     point.dxf.point = (7, 8, 9)
     assert 1 == len(
         tags.noclass
     ), 'points represented by just one tag since v0.6 (code, (x, y[, z]))'
     assert (7., 8., 9.) == point.dxf.point
コード例 #21
0
def test_vertex_array_to_dxf_tags():
    tags = ExtendedTags.from_text(SPLINE)
    vertices = VertexArray.from_tags(tags.get_subclass('AcDbSpline'))
    tags = list(vertices.dxftags())
    assert len(tags) == 7
    assert tags[0] == (10, (0., 0., 0.))
    assert tags[1] == (10, (10., 10., 10.))
    assert tags[-1] == (10, (60., 60., 60.))
コード例 #22
0
ファイル: graphics.py プロジェクト: soldocode/ezdxf
class SeqEnd(GraphicEntity):
    __slots__ = ()
    TEMPLATE = ExtendedTags.from_text("  0\nSEQEND\n  5\n0\n")
    DXFATTRIBS = DXFAttributes(
        DefSubclass(None, {
            'handle': DXFAttr(5),
            'paperspace': DXFAttr(67, default=0),
        }))
コード例 #23
0
 def test_set_2d_point_at_existing_3d_point(self):
     tags = ExtendedTags.from_text("13\n1.0\n23\n2.0\n33\n3.0\n")
     point = PointAccessor(tags)
     point.dxf.flex = (3., 4.)
     assert 1 == len(
         tags.noclass
     ), 'points represented by just one tag since v0.6 (code, (x, y[, z]))'
     assert (3., 4.) == point.dxf.flex
コード例 #24
0
def test_vertex_array_to_dxf_tags():
    tags = ExtendedTags.from_text(SPLINE)
    vertices = VertexArray.from_tags(tags.get_subclass('AcDbSpline'))
    tags = TagCollector.dxftags(vertices)
    assert len(tags) == 7 * 3
    assert tags[0] == (10, 0.)
    assert tags[3] == (10, 10.)
    assert tags[-1] == (30, 60.)
コード例 #25
0
def test_legacy_mode():
    """Legacy mode does the same job as filter_subclass_markers()."""
    tags = ExtendedTags.from_text(LEICA_DISTO_TAGS, legacy=True)
    assert 9 == len(tags.noclass)
    assert 1 == len(tags.subclasses)
    assert tags.noclass[0] == (0, "LINE")
    assert tags.noclass[1] == (8, "LEICA_DISTO_3D")
    assert tags.noclass[-1] == (210, (0, 0, 1))
コード例 #26
0
 def test_getdxfattr_no_DXF_default_value_at_wrong_dxf_version(self):
     tags = ExtendedTags.from_text("10\n1.0\n20\n2.0\n30\n3.0\n")
     point = PointAccessor(tags)
     # just_AC1015 has a DXF default value, but the drawing has an insufficient DXF version
     with pytest.raises(DXFValueError):
         point.get_dxf_attrib('just_AC1015')
         # except the USER defined default value
         assert point.get_dxf_attrib('just_AC1015', 17) == 17
コード例 #27
0
class Viewport(ModernGraphicEntity):
    __slots__ = ()
    TEMPLATE = ExtendedTags.from_text(_VIEWPORT_TPL)
    DXFATTRIBS = DXFAttributes(none_subclass, entity_subclass, viewport_subclass)
    viewport_id = 2  # notes to id:
    # The id of the first viewport has to be 1, which is the definition of
    # paper space. For the following viewports it seems only important, that
    # the id is greater than 1.

    @property
    def AcDbViewport(self)->'Tags':
        return self.tags.subclasses[2]

    def get_next_viewport_id(self) -> int:
        current_id = Viewport.viewport_id
        Viewport.viewport_id += 1
        return current_id

    def get_frozen_layer_handles(self) -> Iterable[str]:
        """
        Returns generator of layer handels.

        """
        return (tag.value for tag in self.AcDbViewport if tag.code == 331)

    def get_frozen_layer_entities(self) -> Iterable['Layer']:
        """
        Returns generator of Layer() objects.

        """
        if self.drawing is None:
            raise DXFAttributeError("'drawing attribute is None, can not build DXF entities.")
        wrapper = self.dxffactory.wrap_handle
        return (wrapper(handle) for handle in self.get_frozen_layer_handles())

    def set_frozen_layers(self, layers: Iterable[Union[str, 'Layer']]) -> None:
        """
        Set frozen layers for this viewport.

        Args:
            layers: list or generator of layer handles or Layer() objects.

        """
        def layer_handles():
            for layer in layers:
                if hasattr(layer, 'dxf'):
                    yield layer.dxf.handle
                else:
                    yield layer

        self.AcDbViewport.remove_tags([331])  # remove existing frozen layer tags
        frozen_layer_tags = [DXFTag(331, handle) for handle in layer_handles()]
        try:  # insert frozen layer tags in front of the flags-tag
            # try to create order like in the DXF standard, because order is sometimes important
            insert_pos = self.AcDbViewport.tag_index(90)
            self.AcDbViewport[insert_pos:insert_pos] = frozen_layer_tags
        except DXFValueError:  # flags-tag not found, just append frozen layer tags
            self.AcDbViewport.extend(frozen_layer_tags)
コード例 #28
0
class AppID(DXFEntity):
    __slots__ = ()
    TEMPLATE = ExtendedTags.from_text(_APPIDTEMPLATE)
    DXFATTRIBS = DXFAttributes(
        DefSubclass(None, {
            'handle': DXFAttr(5),
            'name': DXFAttr(2),
            'flags': DXFAttr(70),
        }))
コード例 #29
0
ファイル: graphics.py プロジェクト: soldocode/ezdxf
class Arc(GraphicEntity):
    __slots__ = ()
    TEMPLATE = ExtendedTags.from_text(_ARC_TPL)
    DXFATTRIBS = make_attribs({
        'center': DXFAttr(10, xtype='Point2D/3D'),
        'radius': DXFAttr(40),
        'start_angle': DXFAttr(50),
        'end_angle': DXFAttr(51),
    })
コード例 #30
0
ファイル: test_114_factory.py プロジェクト: yening2020/ezdxf
def test_factory_load():
    tags = ExtendedTags.from_text(POINT)
    e = factory.load(tags)
    assert e.dxftype() == 'POINT'
    assert e.doc is None
    assert e.dxf.handle == 'FEFE'
    assert e.dxf.owner is None
    assert e.is_alive is True
    assert e.is_virtual is True