Beispiel #1
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:]))
Beispiel #2
0
class Circle(GraphicEntity):
    __slots__ = ()
    TEMPLATE = ExtendedTags.from_text(_CIRCLE_TPL)
    DXFATTRIBS = make_attribs({
        'center': DXFAttr(10, xtype='Point2D/3D'),
        'radius': DXFAttr(40),
    })
Beispiel #3
0
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'),
    })
Beispiel #4
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
Beispiel #5
0
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),
        }))
Beispiel #6
0
def subclass():
    return DefSubclass('AcDbTest', {
        'test1': DXFAttr(1),
        'test2': DXFAttr(2),
        'test3': DXFAttr(1),  # duplicate group code
        'callback': DXFAttr(3, xtype=XType.callback),
        'none_callback': DXFAttr(3),  # duplicate group code
    })
Beispiel #7
0
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),
    })
Beispiel #8
0
class AppID(DXFEntity):
    __slots__ = ()
    TEMPLATE = ExtendedTags.from_text(_APPIDTEMPLATE)
    DXFATTRIBS = DXFAttributes(
        DefSubclass(None, {
            'handle': DXFAttr(5),
            'name': DXFAttr(2),
            'flags': DXFAttr(70),
        }))
def subclass():
    return DefSubclass(
        "AcDbTest",
        {
            "test1": DXFAttr(1),
            "test2": DXFAttr(2),
            "test3": DXFAttr(1),  # duplicate group code
            "callback": DXFAttr(3, xtype=XType.callback),
            "none_callback": DXFAttr(3),  # duplicate group code
        },
    )
Beispiel #10
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
        }),
    )
Beispiel #11
0
class Viewport(GraphicEntity):
    __slots__ = ()
    TEMPLATE = ExtendedTags.from_text(_VPORT_TPL)
    DXFATTRIBS = make_attribs({
        'center':
        DXFAttr(10, xtype='Point2D/3D'
                ),  # center point of entity in paper space coordinates)
        'width': DXFAttr(40),  # width in paper space units
        'height': DXFAttr(41),  # height in paper space units
        'status': DXFAttr(68),
        'id': DXFAttr(69),
    })

    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.

    @contextmanager
    def edit_data(self):
        viewport_data = self.get_viewport_data()
        yield viewport_data
        self.set_viewport_data(viewport_data)

    def get_viewport_data(self):
        try:
            extended_dxf_data = self.tags.get_xdata('ACAD')
        except DXFValueError:
            DXFStructureError("Invalid viewport entity - missing data")
        else:
            return ViewportData.from_tags(extended_dxf_data)

    def set_viewport_data(self, viewport_data):
        dxftags = viewport_data.dxftags()
        pos = None
        for index, xdata in enumerate(self.tags.xdata):
            if xdata[0].value == 'ACAD' and xdata[1].value == 'MVIEW':
                pos = index
        if pos is None:
            self.tags.xdata.insert(
                0, dxftags)  # insert viewport data as first extended data
        else:
            self.tags.xdata[pos] = dxftags

    def get_next_viewport_id(self):
        current_id = Viewport.viewport_id
        Viewport.viewport_id += 1
        return current_id
Beispiel #12
0
class PointAccessor(DXFEntity):
    DXFATTRIBS = DXFAttributes(
        DefSubclass(
            None, {
                'point':
                DXFAttr(10, xtype=XType.point3d),
                'flat':
                DXFAttr(11, xtype=XType.point2d),
                'xp':
                DXFAttr(12, xtype=XType.point3d),
                'flex':
                DXFAttr(13, xtype=XType.any_point),
                'flags':
                DXFAttr(70),
                'counter':
                DXFAttr(-1,
                        xtype=XType.callback,
                        getter='get_counter',
                        setter='set_counter'),
                'just_AC1015':
                DXFAttr(71, default=777, dxfversion='AC1015'),
            }))

    def __init__(self, tags):
        super(PointAccessor, self).__init__(tags, drawing=DWG)
        self._counter = 0

    def get_counter(self):
        return self._counter

    def set_counter(self, value):
        self._counter = value
Beispiel #13
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
            }))
