Exemple #1
0
    def export_embedded_object(self, tagwriter: 'TagWriter'):
        dxf = self.dxf
        cols = self._columns

        tagwriter.write_tag2(101, 'Embedded Object')
        tagwriter.write_tag2(70, 1)  # unknown meaning
        tagwriter.write_tag(dxftag(10, dxf.text_direction))
        tagwriter.write_tag(dxftag(11, dxf.insert))
        tagwriter.write_tag2(40, dxf.width)  # repeated reference column width
        tagwriter.write_tag2(41, cols.defined_height)
        tagwriter.write_tag2(42, cols.total_width)
        tagwriter.write_tag2(43, cols.total_height)
        tagwriter.write_tag2(71, int(cols.column_type))

        if cols.has_dynamic_auto_height:
            count = 0
        else:
            count = cols.count
        tagwriter.write_tag2(72, count)

        tagwriter.write_tag2(44, cols.width)
        tagwriter.write_tag2(45, cols.gutter_width)
        tagwriter.write_tag2(73, int(cols.auto_height))
        tagwriter.write_tag2(74, int(cols.reversed_column_flow))
        for height in cols.heights:
            tagwriter.write_tag2(46, height)
Exemple #2
0
def test_fmt_dxf_tags():
    tags = [
        dxftag(1, 'TEXT'),
        dxftag(10, (1, 2, 3))
    ]
    code = "[{}]".format(''.join(_fmt_dxf_tags(tags)))
    r = eval(code, globals())
    assert r == tags
Exemple #3
0
 def add(self, appid: str, data: Iterable[Sequence]) -> None:
     data = Tags(dxftag(code, value) for code, value in data)
     appid = uniform_appid(appid)
     if data[0] != (APP_DATA_MARKER, appid):
         data.insert(0, dxftag(APP_DATA_MARKER, appid))
     if data[-1] != (APP_DATA_MARKER, '}'):
         data.append(dxftag(APP_DATA_MARKER, '}'))
     self.set(data)
Exemple #4
0
 def add(self, appid: str, data: Iterable[Sequence]) -> None:
     """Add application-defined tags for `appid`.
     Adds first tag (102, "{APPID") if not exist.
     Adds last tag (102, "}" if not exist.
     """
     data = Tags(dxftag(code, value) for code, value in data)
     appid = uniform_appid(appid)
     if data[0] != (APP_DATA_MARKER, appid):
         data.insert(0, dxftag(APP_DATA_MARKER, appid))
     if data[-1] != (APP_DATA_MARKER, "}"):
         data.append(dxftag(APP_DATA_MARKER, "}"))
     self.set(data)
    def _export_dxf_attribute_optional(self, tagwriter: 'TagWriter',
                                       name: str) -> None:
        """
        Exports DXF attribute `name` by `tagwriter`. Optional tags are only written if different to default value.

        Args:
            tagwriter: tag writer object
            name: DXF attribute name

        """
        export_dxf_version = tagwriter.dxfversion
        not_force_optional = not tagwriter.force_optional
        attrib = self.dxfattribs.get(name, None)

        if attrib:
            optional = attrib.optional
            default = attrib.default
            value = self.get(name, None)
            if value is None and not optional:  # force default value e.g. layer
                value = default  # default value could be None

            if (value is not None) and (export_dxf_version >= attrib.dxfversion
                                        ):  # do not export None
                # check optional value == default value
                if optional and not_force_optional and default is not None and (
                        default == value):
                    return  # do not write explicit optional attribs if equal to default value
                # just use x, y for 2d points if value is a 3d point (Vector, tuple)
                if attrib.xtype == XType.point2d and len(value) > 2:
                    value = value[:2]
                tag = dxftag(attrib.code, value)
                tagwriter.write_tag(tag)
        else:
            raise DXFAttributeError(
                ERR_INVALID_DXF_ATTRIB.format(name, self.dxftype))
