123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203 |
- # Created: 25.03.2011
- # Copyright (c) 2011-2018, Manfred Moitzi
- # License: MIT License
- from typing import TYPE_CHECKING, Optional
- from ezdxf.lldxf.types import DXFTag
- from ezdxf.lldxf.tags import Tags
- from ezdxf.lldxf import loader
- from ezdxf.legacy import polyline
- from ezdxf.legacy.facemixins import PolyfaceMixin, PolymeshMixin
- from .graphics import ExtendedTags, DXFAttr, DefSubclass, DXFAttributes, XType
- from .graphics import none_subclass, entity_subclass, ModernGraphicEntityExtension
- if TYPE_CHECKING:
- from ezdxf.eztypes import Tags
- _POLYLINE_TPL = """0
- POLYLINE
- 5
- 0
- 330
- 0
- 100
- AcDbEntity
- 8
- 0
- 100
- AcDb2dPolyline
- 66
- 1
- 70
- 0
- 10
- 0.0
- 20
- 0.0
- 30
- 0.0
- """
- polyline_subclass = DefSubclass('AcDb2dPolyline', {
- 'elevation': DXFAttr(10, xtype=XType.point3d),
- 'flags': DXFAttr(70, default=0),
- 'default_start_width': DXFAttr(40, default=0.0),
- 'default_end_width': DXFAttr(41, default=0.0),
- 'm_count': DXFAttr(71, default=0),
- 'n_count': DXFAttr(72, default=0),
- 'm_smooth_density': DXFAttr(73, default=0),
- 'n_smooth_density': DXFAttr(74, default=0),
- 'smooth_type': DXFAttr(75, default=0),
- 'thickness': DXFAttr(39, default=0.0),
- 'extrusion': DXFAttr(210, xtype=XType.point3d, default=(0.0, 0.0, 1.0)),
- })
- class Polyline(polyline.Polyline, ModernGraphicEntityExtension):
- __slots__ = ()
- TEMPLATE = ExtendedTags.from_text(_POLYLINE_TPL)
- DXFATTRIBS = DXFAttributes(none_subclass, entity_subclass, polyline_subclass)
- def post_new_hook(self) -> None:
- super(Polyline, self).post_new_hook()
- self.update_subclass_specifier()
- def update_subclass_specifier(self) -> None:
- # For dxf attribute access not the name of the subclass is important, but
- # the order of the subclasses 1st, 2nd, 3rd and so on.
- # The 3rd subclass is the AcDb3dPolyline or AcDb2dPolyline subclass
- subclass = self.tags.subclasses[2] # type: Tags
- subclass[0] = DXFTag(100, self.get_mode())
- def cast(self) -> 'Polyline':
- mode = self.get_mode()
- if mode == 'AcDbPolyFaceMesh':
- return Polyface.convert(self)
- elif mode == 'AcDbPolygonMesh':
- return Polymesh.convert(self)
- else:
- return self
- class Polyface(Polyline, PolyfaceMixin):
- __slots__ = ()
- """
- PolyFace structure:
- POLYLINE
- AcDbEntity
- AcDbPolyFaceMesh
- VERTEX - Vertex
- AcDbEntity
- AcDbVertex
- AcDbPolyFaceMeshVertex
- VERTEX - Face
- AcDbEntity
- AcDbFaceRecord
- SEQEND
- """
- @staticmethod
- def convert(polyline: 'Polyline') -> 'Polyface':
- return Polyface(polyline.tags, polyline.drawing)
- class Polymesh(Polyline, PolymeshMixin):
- __slots__ = ()
- """
- PolyMesh structure:
- POLYLINE
- AcDbEntity
- AcDbPolygonMesh
- VERTEX
- AcDbEntity
- AcDbVertex
- AcDbPolygonMeshVertex
- """
- @staticmethod
- def convert(polyline: 'Polyline') -> 'Polymesh':
- return Polymesh(polyline.tags, polyline.drawing)
- _VERTEX_TPL = """0
- VERTEX
- 5
- 0
- 330
- 0
- 100
- AcDbEntity
- 8
- 0
- 100
- AcDbVertex
- 100
- AcDb2dVertex
- 10
- 0.0
- 20
- 0.0
- 30
- 0.0
- 70
- 0
- """
- vertex_subclass = (
- DefSubclass('AcDbVertex', {}), # subclasses[2]
- DefSubclass('AcDb2dVertex', { # subclasses[3]
- 'location': DXFAttr(10, xtype=XType.any_point),
- 'start_width': DXFAttr(40, default=0.0),
- 'end_width': DXFAttr(41, default=0.0),
- 'bulge': DXFAttr(42, default=0),
- 'flags': DXFAttr(70),
- 'tangent': DXFAttr(50),
- 'vtx0': DXFAttr(71),
- 'vtx1': DXFAttr(72),
- 'vtx2': DXFAttr(73),
- 'vtx3': DXFAttr(74),
- })
- )
- EMPTY_VERTEX_SUBCLASS = Tags()
- class DXFVertex(polyline.DXFVertex, ModernGraphicEntityExtension):
- __slots__ = ()
- TEMPLATE = ExtendedTags.from_text(_VERTEX_TPL)
- DXFATTRIBS = DXFAttributes(none_subclass, entity_subclass, *vertex_subclass)
- def post_new_hook(self) -> None:
- self.update_subclass_specifier()
- def update_subclass_specifier(self) -> None:
- def set_subclass(subclassname: str) -> None:
- subclass = self.tags.subclasses[3]
- subclass[0] = DXFTag(100, subclassname)
- if self.is_3d_polyline_vertex: # flags & const.VTX_3D_POLYLINE_VERTEX
- set_subclass('AcDb3dPolylineVertex')
- elif self.is_face_record: # (flags & Vertex.FACE_FLAGS) == const.VTX_3D_POLYFACE_MESH_VERTEX:
- set_subclass('AcDbFaceRecord')
- self.tags.subclasses[2] = EMPTY_VERTEX_SUBCLASS # clear subclass AcDbVertex
- elif self.is_poly_face_mesh_vertex: # flags & Vertex.FACE_FLAGS == Vertex.FACE_FLAGS:
- set_subclass('AcDbPolyFaceMeshVertex')
- elif self.is_polygon_mesh_vertex: # flags & const.VTX_3D_POLYGON_MESH_VERTEX:
- set_subclass('AcDbPolygonMeshVertex')
- else:
- set_subclass('AcDb2dVertex')
- @loader.register('VERTEX', legacy=False)
- def vertex_tags_processor(tags: ExtendedTags) -> Optional[ExtendedTags]:
- """
- If subclass[2] is not 'AcDbVertex', insert empty subclass
- """
- if not isinstance(tags, ExtendedTags):
- return
- if tags.subclasses[2][0].value != 'AcDbVertex':
- tags.subclasses.insert(2, EMPTY_VERTEX_SUBCLASS)
- return tags
|