Beispiel #14
0
class Style(DXFEntity):
    __slots__ = ()
    TEMPLATE = ExtendedTags.from_text(_STYLETEMPLATE)
    DXFATTRIBS = DXFAttributes(
        DefSubclass(
            None,
            {
                'handle': DXFAttr(5),
                'name': DXFAttr(2),
                'flags': DXFAttr(70),
                'height': DXFAttr(40),  # fixed height, 0 if not fixed
                'width': DXFAttr(41),  # width factor
                'oblique':
                DXFAttr(50),  # oblique angle in degree, 0 = vertical
                'generation_flags':
                DXFAttr(71),  # 2 = backward, 4 = mirrored in Y
                'last_height': DXFAttr(42),  # last height used
                'font': DXFAttr(3),  # primary font file name
                'bigfont': DXFAttr(4),  # big font name, blank if none
            }))
Beispiel #15
0
def test_load_doublettes():
    from ezdxf.lldxf.attributes import DefSubclass, DXFAttr
    from ezdxf.lldxf.tags import Tags, DXFTag
    subclass = DefSubclass('AcDbTest', {
        'test1': DXFAttr(1),
        'test2': DXFAttr(2),
        'test3': DXFAttr(1),  # same group code for different attribute
    })

    class TestEntity(DXFEntity):
        DXFATTRIBS = DXFAttributes(subclass)

    data = Tags([
        DXFTag(1, '1'),
        DXFTag(2, '2'),
        DXFTag(1, '3'),
    ])
    ns = DXFNamespace(entity=TestEntity())
    SubclassProcessor.load_tags_into_namespace(ns, data, subclass)
    assert ns.test1 == '1'
    assert ns.test2 == '2'
    assert ns.test3 == '3'
Beispiel #16
0
class DXFClass(DXFEntity):
    __slots__ = ()
    DXFATTRIBS = DXFAttributes(
        DefSubclass(
            None, {
                'name': DXFAttr(1),
                'cpp_class_name': DXFAttr(2),
                'app_name': DXFAttr(3),
                'flags': DXFAttr(90),
                'instance_count': DXFAttr(91, dxfversion='AC1018'),
                'was_a_proxy': DXFAttr(280),
                'is_an_entity': DXFAttr(281),
            }), )
Beispiel #17
0
class Shape(GraphicEntity):
    __slots__ = ()
    TEMPLATE = ExtendedTags.from_text(_SHAPE_TPL)
    DXFATTRIBS = make_attribs({
        'insert': DXFAttr(10, xtype='Point2D/3D'),
        'size': DXFAttr(40),
        'name': DXFAttr(2),
        'rotation': DXFAttr(50, default=0.0),
        'xscale': DXFAttr(41, default=1.0),
        'oblique': DXFAttr(51, default=0.0),
    })
Beispiel #18
0
class PointAccessor(DXFEntity):
    DXFATTRIBS = DXFAttributes(
        DefSubclass(
            None, {
                'point': DXFAttr(10, 'Point3D'),
                'flat': DXFAttr(11, 'Point2D'),
                'xp': DXFAttr(12, 'Point3D'),
                'flex': DXFAttr(13, 'Point2D/3D'),
                'flags': DXFAttr(70),
                'just_AC1015': DXFAttr(71, default=777, dxfversion='AC1015'),
            }))

    def __init__(self, tags):
        super(PointAccessor, self).__init__(tags, drawing=DWG)
Beispiel #19
0
def test_return_default():
    attr = DXFAttr(
        code=62,
        default=12,
        validator=lambda x: False,
        fixer=RETURN_DEFAULT,
    )
    assert attr.fixer(7) == 12

    attr2 = DXFAttr(
        code=63,
        default=13,
        validator=lambda x: False,
        fixer=RETURN_DEFAULT,
    )
    assert attr2.fixer(7) == 13
Beispiel #20
0
def make_attribs(additional=None):
    dxfattribs = {
        'handle': DXFAttr(5),
        'layer': DXFAttr(
            8, default='0'
        ),  # layer name as string, mandatory according to the DXF Reference
        'linetype':
        DXFAttr(6, default='BYLAYER'
                ),  # linetype as string, special names BYLAYER/BYBLOCK
        'color':
        DXFAttr(62,
                default=256),  # dxf color index, 0 .. BYBLOCK, 256 .. BYLAYER
        'thickness': DXFAttr(39, default=0),  # thickness of 2D elements
        'paperspace': DXFAttr(67, default=0),  # 0=modelspace; 1=paperspace
        'extrusion':
        DXFAttr(210, xtype='Point3D',
                default=(0.0, 0.0,
                         1.0)),  # Z-axis of OCS (Object-Coordinate-System)
    }
    if additional is not None:
        dxfattribs.update(additional)
    return DXFAttributes(DefSubclass(None, dxfattribs))