Exemple #6
0
def reference_graphic_entities_in_extension_dictionaries(doc):
    # The extension dictionary is a DICTIONARY object and cannot reference
    # directly graphical entities (see function add_graphic_entity_to_root_dict()).
    # A XRECORD object is not a graphical entity and can store arbitrary data
    # and is therefore a good choice to attach data to a graphical entity by an
    # extension dictionary.

    msp = doc.modelspace()
    line = msp.add_line((0, 0), (1, 0))
    line1 = msp.add_line((0, 1), (1, 1))
    line2 = msp.add_line((0, 2), (1, 2))
    # Attach references to line1 and line2 to the line entity:
    ext_dict = line.new_extension_dict()
    xrecord = ext_dict.add_xrecord("LINK_CONTAINER")
    # The group code 360 is used in DICTIONARY to store handles to linked
    # objects and seems to be a good choice:
    xrecord.tags.append(dxftag(360, line1.dxf.handle))
    xrecord.tags.append(dxftag(360, line2.dxf.handle))
Exemple #7
0
    def add(self, appid: str, tags: Iterable[Union[Tuple[int, Any],
                                                   "DXFTag"]]) -> None:
        """Add a list of DXF tags for `appid`. The `tags` argument is an
        iterable of (group code, value) tuples, where the group code has to be
        an integer value. The mandatory XDATA marker (1001, appid) is added
        automatically if front of the tags if missing.

        Each entity can contain only one list of tags for each `appid`.
        Adding a second list of tags for the same `appid` replaces the
        existing list of tags.

        The valid XDATA group codes are restricted to some specific values in
        the range from 1000 to 1071, for more information see also the
        internals about :ref:`xdata_internals`.

        """
        data = Tags(dxftag(code, value) for code, value in tags)
        if len(data) == 0 or data[0] != (XDATA_MARKER, appid):
            data.insert(0, dxftag(XDATA_MARKER, appid))
        self._add(data)
Exemple #8
0
 def test_commit_creates_valid_XDATA(self):
     xlist = XDataUserList()
     xlist.extend(["String", Vec3(1, 2, 3), 3.1415, 256])
     xlist.commit()
     tags = xlist.xdata.get("EZDXF")
     assert tags == [
         dxftag(1001, "EZDXF"),
         dxftag(1000, "DefaultList"),
         dxftag(1002, "{"),
         dxftag(1000, "String"),
         dxftag(1010, (1, 2, 3)),
         dxftag(1040, 3.1415),
         dxftag(1071, 256),
         dxftag(1002, "}"),
     ]
Exemple #9
0
 def test_commit_replaces_existing_XDATA(self, list1):
     xlist = XDataUserList(XData([list1]))
     xlist.clear()
     xlist.extend(["String", Vec3(1, 2, 3), 3.1415, 256])
     xlist.commit()
     tags = xlist.xdata.get("EZDXF")
     assert tags == [
         dxftag(1001, "EZDXF"),
         dxftag(1000, "DefaultList"),
         dxftag(1002, "{"),
         dxftag(1000, "String"),
         dxftag(1010, (1, 2, 3)),
         dxftag(1040, 3.1415),
         dxftag(1071, 256),
         dxftag(1002, "}"),
     ]
Exemple #10
0
    def test_context_manager_interface(self):
        xdata = XData()
        with XDataUserList(xdata) as xlist:
            xlist.extend(["String", Vec3(1, 2, 3), 3.1415, 256])

        tags = xdata.get("EZDXF")
        assert tags == [
            dxftag(1001, "EZDXF"),
            dxftag(1000, "DefaultList"),
            dxftag(1002, "{"),
            dxftag(1000, "String"),
            dxftag(1010, (1, 2, 3)),
            dxftag(1040, 3.1415),
            dxftag(1071, 256),
            dxftag(1002, "}"),
        ]
Exemple #11
0
 def test_commit_creates_valid_XDATA(self):
     xdict = XDataUserDict()
     xdict["Key0"] = "StringValue"
     xdict["Float"] = 3.1415
     xdict.commit()
     tags = xdict.xdata.get("EZDXF")
     assert tags == [
         dxftag(1001, "EZDXF"),
         dxftag(1000, "DefaultDict"),
         dxftag(1002, "{"),
         dxftag(1000, "Key0"),
         dxftag(1000, "StringValue"),
         dxftag(1000, "Float"),
         dxftag(1040, 3.1415),
         dxftag(1002, "}"),
     ]
