123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222 |
- # Created: 08.04.2018
- # Copyright (c) 2018, Manfred Moitzi
- # License: MIT-License
- from typing import TYPE_CHECKING, Iterable, Dict
- from ezdxf.lldxf.const import DXFIndexError
- from .graphics import ExtendedTags, DXFAttr, DefSubclass, DXFAttributes, XType
- from .graphics import none_subclass, entity_subclass, ModernGraphicEntity
- from .dxfobjects import DXFObject
- from .object_manager import ObjectManager
- if TYPE_CHECKING:
- from ezdxf.eztypes import Drawing, Tags
- # example: processing: D:\source\dxftest\CADKitSamples\Lock-Off.dxf
- _MLINE_TPL = """0
- MLINE
- 5
- 0
- 330
- 0
- 100
- AcDbEntity
- 8
- 0
- 100
- AcDbMline
- 2
- STANDARD
- 340
- 0
- 40
- 1.0
- 70
- 0
- 71
- 1
- 72
- 1
- 73
- 1
- 10
- 0.0
- 20
- 0.0
- 30
- 0.0
- 210
- 0.0
- 220
- 0.0
- 230
- 1.0
- """
- mline_subclass = DefSubclass('AcDbMline', {
- 'mline_style': DXFAttr(2),
- 'mline_style_id': DXFAttr(340),
- 'scale_factor': DXFAttr(40, default=1),
- 'justification': DXFAttr(70), # 0 = Top; 1 = Zero; 2 = Bottom
- 'flags': DXFAttr(71), # Flags (bit-coded values):
- # 1 = Has at least one vertex (code 72 is greater than 0)
- # 2 = Closed
- # 4 = Suppress start caps
- # 8 = Suppress end caps
- 'n_vertices': DXFAttr(72), # Number of vertices
- 'n_style_elements': DXFAttr(73), # Number of elements in MLINESTYLE definition
- 'start_point': DXFAttr(10, xtype=XType.point3d), # in WCS!
- 'extrusion': DXFAttr(210, xtype=XType.point3d), # but all vertices in WCS!
- # 11: vertex coordinates (multiple entries; one entry for each vertex)
- # 12: Direction vector of segment starting at this vertex (multiple entries; one for each vertex)
- # 13: Direction vector of miter at this vertex (multiple entries: one for each vertex)
- # 73: Number of parameters for this element (repeats for each element in segment)
- # 41: Element parameters (repeats based on previous code 74)
- # 75: Number of area fill parameters for this element (repeats for each element in segment)
- # 42: Area fill parameters (repeats based on previous code 75)
- })
- # The group code 41 parameterization is a list of real values, one real per group code 41. The list may contain zero or
- # more items. The first group code 41 value is the distance from the segment vertex along the miter vector to the point
- # where the line element's path intersects the miter vector. The next group code 41 value is the distance along the line
- # element's path from the point defined by the first group 41 to the actual start of the line element. The next is the
- # distance from the start of the line element to the first break (or cut) in the line element. The successive group
- # code 41 values continue to list the start and stop points of the line element in this segment of the mline. Linetypes
- # do not affect group 41 lists.
- #
- # The group code 42 parameterization is also a list of real values. Similar to the 41 parameterization, it describes the
- # parameterization of the fill area for this mline segment. The values are interpreted identically to the 41 parameters
- # and when taken as a whole for all line elements in the mline segment, they define the boundary of the fill area for
- # the mline segment.
- #
- # A common example of the use of the group code 42 mechanism is when an unfilled mline crosses over a filled mline and
- # mledit is used to cause the filled mline to appear unfilled in the crossing area. This would result in two group 42s
- # for each line element in the affected mline segment; one for the fill stop and one for the fill start.
- #
- # The 2 group codes in mline entities and mlinestyle objects are redundant fields. These groups should not be modified
- # under any circumstances, although it is safe to read them and use their values. The correct fields to modify are as
- # follows:
- #
- # Mline
- # The 340 group in the same object, which indicates the proper MLINESTYLE object.
- #
- # Mlinestyle
- # The 3 group value in the MLINESTYLE dictionary, which precedes the 350 group that has the handle or entity name of
- # the current mlinestyle.
- class MLine(ModernGraphicEntity):
- # Requires AC1021/R2007
- __slots__ = ()
- TEMPLATE = ExtendedTags.from_text(_MLINE_TPL)
- DXFATTRIBS = DXFAttributes(none_subclass, entity_subclass, mline_subclass)
- def get_points(self):
- return []
- _MLINE_STYLE_TPL = """0
- MLINESTYLE
- 5
- 0
- 102
- {ACAD_REACTORS
- 102
- }
- 330
- 0
- 100
- AcDbMlineStyle
- 2
- STANDARD
- 70
- 0
- 3
- 62
- 256
- 51
- 90.0
- 52
- 90.0
- 71
- 2
- 49
- 0.5
- 62
- 256
- 6
- BYLAYER
- 49
- -0.5
- 62
- 256
- 6
- BYLAYER
- """
- mline_style_subclass = DefSubclass('AcDbMlineStyle', {
- 'name': DXFAttr(2),
- 'flags': DXFAttr(70), # Flags (bit-coded):
- # 1 =Fill on
- # 2 = Display miters
- # 16 = Start square end (line) cap
- # 32 = Start inner arcs cap
- # 64 = Start round (outer arcs) cap
- # 256 = End square (line) cap
- # 512 = End inner arcs cap
- # 1024 = End round (outer arcs) cap
- 'description': DXFAttr(3), # Style description (string, 255 characters maximum)
- 'fill_color': DXFAttr(62), # Fill color (integer, default = 256)
- 'start_angle': DXFAttr(51), # Start angle (real, default is 90 degrees)
- 'end_angle': DXFAttr(52), # End angle (real, default is 90 degrees)
- 'n_elements': DXFAttr(71), # Number of elements
- # 49: Element offset (real, no default). Multiple entries can exist; one entry for each element
- # 62: Element color (integer, default = 0). Multiple entries can exist; one entry for each element
- # 6: Element linetype (string, default = BYLAYER). Multiple entries can exist; one entry for each element
- })
- class MLineStyle(DXFObject):
- # Requires AC1021/R2007
- __slots__ = ()
- TEMPLATE = ExtendedTags.from_text(_MLINE_STYLE_TPL)
- DXFATTRIBS = DXFAttributes(none_subclass, mline_style_subclass)
- @property
- def AcDbMLineStyle(self) -> 'Tags':
- return self.tags.subclasses[1]
- def get_elements(self) -> Iterable[Dict]:
- tags = self.AcDbMLineStyle
- try:
- start = tags.tag_index(71)
- except DXFIndexError:
- return
- else:
- collector = None
- for code, value in tags[start+1:]:
- if code == 49:
- if collector is not None:
- yield collector
- collector = {'offset': value}
- elif code == 62:
- collector['color'] = value
- elif code == 6:
- collector['linetype'] = value
- if collector is not None:
- yield collector
- class MLineStyleManager(ObjectManager):
- def __init__(self, drawing: 'Drawing'):
- super().__init__(drawing, dict_name='ACAD_MLINESTYLE', object_type='MLINESTYLE')
- self.create_required_entries()
- def create_required_entries(self) -> None:
- for name in ('STANDARD', ):
- if name not in self.object_dict:
- self.new(name)
|