def resolve_linetype( self, entity: 'DXFGraphic', *, resolved_layer: str = None) -> Tuple[str, Tuple[float, ...]]: """ Resolve the linetype of `entity`. Returns a tuple of the linetype name as upper-case string and the simplified linetype pattern as tuple of floats. """ aci = entity.dxf.color # Not sure if plotstyle table overrides actual entity setting? if (0 < aci < 256) and \ self.plot_styles[aci].linetype != acadctb.OBJECT_LINETYPE: # todo: return special line types - overriding linetypes by # plotstyle table pass name = entity.dxf.linetype.upper() # default is 'BYLAYER' if name == 'BYLAYER': entity_layer = resolved_layer or layer_key( self.resolve_layer(entity)) layer = self.layers.get(entity_layer, DEFAULT_LAYER_PROPERTIES) name = layer.linetype_name pattern = layer.linetype_pattern elif name == 'BYBLOCK': if self.inside_block_reference: name = self.current_block_reference.linetype_name pattern = self.current_block_reference.linetype_pattern else: # There is no default layout linetype name = 'STANDARD' pattern = CONTINUOUS_PATTERN else: pattern = self.line_pattern.get(name, CONTINUOUS_PATTERN) return name, pattern
def resolve_color(self, entity: 'DXFGraphic', *, default_hatch_transparency: float = 0.8) -> Color: """ Resolve color of DXF `entity` """ aci = entity.dxf.color # defaults to BYLAYER if aci == const.BYLAYER: entity_layer = layer_key(entity.dxf.layer) # AutoCAD appears to treat layer 0 differently to other layers in this case. if self.is_block_context and entity_layer == '0': color = self.current_block.color else: color = self.layers.get(entity_layer, DEFAULT_LAYER_PROPERTIES).color elif aci == const.BYBLOCK: if not self.is_block_context: color = self.current_layout.default_color else: color = self.current_block.color else: # BYOBJECT color = self._true_entity_color(entity.rgb, aci) if entity.dxftype() == 'HATCH': transparency = default_hatch_transparency else: transparency = entity.transparency alpha_float = 1.0 - transparency alpha = int(round(alpha_float * 255)) if alpha == 255: return color else: return _rgba(color, alpha)
def resolve_color(self, entity: 'DXFGraphic', *, resolved_layer: Optional[str] = None) -> Color: """ Resolve the rgb-color of `entity` as hex color string: "#RRGGBB" or "#RRGGBBAA". """ aci = entity.dxf.color # defaults to BYLAYER if aci == const.BYLAYER: entity_layer = resolved_layer or layer_key( self.resolve_layer(entity)) color = self.layers.get(entity_layer, DEFAULT_LAYER_PROPERTIES).color elif aci == const.BYBLOCK: if not self.inside_block_reference: color = self.current_layout.default_color else: color = self.current_block_reference.color else: # BYOBJECT color = self._true_entity_color(entity.rgb, aci) alpha = int(round((1.0 - entity.transparency) * 255)) if alpha == 255: return color else: return set_color_alpha(color, alpha)
def resolve_linetype(self, entity: 'DXFGraphic'): """ Resolve linetype of DXF `entity` """ aci = entity.dxf.color # Not sure if plotstyle table overrides actual entity setting? if (0 < aci < 256 ) and self.plot_styles[aci].linetype != acadctb.OBJECT_LINETYPE: pass # todo: return special line types - overriding linetypes by plotstyle table name = entity.dxf.linetype.upper() # default is 'BYLAYER' if name == 'BYLAYER': entity_layer = layer_key(entity.dxf.layer) # AutoCAD appears to treat layer 0 differently to other layers in this case. if self.is_block_context and entity_layer == '0': name = self.current_block.linetype_name pattern = self.current_block.linetype_pattern else: layer = self.layers.get(entity_layer, DEFAULT_LAYER_PROPERTIES) name = layer.linetype_name pattern = layer.linetype_pattern elif name == 'BYBLOCK': if self.is_block_context: name = self.current_block.linetype_name pattern = self.current_block.linetype_pattern else: # There is no default layout linetype name = 'STANDARD' pattern = CONTINUOUS_PATTERN else: pattern = self.line_pattern.get(name, CONTINUOUS_PATTERN) return name, pattern
def resolve_color(self, entity: 'DXFGraphic', *, resolved_layer: Optional[str] = None) -> Color: """ Resolve the rgb-color of `entity` as hex color string: "#RRGGBB" or "#RRGGBBAA". """ if entity.dxf.hasattr('true_color'): # An existing true color value always overrides ACI color! # Do not default to BYLAYER or BYBLOCK, this ACI value is ignored! aci = 7 else: aci = entity.dxf.color # defaults to BYLAYER if aci == const.BYLAYER: entity_layer = resolved_layer or layer_key( self.resolve_layer(entity)) layer = self.layers.get(entity_layer, DEFAULT_LAYER_PROPERTIES) color = layer.get_entity_color_from_layer( self.current_layout.default_color) elif aci == const.BYBLOCK: if not self.inside_block_reference: color = self.current_layout.default_color else: color = self.current_block_reference.color else: # BYOBJECT color = self._true_entity_color(entity.rgb, aci) alpha = int(round((1.0 - entity.transparency) * 255)) if alpha == 255: return color else: return set_color_alpha(color, alpha)
def resolve_color(self, entity: 'DXFGraphic', *, default_hatch_transparency: float = 0.8, resolved_layer: str = None) -> Color: """ Resolve color of DXF `entity` """ aci = entity.dxf.color # defaults to BYLAYER if aci == const.BYLAYER: entity_layer = resolved_layer or layer_key(self.resolve_layer(entity)) color = self.layers.get(entity_layer, DEFAULT_LAYER_PROPERTIES).color elif aci == const.BYBLOCK: if not self.inside_block_reference: color = self.current_layout.default_color else: color = self.current_block_reference.color else: # BYOBJECT color = self._true_entity_color(entity.rgb, aci) if entity.dxftype() == 'HATCH': transparency = default_hatch_transparency else: transparency = entity.transparency alpha_float = 1.0 - transparency alpha = int(round(alpha_float * 255)) if alpha == 255: return color else: return _rgba(color, alpha)
def resolve_lineweight(self, entity: 'DXFGraphic'): # Line weight in mm times 100 (e.g. 0.13mm = 13). # Smallest line weight is 0 and biggest line weight is 211 # The DWG format is limited to a fixed value table: 0, 5, 9, ... 200, 211 # DEFAULT: The LAYOUT entity has no explicit graphic properties. # BLOCK and BLOCK_RECORD entities also have no graphic properties. # Maybe XDATA or ExtensionDict in any of this entities. aci = entity.dxf.color # Not sure if plotstyle table overrides actual entity setting? if ( 0 < aci < 256 ) and self.plot_styles[aci].lineweight != acadctb.OBJECT_LINEWEIGHT: # overriding lineweight by plotstyle table return self.plot_styles.get_lineweight(aci) lineweight = entity.dxf.lineweight # default is BYLAYER if lineweight == const.LINEWEIGHT_BYLAYER: entity_layer = layer_key(entity.dxf.layer) # AutoCAD appears to treat layer 0 differently to other layers in this case. if self.is_block_context and entity_layer == '0': return self.current_block.lineweight else: return self.layers.get(entity_layer, DEFAULT_LAYER_PROPERTIES).lineweight elif lineweight == const.LINEWEIGHT_BYBLOCK: if self.is_block_context: return self.current_block.lineweight else: # There is no default layout lineweight return self.default_lineweight() elif lineweight == const.LINEWEIGHT_DEFAULT: return self.default_lineweight() else: return float(lineweight) / 100.0
def is_visible(self, entity: 'DXFGraphic') -> bool: if entity.dxf.invisible: return False layer_name = layer_key(entity.dxf.layer) layer = self.layers.get(layer_name) # todo: should we consider the plot flag too? if layer and not layer.is_visible: return False return True
def add_layer(self, layer: 'Layer') -> None: properties = LayerProperties() name = layer_key(layer.dxf.name) properties.layer = layer.dxf.name # store real layer name (mixed case) properties.color = self._true_layer_color(layer) properties.linetype_name = str(layer.dxf.linetype).upper() # normalize linetype names properties.linetype_pattern = self.line_pattern.get(properties.linetype_name, CONTINUOUS_PATTERN) properties.lineweight = self._true_layer_lineweight(layer.dxf.lineweight) properties.is_visible = layer.is_on() properties.plot = bool(layer.dxf.plot) self.layers[name] = properties
def resolve_visible(self, entity: 'DXFGraphic', *, resolved_layer: Optional[str] = None) -> bool: entity_layer = resolved_layer or layer_key(self.resolve_layer(entity)) layer_properties = self.layers.get(entity_layer) if layer_properties and not layer_properties.is_visible: return False elif entity.dxftype() == 'ATTRIB': return (not bool(entity.dxf.invisible) and not cast(Attrib, entity).is_invisible) else: return not bool(entity.dxf.invisible)
def set_layers_state(self, layers: Set[str], state=True): """ Set layer state of `layers` to on/off. Args: layers: set of layer names state: `True` turn this `layers` on and others off, `False` turn this `layers` off and others on """ layers = {layer_key(name) for name in layers} for name, layer in self.layers.items(): if name in layers: layer.is_visible = state else: layer.is_visible = not state
def resolve_all(self, entity: 'DXFGraphic') -> Properties: """ Resolve all properties for DXF `entity`. """ p = Properties() p.color = self.resolve_color(entity) p.linetype_name, p.linetype_pattern = self.resolve_linetype(entity) p.lineweight = self.resolve_lineweight(entity) dxf = entity.dxf p.linetype_scale = dxf.ltscale p.is_visible = not bool(dxf.invisible) p.layer = dxf.layer layer_name = layer_key(p.layer) layer = self.layers.get(layer_name) if layer and p.is_visible: p.is_visible = layer.is_visible return p
def add_layer(self, layer: 'Layer') -> None: properties = LayerProperties() name = layer_key(layer.dxf.name) # Store real layer name (mixed case): properties.layer = layer.dxf.name properties.color = self._true_layer_color(layer) # Normalize linetype names to UPPERCASE: properties.linetype_name = str(layer.dxf.linetype).upper() properties.linetype_pattern = self.line_pattern.get( properties.linetype_name, CONTINUOUS_PATTERN) properties.lineweight = self._true_layer_lineweight( layer.dxf.lineweight) properties.is_visible = layer.is_on() and not layer.is_frozen() if self.export_mode: properties.is_visible &= bool(layer.dxf.plot) self.layers[name] = properties
def resolve_all(self, entity: 'DXFGraphic') -> Properties: """ Resolve all properties of `entity`. """ p = Properties() p.layer = self.resolve_layer(entity) resolved_layer = layer_key(p.layer) p.units = self.resolve_units() p.color = self.resolve_color(entity, resolved_layer=resolved_layer) p.linetype_name, p.linetype_pattern = \ self.resolve_linetype(entity, resolved_layer=resolved_layer) p.lineweight = self.resolve_lineweight(entity, resolved_layer=resolved_layer) p.linetype_scale = self.resolve_linetype_scale(entity) p.is_visible = self.resolve_visible(entity, resolved_layer=resolved_layer) if entity.dxf.hasattr('style'): p.font = self.resolve_font(entity) if entity.dxftype() == 'HATCH': p.filling = self.resolve_filling(entity) return p
def resolve_all(self, entity: 'DXFGraphic') -> Properties: """ Resolve all properties for DXF `entity`. """ p = Properties() p.layer = self.resolve_layer(entity) resolved_layer = layer_key(p.layer) p.color = self.resolve_color(entity, resolved_layer=resolved_layer) p.linetype_name, p.linetype_pattern = self.resolve_linetype(entity, resolved_layer=resolved_layer) p.lineweight = self.resolve_lineweight(entity, resolved_layer=resolved_layer) dxf = entity.dxf p.linetype_scale = dxf.ltscale p.is_visible = not bool(dxf.invisible) layer = self.layers.get(resolved_layer) if layer and p.is_visible: p.is_visible = layer.is_visible if dxf.hasattr('style'): p.font = self.resolve_font(entity) if entity.dxftype() == 'HATCH': p.filling = self.resolve_filling(entity) return p
def add_layer(self, layer: 'Layer') -> None: """ Setup layer properties. """ properties = LayerProperties() name = layer_key(layer.dxf.name) # Store real layer name (mixed case): properties.layer = layer.dxf.name properties.color = self._true_layer_color(layer) # Depend layer ACI color from layout background color? # True color overrides ACI color and layers with only true color set # have default ACI color 7! if not layer.has_dxf_attrib('true_color'): properties.has_aci_color_7 = layer.dxf.color == 7 # Normalize linetype names to UPPERCASE: properties.linetype_name = str(layer.dxf.linetype).upper() properties.linetype_pattern = self.line_pattern.get( properties.linetype_name, CONTINUOUS_PATTERN) properties.lineweight = self._true_layer_lineweight( layer.dxf.lineweight) properties.is_visible = layer.is_on() and not layer.is_frozen() if self.export_mode: properties.is_visible &= bool(layer.dxf.plot) self.layers[name] = properties
def lineweight(): aci = entity.dxf.color # Not sure if plotstyle table overrides actual entity setting? if (0 < aci < 256) and self.plot_styles[ aci].lineweight != acadctb.OBJECT_LINEWEIGHT: # overriding lineweight by plotstyle table return self.plot_styles.get_lineweight(aci) lineweight = entity.dxf.lineweight # default is BYLAYER if lineweight == const.LINEWEIGHT_BYLAYER: entity_layer = resolved_layer or layer_key( self.resolve_layer(entity)) return self.layers.get(entity_layer, DEFAULT_LAYER_PROPERTIES).lineweight elif lineweight == const.LINEWEIGHT_BYBLOCK: if self.inside_block_reference: return self.current_block_reference.lineweight else: # There is no default layout lineweight return self.default_lineweight() elif lineweight == const.LINEWEIGHT_DEFAULT: return self.default_lineweight() else: return float(lineweight) / 100.0
def resolve_lineweight(self, entity: 'DXFGraphic', *, resolved_layer: str = None) -> float: """ Resolve the lineweight of `entity` in mm. DXF stores the lineweight in mm times 100 (e.g. 0.13mm = 13). The smallest line weight is 0 and the biggest line weight is 211. The DXF/DWG format is limited to a fixed value table, see: :attr:`ezdxf.lldxf.const.VALID_DXF_LINEWEIGHTS` """ aci = entity.dxf.color # Not sure if plotstyle table overrides actual entity setting? if ( 0 < aci < 256 ) and self.plot_styles[aci].lineweight != acadctb.OBJECT_LINEWEIGHT: # overriding lineweight by plotstyle table return self.plot_styles.get_lineweight(aci) lineweight = entity.dxf.lineweight # default is BYLAYER if lineweight == const.LINEWEIGHT_BYLAYER: entity_layer = resolved_layer or layer_key( self.resolve_layer(entity)) return self.layers.get(entity_layer, DEFAULT_LAYER_PROPERTIES).lineweight elif lineweight == const.LINEWEIGHT_BYBLOCK: if self.inside_block_reference: return self.current_block_reference.lineweight else: # There is no default layout lineweight return self.default_lineweight() elif lineweight == const.LINEWEIGHT_DEFAULT: return self.default_lineweight() else: return float(lineweight) / 100.0