Exemple #12
0
    def test_context_manager_interface(self):
        xdata = XData()
        with XDataUserDict(xdata) as xdict:
            xdict["Key1"] = 256
            xdict["Key2"] = "Value2"

        tags = xdata.get("EZDXF")
        assert tags == [
            dxftag(1001, "EZDXF"),
            dxftag(1000, "DefaultDict"),
            dxftag(1002, "{"),
            dxftag(1000, "Key1"),
            dxftag(1071, 256),
            dxftag(1000, "Key2"),
            dxftag(1000, "Value2"),
            dxftag(1002, "}"),
        ]
Exemple #13
0
def transform_xdata_tags(tags: Tags, m: Matrix44) -> Iterator[DXFTag]:
    for tag in tags:
        code, value = tag
        if code == 1011:
            # move, scale, rotate and mirror
            yield dxftag(code, m.transform(Vec3(value)))
        elif code == 1012:
            # scale, rotate and mirror
            yield dxftag(code, m.transform_direction(Vec3(value)))
        elif code == 1013:
            # rotate and mirror
            vec = Vec3(value)
            length = vec.magnitude
            if length > 1e-12:
                vec = m.transform_direction(vec).normalize(length)
                yield dxftag(code, vec)
            else:
                yield tag
        elif code == 1041 or code == 1042:
            # scale distance and factor, works only for uniform scaling
            vec = m.transform_direction(Vec3(value, 0, 0))
            yield dxftag(code, vec.magnitude)
        else:
            yield tag
Exemple #14
0
    def _export_dxf_attribute_optional(self, tagwriter: 'TagWriter',
                                       name: str) -> None:
        """ Exports DXF attribute `name` by `tagwriter`. Optional tags are only
        written if different to default value.

        Args:
            tagwriter: tag writer object
            name: DXF attribute name

        """
        export_dxf_version = tagwriter.dxfversion
        not_force_optional = not tagwriter.force_optional
        attrib: Optional['DXFAttr'] = self.dxfattribs.get(name)

        if attrib:
            optional = attrib.optional
            default = attrib.default
            value = self.get(name, None)
            # Force default value e.g. layer
            if value is None and not optional:
                # Default value could be None
                value = default

                # Do not export None values
            if ((value is not None)
                    and (export_dxf_version >= attrib.dxfversion)):
                # Do not write explicit optional attribs if equal to default
                # value
                if (optional and not_force_optional and default is not None
                        and default == value):
                    return
                    # Just export x, y for 2D points, if value is a 3D point
                if attrib.xtype == XType.point2d and len(value) > 2:
                    try:  # Vec3
                        value = (value.x, value.y)
                    except AttributeError:
                        value = value[:2]

                if isinstance(value, str):
                    assert '\n' not in value, "line break '\\n' not allowed"
                    assert '\r' not in value, "line break '\\r' not allowed"
                tag = dxftag(attrib.code, value)
                tagwriter.write_tag(tag)
        else:
            raise const.DXFAttributeError(
                ERR_INVALID_DXF_ATTRIB.format(name, self.dxftype))
Exemple #15
0
 def test_modify_existing_XDATA(self, list1):
     xlist = XDataUserList(XData([list1]))
     xlist[0] = 3.1415
     xlist[1] = 256
     xlist.commit()
     tags = xlist.xdata.get("EZDXF")
     assert tags == [
         dxftag(1001, "EZDXF"),
         dxftag(1000, "DefaultList"),
         dxftag(1002, "{"),
         dxftag(1040, 3.1415),
         dxftag(1071, 256),
         dxftag(1002, "}"),
     ]