Beispiel #21
0
class UCS(DXFEntity):
    __slots__ = ()
    TEMPLATE = ExtendedTags.from_text(_UCSTEMPLATE)
    DXFATTRIBS = DXFAttributes(
        DefSubclass(
            None, {
                'handle': DXFAttr(5),
                'name': DXFAttr(2),
                'flags': DXFAttr(70),
                'origin': DXFAttr(10, xtype=XType.point3d),
                'xaxis': DXFAttr(11, xtype=XType.point3d),
                'yaxis': DXFAttr(12, xtype=XType.point3d),
            }))

    def ucs(self) -> UserCoordinateSystem:
        return UserCoordinateSystem(
            origin=self.get_dxf_attrib('origin', default=(0, 0, 0)),
            ux=self.get_dxf_attrib('xaxis', default=(1, 0, 0)),
            uy=self.get_dxf_attrib('yaxis', default=(0, 1, 0)),
        )
Beispiel #22
0
from ezdxf.math import Vector, Matrix44, NULLVEC, Z_AXIS
from ezdxf.math.transformtools import (
    transform_thickness_and_extrusion_without_ocs, )
from .dxfentity import base_class, SubclassProcessor
from .dxfgfx import DXFGraphic, acdb_entity
from .factory import register_entity

if TYPE_CHECKING:
    from ezdxf.eztypes import TagWriter, DXFNamespace

__all__ = ['Line']

acdb_line = DefSubclass(
    'AcDbLine', {
        'start':
        DXFAttr(10, xtype=XType.point3d, default=NULLVEC),
        'end':
        DXFAttr(11, xtype=XType.point3d, default=NULLVEC),
        'thickness':
        DXFAttr(39, default=0, optional=True),
        'extrusion':
        DXFAttr(
            210,
            xtype=XType.point3d,
            default=Z_AXIS,
            optional=True,
            validator=validator.is_not_null_vector,
            fixer=RETURN_DEFAULT,
        ),
    })
Beispiel #23
0
from ezdxf.tools import set_flag_state
from .dxfentity import base_class, SubclassProcessor
from .dxfgfx import DXFGraphic, acdb_entity
from .factory import register_entity

if TYPE_CHECKING:
    from ezdxf.eztypes import TagWriter, DXFNamespace, Drawing

__all__ = ['Viewport']

