def from_tags(tags): gdata = GradientData() try: index = tags.tag_index( 450) # required tag if hatch has gradient data except DXFValueError: raise DXFStructureError( "HATCH: Missing required DXF tag for gradient data (code=450)." ) # if tags[index].value == 0 hatch is a solid ???? first_color_value = True for code, value in tags[index:]: if code == 460: gdata.rotation = (value / math.pi) * 180. # radians to grad elif code == 461: gdata.centered = value elif code == 452: gdata.one_color = value elif code == 462: gdata.tint = value elif code == 470: gdata.name = value elif code == 421: # code == 63 color as ACI, can be ignored if first_color_value: gdata.color1 = int2rgb(value) first_color_value = False else: gdata.color2 = int2rgb(value) return gdata
def load_tags(cls, tags: Tags) -> 'Gradient': gdata = cls() assert tags[0].code == 450 gdata.kind = tags[0].value # 0 for solid - 1 for gradient first_color_value = True first_aci_value = True for code, value in tags: if code == 460: gdata.rotation = math.degrees(value) # radians to grad elif code == 461: gdata.centered = value elif code == 452: gdata.one_color = value elif code == 462: gdata.tint = value elif code == 470: gdata.name = value elif code == 63: if first_aci_value: gdata.aci1 = value first_aci_value = False else: gdata.aci2 = value elif code == 421: if first_color_value: gdata.color1 = int2rgb(value) first_color_value = False else: gdata.color2 = int2rgb(value) return gdata
def bgcolor(self): try: xdata_bgcolor = self.tags.get_xdata('HATCHBACKGROUNDCOLOR') except ValueError: return None color = xdata_bgcolor.get_first_value(1071, 0) return int2rgb(color)
def check_for_attributes(self, node, entity): scale = self.scale dxf = self.dxf translate_y = self.elements.device.unit_height if entity.rgb is not None: if isinstance(entity.rgb, tuple): node.stroke = Color(*entity.rgb) else: node.stroke = Color(entity.rgb) else: c = entity.dxf.color if c == 256: # Bylayer. if entity.dxf.layer in dxf.layers: layer = dxf.layers.get(entity.dxf.layer) c = layer.color try: if c == 7: color = Color( "black" ) # Color 7 is black on light backgrounds, light on black. else: color = Color(*int2rgb(DXF_DEFAULT_COLORS[c])) except Exception: color = Color("black") node.stroke = color node.matrix.post_scale(scale, scale) node.matrix.post_translate_y(translate_y) node.modified()
def rgb(self) -> Optional[Tuple[int, int, int]]: """ Returns RGB true color as (r, g, b) tuple or None if true_color is not set. """ if self.dxf.hasattr('true_color'): return int2rgb(self.dxf.get('true_color')) else: return None
def nearest_index(rgb_color): """Get the DXF color index for the color nearest to the RGB color.""" distances = [_distance(rgb_color, rgb.int2rgb(dxf_color)) for dxf_color in rgb.dxf_default_colors] min_dist = min(distances) idx_min = distances.index(min_dist) if idx_min == 0: idx_min = BLACK elif idx_min == 7: idx_min = WHITE return idx_min
def nearest_index(rgb_color): """Get the DXF color index for the color nearest to the RGB color.""" distances = [ _distance(rgb_color, rgb.int2rgb(dxf_color)) for dxf_color in rgb.dxf_default_colors ] min_dist = min(distances) idx_min = distances.index(min_dist) if idx_min == 0: idx_min = BLACK elif idx_min == 7: idx_min = WHITE return idx_min
def _load_plot_style_table(filename: str): # Each layout can have a different plot style table stored in Layout.dxf.current_style_sheet. # HEADER var $STYLESHEET stores the default ctb-file name try: ctb = acadctb.load(filename) except IOError: ctb = acadctb.new_ctb() # Colors in CTB files can be RGB colors but don't have to, # therefor initialize color without RGB values by the # default AutoCAD palette: for aci in range(1, 256): entry = ctb[aci] if entry.has_object_color(): # initialize with default AutoCAD palette entry.color = int2rgb(DXF_DEFAULT_COLORS[aci]) return ctb
def bgcolor(self) -> Optional['RGB']: """ Property background color as ``(r, g, b)`` tuple, rgb values in range 0..255 (read/write/del) usage:: color = hatch.bgcolor # get background color as (r, g, b) tuple hatch.bgcolor = (10, 20, 30) # set background color del hatch.bgcolor # delete background color """ try: xdata_bgcolor = self.get_xdata('HATCHBACKGROUNDCOLOR') except const.DXFValueError: return None color = xdata_bgcolor.get_first_value(1071, 0) return int2rgb(color)
def rgb(self): return int2rgb(self.get_dxf_attrib('true_color'))
def rgb(self) -> Tuple[int, int, int]: return int2rgb(self.get_dxf_attrib('true_color'))
def entity_to_svg(elements, dxf, entity, scale, translate_y): element = None try: entity.transform_to_wcs(entity.ocs()) except AttributeError: pass if entity.dxftype() == 'CIRCLE': element = Circle(center=entity.dxf.center, r=entity.dxf.radius) elif entity.dxftype() == 'ARC': circ = Circle(center=entity.dxf.center, r=entity.dxf.radius) start_angle = Angle.degrees(entity.dxf.start_angle) end_angle = Angle.degrees(entity.dxf.end_angle) if end_angle < start_angle: end_angle += Angle.turns(1) element = Path(circ.arc_angle(start_angle, end_angle)) elif entity.dxftype() == 'ELLIPSE': # TODO: needs more math, axis is vector, ratio is to minor. element = Ellipse( center=entity.dxf.center, # major axis is vector # ratio is the ratio of major to minor. start_point=entity.start_point, end_point=entity.end_point, start_angle=entity.dxf.start_param, end_angle=entity.dxf.end_param) elif entity.dxftype() == 'LINE': # https://ezdxf.readthedocs.io/en/stable/dxfentities/line.html element = SimpleLine(x1=entity.dxf.start[0], y1=entity.dxf.start[1], x2=entity.dxf.end[0], y2=entity.dxf.end[1]) elif entity.dxftype() == 'POLYLINE': # https://ezdxf.readthedocs.io/en/stable/dxfentities/lwpolyline.html if entity.is_2d_polyline: if not entity.has_arc: if entity.is_closed: element = Polygon([(p[0], p[1]) for p in entity.points()]) else: element = Polyline([(p[0], p[1]) for p in entity.points()]) else: element = Path() bulge = 0 for e in entity: point = e.dxf.location if bulge == 0: element.line((point[0], point[1])) else: element += Arc(start=element.current_point, end=(point[0], point[1]), bulge=bulge) bulge = e.dxf.bulge if entity.is_closed: if bulge == 0: element.closed() else: element += Arc(start=element.current_point, end=element.z_point, bulge=bulge) element.closed() elif entity.dxftype() == 'LWPOLYLINE': # https://ezdxf.readthedocs.io/en/stable/dxfentities/lwpolyline.html if not entity.has_arc: if entity.closed: element = Polygon(*[(p[0], p[1]) for p in entity]) else: element = Polyline(*[(p[0], p[1]) for p in entity]) else: element = Path() bulge = 0 for e in entity: if bulge == 0: element.line((e[0], e[1])) else: element += Arc(start=element.current_point, end=(e[0], e[1]), bulge=bulge) bulge = e[4] if entity.closed: if bulge == 0: element.closed() else: element += Arc(start=element.current_point, end=element.z_point, bulge=bulge) element.closed() elif entity.dxftype() == 'HATCH': # https://ezdxf.readthedocs.io/en/stable/dxfentities/hatch.html element = Path() if entity.bgcolor is not None: Path.fill = Color(entity.bgcolor) for p in entity.paths: if p.path_type_flags & 2: for v in p.vertices: element.line(v[0], v[1]) if p.is_closed: element.closed() else: for e in p.edges: if type(e) == "LineEdge": # https://ezdxf.readthedocs.io/en/stable/dxfentities/hatch.html#ezdxf.entities.LineEdge element.line(e.start, e.end) elif type(e) == "ArcEdge": # https://ezdxf.readthedocs.io/en/stable/dxfentities/hatch.html#ezdxf.entities.ArcEdge circ = Circle( center=e.center, radius=e.radius, ) element += circ.arc_angle( Angle.degrees(e.start_angle), Angle.degrees(e.end_angle)) elif type(e) == "EllipseEdge": # https://ezdxf.readthedocs.io/en/stable/dxfentities/hatch.html#ezdxf.entities.EllipseEdge element += Arc( radius=e.radius, start_angle=Angle.degrees(e.start_angle), end_angle=Angle.degrees(e.end_angle), ccw=e.is_counter_clockwise) elif type(e) == "SplineEdge": # https://ezdxf.readthedocs.io/en/stable/dxfentities/hatch.html#ezdxf.entities.SplineEdge if e.degree == 3: for i in range(len(e.knot_values)): control = e.control_values[i] knot = e.knot_values[i] element.quad(control, knot) elif e.degree == 4: for i in range(len(e.knot_values)): control1 = e.control_values[2 * i] control2 = e.control_values[2 * i + 1] knot = e.knot_values[i] element.cubic(control1, control2, knot) else: for i in range(len(e.knot_values)): knot = e.knot_values[i] element.line(knot) elif entity.dxftype() == 'IMAGE': bottom_left_position = entity.dxf.insert size = entity.dxf.image_size imagedef = entity.dxf.image_def_handle if not isinstance(imagedef, str): imagedef = imagedef.filename element = SVGImage(href=imagedef, x=bottom_left_position[0], y=bottom_left_position[1] - size[1], width=size[0], height=size[1]) elif entity.dxftype() == 'MTEXT': insert = entity.dxf.insert element = SVGText(x=insert[0], y=insert[1], text=entity.text) elif entity.dxftype() == 'TEXT': insert = entity.dxf.insert element = SVGText(x=insert[0], y=insert[1], text=entity.dxf.text) elif entity.dxftype() == 'SOLID' or entity.dxftype() == 'TRACE': # https://ezdxf.readthedocs.io/en/stable/dxfentities/solid.html element = Path() element.move((entity[0][0], entity[0][1])) element.line((entity[1][0], entity[1][1])) element.line((entity[2][0], entity[2][1])) element.line((entity[3][0], entity[3][1])) element.closed() element.fill = Color('Black') elif entity.dxftype() == 'SPLINE': element = Path() try: for b in entity.construction_tool().bezier_decomposition(): if len(element) == 0: element.move((b[0][0], b[0][1])) element.cubic((b[1][0], b[1][1]), (b[2][0], b[2][1]), (b[3][0], b[3][1])) except (AttributeError, TypeError): # Fallback for rational b-splines. try: for bezier in entity.construction_tool( ).cubic_bezier_approximation(4): b = bezier.control_points element.cubic((b[1][0], b[1][1]), (b[2][0], b[2][1]), (b[3][0], b[3][1])) except (AttributeError, TypeError): # Fallback for versions of EZDXF prior to 0.13 element.move(entity.control_points[0]) for i in range(1, entity.dxf.n_control_points): element.line(entity.control_points[i]) if entity.closed: element.closed() elif entity.dxftype() == 'INSERT': for e in entity.virtual_entities(): if e is None: continue DxfLoader.entity_to_svg(elements, dxf, e, scale, translate_y) return else: return # Might be something unsupported. from ezdxf.tools.rgb import DXF_DEFAULT_COLORS, int2rgb if entity.rgb is not None: if isinstance(entity.rgb, tuple): element.stroke = Color(*entity.rgb) else: element.stroke = Color(entity.rgb) else: c = entity.dxf.color if c == 256: # Bylayer. if entity.dxf.layer in dxf.layers: layer = dxf.layers.get(entity.dxf.layer) c = layer.color try: if c == 7: color = Color( "black" ) # Color 7 is black on light backgrounds, light on black. else: color = Color(*int2rgb(DXF_DEFAULT_COLORS[c])) except: color = Color('black') element.stroke = color element.transform.post_scale(scale, -scale) element.transform.post_translate_y(translate_y) if isinstance(element, SVGText): elements.append(element) else: element.values[ SVG_ATTR_VECTOR_EFFECT] = SVG_VALUE_NON_SCALING_STROKE path = abs(Path(element)) if len(path) != 0: if not isinstance(path[0], Move): path = Move(path.first_point) + path elements.append(path)
def test_rgb(self): r, g, b = int2rgb(0xA0B0C0) self.assertTrue(0xA0, r) self.assertTrue(0xB0, g) self.assertTrue(0xC0, b)
def get_layers(self): for layer in self.doc.layers: yield { 'name': layer.dxf.name, 'color': QColor(*int2rgb(DXF_DEFAULT_COLORS[layer.color])) }
def test_rgb(): r, g, b = int2rgb(0xA0B0C0) assert 0xA0 == r assert 0xB0 == g assert 0xC0 == b