Exemple #16
0
 def test_modify_existing_user_list(self, user_list):
     xlist = XDataUserList(XData([user_list]),
                           name="MyUserList",
                           appid="MyAppID")
     xlist[0] = 3.1415
     xlist[1] = 256
     xlist.commit()
     tags = xlist.xdata.get("MyAppID")
     assert tags == [
         dxftag(1001, "MyAppID"),
         dxftag(1000, "MyUserList"),
         dxftag(1002, "{"),
         dxftag(1040, 3.1415),
         dxftag(1071, 256),
         dxftag(1002, "}"),
     ]
Exemple #17
0
    def commit(self) -> None:
        """Store all changes to the underlying :class:`XData` instance.
        This call is not required if using the :meth:`entity` context manager.

        Raises:
            DXFValueError: invalid chars ``"\\n"`` or ``"\\r"`` in a string
            DXFTypeError: invalid data type

        """
        data = []
        for value in self._data:
            if isinstance(value, str):
                if len(value) > 255:  # XDATA limit for group code 1000
                    raise DXFValueError("string too long, max. 255 characters")
                if "\n" in value or "\r" in value:
                    raise DXFValueError(
                        "found invalid line break '\\n' or '\\r'")
            code = self.group_codes.get(type(value))
            if code:
                data.append(dxftag(code, value))
            else:
                raise DXFTypeError(f"invalid type: {type(value)}")
        self.xdata.set_xlist(self._appid, self._name, data)
Exemple #18
0
 def test_render_int_type(self):
     tag = dxftag(70, 1)
     assert render_tag(tag, 0) == "70"
     assert render_tag(tag, 1) == "<int>"
     assert render_tag(tag, 2) == "1"
Exemple #19
0
 def test_render_float_type(self):
     tag = dxftag(40, 1.1)
     assert render_tag(tag, 0) == "40"
     assert render_tag(tag, 1) == "<float>"
     assert render_tag(tag, 2) == "1.1"
Exemple #20
0
 def test_render_handle_type(self):
     tag = dxftag(5, "ABBA")
     assert render_tag(tag, 0) == "5"
     assert render_tag(tag, 1) == "<handle>"
     assert render_tag(tag, 2) == "ABBA"
Exemple #21
0
 def test_render_reference_type(self):
     tag = dxftag(330, "ABBA")
     assert render_tag(tag, 0) == "330"
     assert render_tag(tag, 1) == "<ref>"
     assert render_tag(tag, 2) == "ABBA"
Exemple #22
0
 def add(self, appid: str, tags: Iterable) -> None:
     data = Tags(dxftag(code, value) for code, value in tags)
     if len(data) == 0 or data[0] != (XDATA_MARKER, appid):
         data.insert(0, dxftag(XDATA_MARKER, appid))
     self._add(data)
Exemple #23
0
 def test_render_ctrl_type(self):
     tag = dxftag(0, "LINE")
     assert render_tag(tag, 0) == "0"
     assert render_tag(tag, 1) == "<ctrl>"
     assert render_tag(tag, 2) == "LINE"
Exemple #24
0
def totags(tags: Iterable) -> Iterable[DXFTag]:
    for tag in tags:
        if isinstance(tag, DXFTag):
            yield tag
        else:
            yield dxftag(tag[0], tag[1])
Exemple #25
0
 def test_render_point_type(self):
     tag = dxftag(10, Vec3(1, 2, 3))
     assert render_tag(tag, 0) == "10"
     assert render_tag(tag, 1) == "<point>"
     assert render_tag(tag, 2) == "(1.0, 2.0, 3.0)"
Exemple #26
0
 def test_render_binary_data_type(self):
     tag = dxftag(310, "FEFE")
     assert render_tag(tag, 0) == "310"
     assert render_tag(tag, 1) == "<bin>"
     assert render_tag(tag, 2) == "FEFE"
Exemple #27
0
 def test_raise_index_error_for_invalid_column_index(self):
     tag = dxftag(1, "text")
     pytest.raises(IndexError, render_tag, tag, 3)
Exemple #28
0
 def test_render_string_type(self):
     tag = dxftag(1, "text")
     assert render_tag(tag, 0) == "1"
     assert render_tag(tag, 1) == "<str>"
     assert render_tag(tag, 2) == "text"