acdb_viewport = DefSubclass(
    'AcDbViewport',
    {
        # Center point (in WCS)
        'center':
        DXFAttr(10, xtype=XType.point3d, default=NULLVEC),

        # Width in paper space units:
        'width':
        DXFAttr(40, default=1),

        # Height in paper space units:
        'height':
        DXFAttr(41, default=1),

        # Viewport status field:
        # -1 = On, but is fully off screen, or is one of the viewports that is not
        #      active because the $MAXACTVP count is currently being exceeded.
        #  0 = Off
        # <positive value> = On and active. The value indicates the order of
        # stacking for the viewports, where 1 is the active viewport, 2 is the next,
Beispiel #24
0
def fix_ratio(ratio: float) -> float:
    sign = -1 if ratio < 0 else +1
    ratio = abs(ratio)
    if ratio < MIN_RATIO:
        return MIN_RATIO * sign
    elif ratio > MAX_RATIO:
        return MAX_RATIO * sign
    return ratio * sign


acdb_ellipse = DefSubclass(
    'AcDbEllipse',
    {
        'center':
        DXFAttr(10, xtype=XType.point3d, default=NULLVEC),

        # Major axis vector from 'center':
        'major_axis':
        DXFAttr(
            11,
            xtype=XType.point3d,
            default=X_AXIS,
            validator=validator.is_not_null_vector,
        ),

        # The extrusion vector does not establish an OCS, it is just the normal
        # vector of the ellipse plane:
        'extrusion':
        DXFAttr(
            210,
Beispiel #25
0
from .dxfentity import base_class, SubclassProcessor
from .dxfgfx import DXFGraphic, acdb_entity
from .factory import register_entity

if TYPE_CHECKING:
    from ezdxf.eztypes import TagWriter, DXFNamespace, Matrix44

__all__ = ["Tolerance"]

acdb_tolerance = DefSubclass(
    "AcDbFcf",
    {
        "dimstyle":
        DXFAttr(
            3,
            default="Standard",
            validator=validator.is_valid_table_name,
        ),
        # Insertion point (in WCS):
        "insert":
        DXFAttr(10, xtype=XType.point3d, default=NULLVEC),
        # String representing the visual representation of the tolerance:
        "content":
        DXFAttr(1, default=""),
        "extrusion":
        DXFAttr(
            210,
            xtype=XType.point3d,
            default=Z_AXIS,
            optional=True,
            validator=validator.is_not_null_vector,
Beispiel #26
0
    RETURN_DEFAULT,
)
from .dxfentity import base_class, SubclassProcessor
from .dxfobj import DXFObject
from .factory import register_entity

if TYPE_CHECKING:
    from ezdxf.eztypes import TagWriter, DXFNamespace

__all__ = ['Sun']

acdb_sun = DefSubclass(
    'AcDbSun',
    {
        'version':
        DXFAttr(90, default=1),
        'status':
        DXFAttr(
            290,
            default=1,
            validator=validator.is_integer_bool,
            fixer=RETURN_DEFAULT,
        ),
        'color':
        DXFAttr(
            63,
            default=7,
            validator=validator.is_valid_aci_color,
            fixer=RETURN_DEFAULT,
        ),
        'true_color':
Beispiel #27
0
from .factory import register_entity

logger = logging.getLogger('ezdxf')

if TYPE_CHECKING:
    from ezdxf.eztypes import TagWriter, DXFNamespace

__all__ = ['Textstyle']

acdb_style = DefSubclass(
    'AcDbTextStyleTableRecord',
    {
        'name':
        DXFAttr(
            2,
            default='Standard',
            validator=validator.is_valid_table_name,
        ),
        'flags':
        DXFAttr(70, default=0),

        # Fixed height, 0 if not fixed
        'height':
        DXFAttr(
            40,
            default=0,
            validator=validator.is_greater_or_equal_zero,
            fixer=RETURN_DEFAULT,
        ),
        # Width factor:
        'width':
Beispiel #28
0
from ezdxf.math.transformtools import OCSTransform
from .dxfentity import base_class, SubclassProcessor
from .dxfgfx import DXFGraphic, acdb_entity, elevation_to_z_axis
from .factory import register_entity

if TYPE_CHECKING:
    from ezdxf.eztypes import TagWriter, DXFNamespace

__all__ = ['Solid', 'Trace', 'Face3d']

acdb_trace = DefSubclass(
    'AcDbTrace',
    {
        # 1. corner Solid WCS; Trace OCS
        'vtx0':
        DXFAttr(10, xtype=XType.point3d, default=NULLVEC),

        # 2. corner Solid WCS; Trace OCS
        'vtx1':
        DXFAttr(11, xtype=XType.point3d, default=NULLVEC),

        # 3. corner Solid WCS; Trace OCS
        'vtx2':
        DXFAttr(12, xtype=XType.point3d, default=NULLVEC),

        # 4. corner Solid WCS; Trace OCS:
        # If only three corners are entered to define the SOLID, then the fourth
        # corner coordinate is the same as the third.
        'vtx3':
        DXFAttr(13, xtype=XType.point3d, default=NULLVEC),
Beispiel #29
0
class Solid3d(Body):
    __slots__ = ()
    TEMPLATE = ExtendedTags.from_text(_3DSOLID_TPL)
    DXFATTRIBS = DXFAttributes(
        none_subclass, entity_subclass, modeler_geometry_subclass,
        DefSubclass('AcDb3dSolid', {'history': DXFAttr(350, default=0)}))
Beispiel #30
0
5
0
330
0
100
AcDbEntity
8
0
100
AcDbModelerGeometry
70
1
"""

modeler_geometry_subclass = DefSubclass('AcDbModelerGeometry', {
    'version': DXFAttr(70, default=1),
})


def convert_tags_to_text_lines(line_tags):
    """
    Args:
        line_tags: tags with code 1 or 3, tag with code 3 is the tail of previous line with more than 255 chars.

    Returns: yield strings

    """
    line_tags = iter(line_tags)
    try:
        line = next(line_tags).value  # raises StopIteration
    except StopIteration: