def dstyle(self, name=''): if not name: raise SketchLoadError(_("unnamed style")) style = self.style.AsDynamicStyle() style.SetName(name) self.style_dict[name] = style self.style = Style()
def load_LTYPE(self): param = { '2': '', # Linetype name '3': '', # Descriptive text for linetype #'73': 0, # The number of linetype elements #'40': 0, # Total pattern length '49': [], # Dash, dot or space length (one entry per element) } param = self.read_param(param, [0]) name = upper(param['2']) if name: self.ltype_dict[name] = param dashes = [] for i in xrange(len(param['49'])): dashes.append(abs(param['49'][i]) * self.unit_to_pt) name3 = param['3'] #print name3, dashes if name3 and dashes: style = Style() style.line_dashes = tuple(dashes) style = style.AsDynamicStyle() style.SetName(name + name3) self.dynamic_style_dict[name] = style
def __init__(self, file, filename, match): GenericLoader.__init__(self, file, filename, match) self.file = file self.curstyle = Style() self.verbosity = 0 self.gdiobjects = [] self.dcstack = [] self.curpoint = Point(0, 0)
def use_style(self, name=''): if not name: raise SketchLoadError(_("unnamed style")) if not self.style.IsEmpty(): self.prop_stack.load_AddStyle(self.style) self.style = Style() style = self.style_dict[name] self.prop_stack.load_AddStyle(style)
def get_prop_stack(self): stack = self.prop_stack if not self.style.IsEmpty(): stack.load_AddStyle(self.style) stack.condense() if self.base_style is not None: self.prop_stack = PropertyStack(base=self.base_style.Duplicate()) else: self.prop_stack = PropertyStack() self.style = Style() return stack
def __init__(self, file, filename, match): LoaderWithComposites.__init__(self) self.file = file self.filename = filename self.match = match self.style = Style() if self.base_style is not None: self.prop_stack = PropertyStack(base=self.base_style.Duplicate()) else: self.prop_stack = PropertyStack() self.messages = {}
def initialize(self): self.draw = 0 self.scale = .283464566929 self.cur_x = 0.0 self.cur_y = 0.0 self.palette = Palette(self.basename) self.path = CreatePath() self.cur_style = Style() self.cur_style.line_width = 0.6 self.cur_style.line_join = const.JoinRound self.cur_style.line_cap = const.CapRound self.cur_style.line_pattern = self.palette.next_color(1)
def __init__(self, file, filename, match): GenericLoader.__init__(self, file, filename, match) self.file = file self.DWGCODEPAGE = 'latin1' self.unit_to_pt = 2.83464566929 self.dynamic_style_dict = {} self.style_dict = {} self.ltype_dict = { 'CONTINUOUS': { '2': 'CONTINUOUS', # Linetype name '3': 'Solid line', # Descriptive text for linetype '49': [], # Dash, dot or space length #(one entry per element) } } self.layer_dict = { '0': { '2': '0', # Layer name '6': 'CONTINUOUS', #Linetype name '62': 0, # Color number '370': None, #Line weight } } self.block_dict = {} self.stack = [] self.stack_trafo = [] self.default_layer = '0' self.default_style = 'STANDARD' self.default_block = None self.default_line_width = 30 self.EXTMIN = (1e+20, 1e+20) self.EXTMAX = (-1e+20, -1e+20) self.PEXTMIN = (1e+20, 1e+20) self.PEXTMAX = (-1e+20, -1e+20) self.general_param = { '8': self.default_layer, # Layer name '6': 'BYLAYER', # Linetype name '62': 256, # Color number '48': 1.0, # Linetype scale #'60': 0, # Object visibility. If 1 Invisible } self.curstyle = Style() self.update_trafo()
def initialize(self): self.curstyle = Style() self.curstyle.line_join = JoinRound self.curstyle.line_cap = CapRound self.cur_x = 0.0 self.cur_y = 0.0 self.draw = 0 self.absolute = 1 self.path = CreatePath() self.curpen = None self.penwidth = {} self.select_pen()
def get_line_style(self, **kw): if kw['8'] in self.layer_dict: self.default_layer = layer_name = kw['8'] else: layer_name = self.default_layer linetype_name = upper(kw['6']) scale = kw['48'] color_index = kw['62'] style = Style() style.line_width = self.get_line_width() style.line_join = const.JoinRound style.line_cap = const.CapRound style.line_dashes = self.get_line_type(linetype_name = linetype_name, scale = scale, width = style.line_width) style.line_pattern = self.get_pattern(color_index) return style
def styleFromFolder(path): print(path) assert (os.path.exists(path + "cfg.txt")) with open(path + "cfg.txt", "r") as f: lines = list(f) name = lines[0].strip() descr = lines[1].strip() if lines[2] == "CONV_NN": alg = Algorithms.Conv_NN else: alg = Algorithms.Cycle_GAN styleDir = path + lines[3].strip() styleImage = path + "style.jpg" if (os.path.exists(path + "preview.jpg")): previewImage = path + "preview.jpg" else: previewImage = None return Style(name=name, descr=descr, alg=alg, styleDir=styleDir, styleImage=styleImage, computed=True, previewImage=previewImage)
from app.io import load from app.conf import const from app.Graphics.color import ParseSketchColor, CreateCMYKColor, CreateRGBColor, CreateSPOTColor, \ CreateRGBAColor, CreateCMYKAColor, CreateSPOTAColor from app import SolidPattern, HatchingPattern,EmptyPattern, \ LinearGradient, ConicalGradient, RadialGradient, ImageTilePattern, \ Style, MultiGradient, Trafo, Translation, Point, \ GridLayer, GuideLayer, GuideLine, Arrow, CreatePath, StandardColors, \ GetFont from app.io.load import GenericLoader from app.Graphics import pagelayout, plugobj, blendgroup, text, image, eps,\ properties base_style = Style() base_style.fill_pattern = EmptyPattern base_style.fill_transform = 1 base_style.line_pattern = SolidPattern(StandardColors.black) base_style.line_width = 0.0 base_style.line_join = const.JoinMiter base_style.line_cap = const.CapButt base_style.line_dashes = () base_style.line_arrow1 = None base_style.line_arrow2 = None base_style.font = None base_style.font_size = 12.0 # sanity check: does base_style have all properties? for key in dir(properties.factory_defaults): if not hasattr(base_style, key):
class WMFLoader(GenericLoader): def __init__(self, file, filename, match): GenericLoader.__init__(self, file, filename, match) self.file = file self.curstyle = Style() self.verbosity = 0 self.gdiobjects = [] self.dcstack = [] self.curpoint = Point(0, 0) def _print(self, format, *args, **kw): if self.verbosity: try: if kw: text = format % kw elif args: text = format % args else: text = format except: text = string.join([format] + map(str, args)) if text[-1] != '\n': text = text + '\n' sys.stdout.write(text) def get_struct(self, format): size = calcsize(format) return unpack(format, self.file.read(size)) def get_int16(self): return self.get_struct('<h')[0] def get_int32(self): return self.get_struct('<i')[0] def read_headers(self): self.file.seek(0) placeable = self.file.read(calcsize(struct_placeable_header)) key, handle, left, top, right, bottom, inch, reserved, checksum\ = unpack(struct_placeable_header, placeable) if key != rx_magic: raise SketchLoadError(_("The file is not a placeable " "windows metafile")) self._print("The file is not a placeable windows metafile") sum = 0 for word in unpack('<10h', placeable[:20]): sum = sum ^ word if sum != checksum: #raise SketchLoadError(_("The file has an incorrect checksum")) self._print("The file has an incorrect checksum") self.inch = inch self.bbox = (left, top, right, bottom) factor = 72.0 / self.inch self.wx = self.wy = 0 self.wwidth = right - left self.wheight = bottom - top self.vx = self.vy = 0 self.vwidth = self.wwidth self.vheight = self.wheight self.base_trafo = Trafo(factor, 0, 0, -factor, 0, factor * self.vheight) self.update_trafo() header = self.file.read(calcsize(struct_wmf_header)) filetype, headersize, version, filesize, numobj, maxrecord, numparams\ = unpack(struct_wmf_header, header) self._print('\nHeader\n------\n') fmt = '% 10s: %s\n' self._print(fmt, 'inch', self.inch) self._print(fmt, 'bbox', self.bbox) self._print(fmt, 'headersize', headersize) self._print(fmt, 'version', version) self._print(fmt, 'numobj', numobj) self._print(fmt, 'numparams', numparams) self._print(fmt, 'maxrecord', maxrecord) self._print('\n') def update_trafo(self): wt = Translation(-self.wx, -self.wy) vt = Translation(self.vx, self.vy) scale = Scale(float(self.vwidth) / self.wwidth, float(self.vheight) / self.wheight) self.trafo = self.base_trafo(vt(scale(wt))) def add_gdiobject(self, object): try: idx = self.gdiobjects.index(None) except ValueError: self.gdiobjects.append(object) else: self.gdiobjects[idx] = object def delete_gdiobject(self, idx): self.gdiobjects[idx] = None def SelectObject(self): idx = self.get_int16() try: object = self.gdiobjects[idx] except IndexError: print 'Index Error:', idx, self.gdiobjects raise for property, value in object: setattr(self.curstyle, property, value) self._print('->', idx, object) def DeleteObject(self): idx = self.get_int16() self.delete_gdiobject(idx) self._print('->', idx) def get_dc(self): return self.curstyle.Duplicate(), self.trafo, self.curpoint def set_dc(self, dc): self.curstyle, self.trafo, self.curpoint = dc def SaveDC(self): self.dcstack.append(self.get_dc()) def RestoreDC(self): self.set_dc(self.dcstack[-1]) del self.dcstack[-1] def SetMapMode(self): mode = self.get_int16() self._print('->', mode) def SetWindowOrg(self): self.wy, self.wx = self.get_struct('<hh') self.update_trafo() self._print('->', self.wx, self.wy) def SetWindowExt(self): self.wheight, self.wwidth = self.get_struct('<hh') self.update_trafo() self._print('->', self.wwidth, self.wheight) def SetPolyFillMode(self): mode = self.get_int16() self._print('->', mode) SetBkMode = noop SetBkColor = noop SetROP2 = noop def CreateBrushIndirect(self): style, r, g, b, hatch = self.get_struct('<hBBBxh') if style == 1: pattern = EmptyPattern else: pattern = SolidPattern(CreateRGBColor(r/255.0, g/255.0, b/255.0)) self.add_gdiobject((('fill_pattern', pattern),)) self._print('->', style, r, g, b, hatch) def DibCreatePatternBrush(self): self.add_message(_("Bitmap brushes not yet implemented. Using black")) pattern = SolidPattern(StandardColors.black) self.add_gdiobject((('fill_pattern', pattern),)) def CreatePenIndirect(self): style, widthx, widthy, r, g, b = self.get_struct('<hhhBBBx') cap = (style & 0x0F00) >> 8 join = (style & 0x00F0) >> 4 style = style & 0x000F if style == 5: pattern = EmptyPattern else: pattern = SolidPattern(CreateRGBColor(r/255.0, g/255.0, b/255.0)) width = abs(widthx * self.trafo.m11) self.add_gdiobject((('line_pattern', pattern,), ('line_width', width))) self._print('->', style, widthx, widthy, r, g, b, cap, join) def CreatePalette(self): self.add_gdiobject((('ignore', None),)) def CreateRegion(self): self.add_gdiobject((('ignore', None),)) CreateFontIndirect = CreatePalette SelectPalette = noop RealizePalette = noop SetTextColor = noop SetTextAlign = noop SetTextJustification = noop SetStretchBltMode = noop def read_points(self, num): coords = self.get_struct('<' + num * 'hh') points = []; append = points.append trafo = self.trafo for i in range(0, 2 * num, 2): append(trafo(coords[i], coords[i + 1])) return points def Polyline(self): points = self.read_points(self.get_int16()) if points: path = CreatePath() map(path.AppendLine, points) self.prop_stack.AddStyle(self.curstyle.Duplicate()) self.prop_stack.SetProperty(fill_pattern = EmptyPattern) self.bezier((path,)) #for i in range(len(points)): # self._print('->', points[i]) def Polygon(self): points = self.read_points(self.get_int16()) if points: path = CreatePath() map(path.AppendLine, points) if path.Node(-1) != path.Node(0): #print 'correct polygon' path.AppendLine(path.Node(0)) path.load_close() self.prop_stack.AddStyle(self.curstyle.Duplicate()) self.bezier((path,)) #for i in range(len(points)): # self._print('->', points[i]) def PolyPolygon(self): nr_of_polygons = self.get_int16() nr_of_points = [] for i in range(nr_of_polygons): nr_of_points.append(self.get_int16()) path = () for i in nr_of_points: points = self.read_points(i) if points: subpath = CreatePath() map(subpath.AppendLine, points) if subpath.Node(-1) != subpath.Node(0): subpath.AppendLine(subpath.Node(0)) subpath.load_close() path = path + (subpath,) if path: self.prop_stack.AddStyle(self.curstyle.Duplicate()) self.bezier(path) def MoveTo(self): y, x = self.get_struct('<hh') self.curpoint = self.trafo(x, y) self._print('->', self.curpoint) def LineTo(self): y, x = self.get_struct('<hh') p = self.trafo(x, y) self.prop_stack.AddStyle(self.curstyle.Duplicate()) self.prop_stack.SetProperty(fill_pattern = EmptyPattern) path = CreatePath() path.AppendLine(self.curpoint) path.AppendLine(p) self.bezier((path,)) self.curpoint = p self._print('->', self.curpoint) def Ellipse(self): bottom, right, top, left = self.get_struct('<hhhh') left, top = self.trafo(left, top) right, bottom = self.trafo(right, bottom) self.prop_stack.AddStyle(self.curstyle.Duplicate()) self.ellipse((right - left) / 2, 0, 0, (bottom - top) / 2, (right + left) / 2, (top + bottom) / 2) def Arc(self, arc_type = const.ArcArc): ye, xe, ys, xs, bottom, right, top, left = self.get_struct('<hhhhhhhh') left, top = self.trafo(left, top) right, bottom = self.trafo(right, bottom) xs, ys = self.trafo(xs, ys) xe, ye = self.trafo(xe, ye) self.prop_stack.AddStyle(self.curstyle.Duplicate()) if arc_type == const.ArcArc: self.prop_stack.SetProperty(fill_pattern = EmptyPattern) if left != right and top != bottom: t = Trafo((right - left) / 2, 0, 0, (bottom - top) / 2, (right + left) / 2, (top + bottom) / 2).inverse() # swap start and end-angle end_angle = t(xs, ys).polar()[1] start_angle = t(xe, ye).polar()[1] else: start_angle = end_angle = 0.0 self.ellipse((right - left) / 2, 0, 0, (bottom - top) / 2, (right + left) / 2, (top + bottom) / 2, start_angle = start_angle, end_angle = end_angle, arc_type = arc_type) def Pie(self): self.Arc(const.ArcPieSlice) def Rectangle(self): bottom, right, top, left = self.get_struct('<hhhh') left, top = self.trafo(left, top) right, bottom = self.trafo(right, bottom) self.prop_stack.AddStyle(self.curstyle.Duplicate()) self.rectangle(right - left, 0, 0, bottom - top, left, top) def RoundRect(self): ellh, ellw, bottom, right, top, left = self.get_struct('<hhhhhh') left, top = self.trafo(left, top) right, bottom = self.trafo(right, bottom) ellw, ellh = self.trafo.DTransform(ellw, ellh) self._print('->', left, top, right, bottom, ellw, ellh) self.prop_stack.AddStyle(self.curstyle.Duplicate()) self.rectangle(right - left, 0, 0, bottom - top, left, top, radius1 = abs(ellw / (right - left)), radius2 = abs(ellh / (bottom - top))) def Escape(self): pass def interpret(self): tell = self.file.tell function = -1 while function: pos = tell() size, function = self.get_struct('<ih') self._print('%5d: %4x: %s' % (size, function, wmf_functions.get(function, ''))) if hasattr(self, wmf_functions.get(function, '')): getattr(self, wmf_functions[function])() else: if function: self.file.read(2 * (size - 3)) self._print('*** unimplemented:', wmf_functions.get(function, '')) pos = pos + 2 * size if tell() < pos: self.file.read(pos - tell()) elif tell() > pos: self._print('read too many bytes') self.file.seek(pos - tell(), 1) def Load(self): self.document() self.layer(name = _("WMF objects")) self.read_headers() self.interpret() self.end_all() self.object.load_Completed() return self.object
import struct import operator import copy import types from app import _, Trafo, Scale, Translation, Point, Polar, CreatePath, \ CreateRGBColor, SolidPattern, EmptyPattern, LinearGradient, \ MultiGradient, Style, const, StandardColors, GridLayer, GetFont, \ HatchingPattern from app.events.warn import INTERNAL, warn_tb from app.io.load import GenericLoader, SketchLoadError import uniconvertor from app.Graphics import text basestyle = Style() basestyle.fill_pattern = EmptyPattern basestyle.fill_transform = 1 basestyle.line_pattern = EmptyPattern basestyle.line_width = 1.0 basestyle.line_join = const.JoinMiter basestyle.line_cap = const.CapButt basestyle.line_dashes = () basestyle.line_arrow1 = None basestyle.line_arrow2 = None basestyle.font = None basestyle.font_size = 12.0 CGM_ID = { 0x0020: 'BEGMF',
class DSTLoader(GenericLoader): def __init__(self, file, filename, match): GenericLoader.__init__(self, file, filename, match) self.file = file self.basename, self.ext = os.path.splitext(filename) def initialize(self): self.draw = 0 self.scale = .283464566929 self.cur_x = 0.0 self.cur_y = 0.0 self.palette = Palette(self.basename) self.path = CreatePath() self.cur_style = Style() self.cur_style.line_width = 0.6 self.cur_style.line_join = const.JoinRound self.cur_style.line_cap = const.CapRound self.cur_style.line_pattern = self.palette.next_color(1) def readInt32(self, file): try: data = unpack('<I', file.read(4))[0] except: data = None return data def readInt8(self, file): try: data = int(unpack('B', file.read(1))[0]) except: data = None return data def get_position(self, x=None, y=None): if x is None: x = self.cur_x else: x = float(x) * self.scale + self.cur_x if y is None: y = self.cur_y else: y = float(y) * self.scale + self.cur_y return x, y def bezier(self): if self.path.len > 1: self.prop_stack.AddStyle(self.cur_style.Duplicate()) GenericLoader.bezier(self, paths=(self.path, )) self.path = CreatePath() def jump(self, x, y): x, y = self.get_position(x, y) self.cur_x = x self.cur_y = y def needle_move(self, x, y): if self.draw == 1: self.path.AppendLine(x, y) else: self.bezier() self.path.AppendLine(x, y) self.cur_x = x self.cur_y = y def needle_down(self, x=None, y=None): self.draw = 1 x, y = self.get_position(x, y) self.needle_move(x, y) def needle_up(self, x=None, y=None): if self.draw == 1: self.bezier() self.draw = 0 x, y = self.get_position(x, y) self.needle_move(x, y) def decode_x(self, d1, d2, d3): x = 1 * byte(d1, 7) - 1 * byte(d1, 6) + 9 * byte(d1, 5) - 9 * byte( d1, 4) x += 3 * byte(d2, 7) - 3 * byte(d2, 6) + 27 * byte(d2, 5) - 27 * byte( d2, 4) x += 81 * byte(d3, 5) - 81 * byte(d3, 4) return x def decode_y(self, d1, d2, d3): y = 1 * byte(d1, 0) - 1 * byte(d1, 1) + 9 * byte(d1, 2) - 9 * byte( d1, 3) y += 3 * byte(d2, 0) - 3 * byte(d2, 1) + 27 * byte(d2, 2) - 27 * byte( d2, 3) y += 81 * byte(d3, 2) - 81 * byte(d3, 3) return y def decode_flag(self, d3): if d3 == 243: return END if d3 & 195 == 3: return NORMAL elif d3 & 195 == 131: return JUMP elif d3 & 195 == 195: return CHANGECOLOR else: return UNKNOWN def readheader(self, file): file.seek(0) header = file.read(512).split('\r') dict = {} for i in header: if i[2] == ':': dict[i[0:2]] = i[3:].replace(' ', '') x = int(dict['-X']) y = int(dict['-Y']) self.jump(x, y) def Load(self): file = self.file fileinfo = os.stat(self.filename) totalsize = fileinfo[6] self.initialize() self.readheader(file) self.document() self.layer(name=_("DST_objects")) parsed = 0 parsed_interval = totalsize / 99 + 1 flag = UNKNOWN while 1: interval_count = file.tell() / parsed_interval if interval_count > parsed: parsed += 10 # 10% progress app.updateInfo(inf2='%u' % parsed + '% of file is parsed...', inf3=parsed) data = file.read(3) if len(data) < 3 or flag == 'END': self.needle_up() ## END INTERPRETATION app.updateInfo(inf2=_('Parsing is finished'), inf3=100) break d1, d2, d3 = unpack('BBB', data) x = self.decode_x(d1, d2, d3) y = self.decode_y(d1, d2, d3) #XXX swap coordinate x, y = y, x flag = self.decode_flag(d3) if flag == NORMAL: self.needle_down(x, y) elif flag == CHANGECOLOR: self.needle_up(x, y) self.cur_style.line_pattern = self.palette.next_color() elif flag == JUMP: #self.bezier() # cut the rope self.jump(x, y) self.end_all() self.object.load_Completed() return self.object
class GenericLoader(LoaderWithComposites): format_name = '' base_style = None def __init__(self, file, filename, match): LoaderWithComposites.__init__(self) self.file = file self.filename = filename self.match = match self.style = Style() if self.base_style is not None: self.prop_stack = PropertyStack(base=self.base_style.Duplicate()) else: self.prop_stack = PropertyStack() self.messages = {} def get_prop_stack(self): stack = self.prop_stack if not self.style.IsEmpty(): stack.load_AddStyle(self.style) stack.condense() if self.base_style is not None: self.prop_stack = PropertyStack(base=self.base_style.Duplicate()) else: self.prop_stack = PropertyStack() self.style = Style() return stack def set_prop_stack(self, stack): self.prop_stack = stack def document(self, *args, **kw): self.begin_composite(doc_class, args, kw) def layer(self, *args, **kw): self.begin_layer_class(layer.Layer, args, kw) def masterlayer(self, *args, **kw): kw['is_MasterLayer'] = 1 self.begin_layer_class(layer.Layer, args, kw) def page(self, *args, **kw): kw['is_Page'] = 1 self.begin_layer_class(layer.Layer, args, kw) def end_layer(self): self.end_composite() def begin_layer_class(self, layer_class, args, kw=None): if issubclass(self.composite_class, layer.Layer): self.end_composite() if issubclass(self.composite_class, doc_class): self.begin_composite(layer_class, args, kw) else: raise SketchLoadError('self.composite_class is %s, not a document', self.composite_class) def bezier(self, paths=None): self.append_object( PolyBezier(paths=paths, properties=self.get_prop_stack())) def rectangle(self, m11, m21, m12, m22, v1, v2, radius1=0, radius2=0): trafo = Trafo(m11, m21, m12, m22, v1, v2) self.append_object( Rectangle(trafo, radius1=radius1, radius2=radius2, properties=self.get_prop_stack())) def ellipse(self, m11, m21, m12, m22, v1, v2, start_angle=0.0, end_angle=0.0, arc_type=ArcPieSlice): self.append_object( Ellipse(Trafo(m11, m21, m12, m22, v1, v2), start_angle, end_angle, arc_type, properties=self.get_prop_stack())) def simple_text(self, str, trafo=None, valign=text.ALIGN_BASE, halign=text.ALIGN_LEFT): if type(trafo) == TupleType: if len(trafo) == 2: trafo = apply(Translation, trafo) else: raise TypeError, "trafo must be a Trafo-object or a 2-tuple" self.append_object( text.SimpleText(text=str, trafo=trafo, valign=valign, halign=halign, properties=self.get_prop_stack())) def image(self, image, trafo): if type(trafo) == TupleType: if len(trafo) == 2: trafo = apply(Translation, trafo) else: raise TypeError, "trafo must be a Trafo-object or a 2-tuple" image = ImageData(image) self.append_object(Image(image, trafo=trafo)) def begin_group(self, *args, **kw): self.begin_composite(group.Group, args, kw) def end_group(self): self.end_composite() def guess_cont(self): self.guess_continuity = 1 def end_composite(self): isdoc = self.composite_class is doc_class LoaderWithComposites.end_composite(self) if isdoc: self.add_meta(self.object) def add_meta(self, doc): doc.meta.fullpathname = self.filename dir, name = os.path.split(self.filename) doc.meta.directory = dir doc.meta.filename = name doc.meta.native_format = 0 doc.meta.format_name = self.format_name def add_message(self, message): pdebug(('load', 'echo_messages'), message) self.messages[message] = self.messages.get(message, 0) + 1 def Messages(self): messages = self.messages.items() list = [] for message, count in messages: if count > 1: list.append(_("%(message)s (%(count)d times)") % locals()) else: list.append(message) list.sort() return string.join(list, '\n')
class SKLoader(GenericLoader): format_name = format_name base_style = base_style functions = [ 'document', 'layer', 'masterlayer', 'page', ('bezier', 'b'), ('rectangle', 'r'), ('ellipse', 'e'), 'group', ('group', 'G'), 'endgroup', ('endgroup', 'G_'), 'guess_cont' ] def __init__(self, file, filename, match): GenericLoader.__init__(self, file, filename, match) if atoi(match.group('minor')) > 2: self.add_message( _("The file was created by a newer version" " of sK1, there might be inaccuracies.")) if self.filename: self.directory = os.path.split(filename)[0] else: self.directory = '' self.style_dict = {} self.id_dict = {} self.page_layout = None self.pattern = None self.gradient = None self.arrow1 = None self.arrow2 = None self.font = None self.font_size = 1.0 self.color_cache = {} def __del__(self): pass def warn(self, level, *args, **kw): message = apply(warn, (level, ) + args, kw) self.add_message(message) def get_func_dict(self): func_dict = {} for name in self.functions: if type(name) == StringType: func_dict[name] = getattr(self, name) else: func_dict[name[1]] = getattr(self, name[0]) return func_dict functions.append('layout') def layout(self, format, orientation): if type(format) == StringType: if format not in papersizes: # The format is given by name but it's not one of the # standard papersizes. The file may be corrupted. self.add_message( _("Unknown paper format '%s', " "using A4 instead") % format) format = "A4" layout = pagelayout.PageLayout(format, orientation=orientation) else: w, h = format layout = pagelayout.PageLayout(width=w, height=h, orientation=orientation) self.page_layout = layout functions.append('grid') def grid(self, geometry, visible=0, color=None, name=None): if name is None: name = _("Grid") self.begin_layer_class( GridLayer, (geometry, visible, self.convert_color(color), name)) self.end_composite() def convert_color(self, color_spec): try: c = self.color_cache.get(color_spec) if c: return c if color_spec[0] == 'RGB' and len(color_spec) == 4: c = CreateRGBColor(color_spec[1], color_spec[2], color_spec[3]) elif color_spec[0] == 'RGB' and len(color_spec) == 5: c = CreateRGBAColor(color_spec[1], color_spec[2], color_spec[3], color_spec[4]) elif color_spec[0] == 'CMYK' and len(color_spec) == 5: c = CreateCMYKColor(color_spec[1], color_spec[2], color_spec[3], color_spec[4]) elif color_spec[0] == 'CMYK' and len(color_spec) == 6: c = CreateCMYKAColor(color_spec[1], color_spec[2], color_spec[3], color_spec[4], color_spec[5]) elif color_spec[0] == 'SPOT' and len(color_spec) == 10: c = CreateSPOTColor(color_spec[3], color_spec[4], color_spec[5], color_spec[6], color_spec[7], color_spec[8], color_spec[9], color_spec[2], color_spec[1]) elif color_spec[0] == 'SPOT' and len(color_spec) == 11: c = CreateSPOTAColor(color_spec[3], color_spec[4], color_spec[5], color_spec[6], color_spec[7], color_spec[8], color_spec[9], color_spec[10], color_spec[2], color_spec[1]) else: c = apply(ParseSketchColor, color_spec) self.color_cache[color_spec] = c except: # This should only happen if the color_spec is invalid type, value = sys.exc_info()[:2] warn(INTERNAL, 'Color allocation failed: %s: %s', type, value) c = StandardColors.black return c functions.append('gl') def gl(self, colors): c = [] for pos, color in colors: c.append((pos, self.convert_color(color))) self.gradient = MultiGradient(c) functions.append('pe') def pe(self): self.pattern = EmptyPattern functions.append('ps') def ps(self, color): self.pattern = SolidPattern(self.convert_color(color)) functions.append('pgl') def pgl(self, dx, dy, border=0): if not self.gradient: raise SketchLoadError(_("No gradient for gradient pattern")) self.pattern = LinearGradient(self.gradient, Point(dx, dy), border) functions.append('pgr') def pgr(self, dx, dy, border=0): if not self.gradient: raise SketchLoadError(_("No gradient for gradient pattern")) self.pattern = RadialGradient(self.gradient, Point(dx, dy), border) functions.append('pgc') def pgc(self, cx, cy, dx, dy): if not self.gradient: raise SketchLoadError(_("No gradient for gradient pattern")) self.pattern = ConicalGradient(self.gradient, Point(cx, cy), Point(dx, dy)) functions.append('phs') def phs(self, color, background, dx, dy, dist, width): self.pattern = HatchingPattern(self.convert_color(color), self.convert_color(background), Point(dx, dy), dist, width) functions.append('pit') def pit(self, id, trafo): trafo = apply(Trafo, trafo) self.pattern = ImageTilePattern(self.id_dict[id], trafo) functions.append('fp') def fp(self, color=None): if color is None: self.style.fill_pattern = self.pattern else: self.style.fill_pattern = SolidPattern(self.convert_color(color)) functions.append('fe') def fe(self): self.style.fill_pattern = EmptyPattern functions.append('ft') def ft(self, bool): self.style.fill_transform = bool functions.append('lp') def lp(self, color=None): if color is None: self.style.line_pattern = self.pattern else: self.style.line_pattern = SolidPattern(self.convert_color(color)) functions.append('le') def le(self): self.style.line_pattern = EmptyPattern functions.append('lw') def lw(self, width): self.style.line_width = width functions.append('lj') def lj(self, join): self.style.line_join = join functions.append('lc') def lc(self, cap): if not 1 <= cap <= 3: self.add_message('line cap corrected from %d to 1' % cap) cap = 1 self.style.line_cap = cap functions.append('ld') def ld(self, dashes): self.style.line_dashes = dashes functions.append('la1') def la1(self, args=None): if args is not None: self.style.line_arrow1 = apply(Arrow, args) else: self.style.line_arrow1 = None functions.append('la2') def la2(self, args=None): if args is not None: self.style.line_arrow2 = apply(Arrow, args) else: self.style.line_arrow2 = None functions.append('dstyle') def dstyle(self, name=''): if not name: raise SketchLoadError(_("unnamed style")) style = self.style.AsDynamicStyle() style.SetName(name) self.style_dict[name] = style self.style = Style() functions.append(('use_style', 'style')) def use_style(self, name=''): if not name: raise SketchLoadError(_("unnamed style")) if not self.style.IsEmpty(): self.prop_stack.load_AddStyle(self.style) self.style = Style() style = self.style_dict[name] self.prop_stack.load_AddStyle(style) functions.append('Fn') def Fn(self, name): self.style.font = GetFont(name) functions.append('Fs') def Fs(self, size): self.style.font_size = size functions.append('guide') def guide(self, pos, horizontal): if horizontal: p = Point(0, pos) else: p = Point(pos, 0) self.append_object(GuideLine(p, horizontal)) functions.append('guidelayer') def guidelayer(self, *args, **kw): self.begin_layer_class(GuideLayer, args, kw) def bezier_load(self, line): bezier = self.object while 1: try: bezier.paths[-1].append_from_string(line) line = bezier.paths[-1].append_from_file(self.file) except: warn(INTERNAL, _("Error reading line %s"), ` line `) line = self.file.readline() if line[:2] == 'bC': bezier.paths[-1].load_close() line = self.file.readline() if line[:2] == 'bn': bezier.paths = bezier.paths + (CreatePath(), ) line = self.file.readline() else: break if line[:2] not in ('bs', 'bc'): break return line functions.append('txt') def txt(self, thetext, trafo, halign=text.ALIGN_LEFT, valign=text.ALIGN_BASE, chargap=1.0, wordgap=1.0, linegap=1.0): thetext = self.unicode_decoder(thetext) if len(trafo) == 2: trafo = Translation(trafo) else: trafo = apply(Trafo, trafo) object = text.SimpleText(text=thetext, trafo=trafo, halign=halign, valign=valign, properties=self.get_prop_stack()) object.properties.SetProperty(align=halign, valign=valign, chargap=chargap, wordgap=wordgap, linegap=linegap) self.append_object(object) def unicode_decoder(self, text): output = '' for word in text.split('\u')[1:]: num = int(word, 16) if num > 256: output += ('\u' + word).decode('raw_unicode_escape') else: output += chr(int(num)).decode('latin1') return output functions.append('im') def im(self, trafo, id): if len(trafo) == 2: trafo = Translation(trafo) else: trafo = apply(Trafo, trafo) self.append_object(image.Image(self.id_dict[id], trafo=trafo)) functions.append('bm') def bm(self, id, filename=None): if filename is None: from streamfilter import Base64Decode, SubFileDecode decoder = Base64Decode(SubFileDecode(self.file, '-')) data = image.load_image(decoder) else: data = image.load_image(os.path.join(self.directory, filename)) self.id_dict[id] = data functions.append('eps') def eps(self, trafo, filename): if len(trafo) == 2: trafo = Translation(trafo) else: trafo = apply(Trafo, trafo) if not os.path.isabs(filename): if self.directory: filename = os.path.join(self.directory, filename) else: filename = os.path.join(os.getcwd(), filename) self.append_object(eps.EpsImage(filename=filename, trafo=trafo)) functions.append('B') def B(self, *args, **kw): self.begin_composite(blendgroup.BlendGroup, args, kw) functions.append('B_') def B_(self): self.end_composite() functions.append('Bi') def Bi(self, *args, **kw): self.begin_composite(blendgroup.BlendInterpolation, args, kw) self.end_composite() group = GenericLoader.begin_group endgroup = GenericLoader.end_group functions.append('M') def M(self, *args, **kw): from app.Graphics import maskgroup self.begin_composite(maskgroup.MaskGroup, args, kw) functions.append('M_') def M_(self): self.end_composite() functions.append('PT') def PT(self, *args, **kw): self.begin_composite(text.PathText, args, kw) functions.append('pt') def pt(self, thetext, *args): matrix = () model = text.PATHTEXT_ROTATE start_pos = 0.0 if args: if type(args[0]) == TupleType: matrix = args[0] args = args[1:] if args: model = args[0] if len(args) > 1: start_pos = args[1] if matrix: trafo = apply(Trafo, matrix) else: trafo = None self.append_object( text.InternalPathText(thetext, trafo=trafo, model=model, start_pos=start_pos, properties=self.get_prop_stack())) functions.append('PT_') def PT_(self): self.end_composite() functions.append('PC') def PC(self, class_name, *args, **kw): kw['loading'] = 1 info = filters.find_object_plugin(class_name) if info is not None: try: theclass = info.Constructor() self.begin_composite(theclass, args, kw) return except SketchError: pass # constructing the plugin object failed. Use an UnknownPlugin # object. self.add_message(_("Unknown Plugin: %s") % class_name) self.begin_composite(plugobj.UnknownPlugin, (class_name, ) + args, kw) functions.append('PC_') def PC_(self): self.end_composite() # # The loader driver # def Load(self): file = self.file if type(file) == StringType: file = open(file, 'r') dict = self.get_func_dict() from app import skread parse = skread.parse_sk_line2 readline = file.readline bezier_load = self.bezier_load num = 1 line = '#' fileinfo = os.stat(self.filename) totalsize = fileinfo[6] interval = int((totalsize / 200) / 10) + 1 interval_count = 0 if __debug__: import time start_time = time.clock() try: line = readline() parsed = int(file.tell() * 100 / totalsize) app.updateInfo(inf2='%u' % parsed + '% of file is parsed...', inf3=parsed) while line: num = num + 1 if line[0] == 'b' and line[1] in 'sc': line = bezier_load(line) continue #parse(line, dict) funcname, args, kwargs = parse(line) if funcname is not None: function = dict.get(funcname) if function is not None: try: apply(function, args, kwargs) except TypeError: tb = sys.exc_info()[2] try: if tb.tb_next is None: # the exception was raised by apply # and not within the function. Try to # invoke the function with fewer # arguments if call_function(function, args, kwargs): message = _("Omitted some arguments " "for function %s") else: message = _("Cannot call function %s") self.add_message(message % function.__name__) else: raise finally: del tb else: self.add_message(_("Unknown function %s") % funcname) line = readline() interval_count += 1 if interval_count > interval: interval_count = 0 parsed = int(file.tell() * 100 / totalsize) app.updateInfo(inf2='%u' % parsed + '% of file is parsed...', inf3=parsed) except (SketchLoadError, SyntaxError), value: # a loader specific error occurred warn_tb(INTERNAL, 'error in line %d', num) if load._dont_handle_exceptions: raise else: raise SketchLoadError('%d:%s' % (num, value)) except:
class DXFLoader(GenericLoader): functions={ "POP_TRAFO": 'pop_trafo', "TABLE": 'load_TABLE', "BLOCK": 'load_BLOCK', "LINE": 'load_line', "LWPOLYLINE": 'load_lwpolyline', "POLYLINE": 'load_polyline', "SEQEND": 'load_seqend', "VERTEX": 'load_vertex', "CIRCLE": 'load_circle', "ARC": 'load_arc', "ELLIPSE": 'load_ellips', "POINT": 'load_point', "SOLID": 'load_solid', "INSERT": 'load_insert', "TEXT": 'load_text', #"MTEXT": 'load_text', "3DFACE": 'load_3dface', "SPLINE": 'load_spline', "VIEWPORT": 'load_bypass', } def __init__(self, file, filename, match): GenericLoader.__init__(self, file, filename, match) self.file = file self.DWGCODEPAGE = 'latin1' self.unit_to_pt = 2.83464566929 self.dynamic_style_dict = {} self.style_dict = {} self.ltype_dict = {'CONTINUOUS': { '2': 'CONTINUOUS', # Linetype name '3': 'Solid line', # Descriptive text for linetype '49': [], # Dash, dot or space length #(one entry per element) } } self.layer_dict = {'0': { '2': '0', # Layer name '6': 'CONTINUOUS', #Linetype name '62': 0, # Color number '370': None, #Line weight } } self.block_dict = {} self.stack = [] self.stack_trafo = [] self.default_layer = '0' self.default_style = 'STANDARD' self.default_block = None self.default_line_width = 30 self.EXTMIN = (1e+20, 1e+20) self.EXTMAX = (-1e+20, -1e+20) self.PEXTMIN = (1e+20, 1e+20) self.PEXTMAX = (-1e+20, -1e+20) self.general_param = { '8': self.default_layer, # Layer name '6': 'BYLAYER', # Linetype name '62': 256, # Color number '48': 1.0, # Linetype scale #'60': 0, # Object visibility. If 1 Invisible } self.curstyle = Style() self.update_trafo() def update_trafo(self, scale = 1): EXT_hight = self.EXTMAX[0] - self.EXTMIN[0] EXT_width = self.EXTMAX[1] - self.EXTMIN[1] PEXT_hight = self.PEXTMAX[0] - self.PEXTMIN[0] PEXT_width = self.PEXTMAX[1] - self.PEXTMIN[1] if EXT_hight > 0: scale = 840 / max(EXT_hight, EXT_width) self.unit_to_pt = scale x = self.EXTMIN[0] * scale y = self.EXTMIN[1] * scale elif PEXT_hight > 0: scale = 840 / max(PEXT_hight, PEXT_width) self.unit_to_pt = scale x = self.PEXTMIN[0] * scale y = self.PEXTMIN[1] * scale else: x = 0 y = 0 self.trafo = Trafo(scale, 0, 0, scale, -x, -y) def push_trafo(self, trafo = None): # save trafo in stack_trafo if trafo is None: trafo = self.trafo self.stack_trafo.append(trafo) def pop_trafo(self): self.trafo = self.stack_trafo.pop() def get_pattern(self, color_index): # 0 = Color BYBLOCK if color_index == 0: block_name = self.default_block if block_name is None: layer_name = '0' else: layer_name = self.block_dict[block_name]['8'] color_index = self.layer_dict[layer_name]['62'] # 256 = Color BYLAYER if color_index == 256 or color_index is None: layer_name = self.default_layer color_index = self.layer_dict[layer_name]['62'] ## FIXMY 257 = Color BYENTITY if color_index < 0: pattern = EmptyPattern else: pattern = SolidPattern(colors[color_index]) return pattern def get_line_width(self, layer_name = None): if layer_name is None: layer_name = self.default_layer layer = self.layer_dict[layer_name] if '370' in layer: width = layer['370'] if width == -3 or width is None: width = self.default_line_width width = width * 72.0 / 2.54 /1000 # th 100 mm to pt if width <= 0.0: # XXX width = 0.1 return width def get_line_type(self, linetype_name = None, scale = 1.0, width = 1.0, layer_name = None): #if linetype_name == 'BYBLOCK': #block_name = self.default_block #layer_name = self.block_dict[block_name]['8'] if layer_name is None: layer_name = self.default_layer if linetype_name is None or linetype_name == 'BYLAYER' or linetype_name == 'BYBLOCK': linetype_name = self.layer_dict[layer_name]['6'] linetype = self.ltype_dict[upper(linetype_name)]['49'] lscale = scale * self.unit_to_pt / width dashes = map(lambda i : abs(linetype[i]) * lscale, xrange(len(linetype))) return tuple(dashes) def get_line_style(self, **kw): if kw['8'] in self.layer_dict: self.default_layer = layer_name = kw['8'] else: layer_name = self.default_layer linetype_name = upper(kw['6']) scale = kw['48'] color_index = kw['62'] style = Style() style.line_width = self.get_line_width() style.line_join = const.JoinRound style.line_cap = const.CapRound style.line_dashes = self.get_line_type(linetype_name = linetype_name, scale = scale, width = style.line_width) style.line_pattern = self.get_pattern(color_index) return style ################ # HEADER Section # def load_HEADER(self): return_code = False header_dict = {} variable = None params = {} line1, line2 = self.read_record() while line1 or line2: if variable and (line1 == '9' or line1 == '0'): header_dict[variable] = params else: params[line1] = line2 if line1 == '0' and line2 == 'ENDSEC': return_code = True break elif line1 == '9': params = {} variable = line2 line1, line2 = self.read_record() return return_code, header_dict def process_header(self, header): if '$DWGCODEPAGE' in header: self.DWGCODEPAGE = 'cp'+ upper(header['$DWGCODEPAGE']['3']).replace('ANSI_', '').replace('DOS','') if '$INSUNITS' in header: INSUNITS = convert('70', header['$INSUNITS']['70']) if INSUNITS in unit: self.unit_to_pt = unit[INSUNITS] if '$EXTMIN' in header: param10 = convert('10', header['$EXTMIN']['10']) param20 = convert('20', header['$EXTMIN']['20']) self.EXTMIN = (param10, param20) if '$EXTMAX' in header: param10 = convert('10', header['$EXTMAX']['10']) param20 = convert('20', header['$EXTMAX']['20']) self.EXTMAX = (param10, param20) if '$PEXTMIN' in header: param10 = convert('10', header['$PEXTMIN']['10']) param20 = convert('20', header['$PEXTMIN']['20']) self.PEXTMIN = (param10, param20) if '$PEXTMAX' in header: param10 = convert('10', header['$PEXTMAX']['10']) param20 = convert('20', header['$PEXTMAX']['20']) self.PEXTMAX = (param10, param20) self.update_trafo() if '$CLAYER' in header: self.default_layer = convert('8', header['$CLAYER']['8'], self.DWGCODEPAGE) ################ # TABLES Section # def load_TABLE(self): param={ '2': '', # Table name '70': 0 # Maximum number of entries in table } param = self.read_param(param) table_name = param['2'] table_number = param['70'] print '****', table_name, table_number line1, line2 = self.read_record() while line1 or line2: if line1 == '0' and line2 == 'ENDTAB': break if table_name == 'LTYPE': self.load_LTYPE() elif table_name == 'LAYER': self.load_LAYER() elif table_name == 'STYLE': self.load_STYLE() line1, line2 = self.read_record() def load_LTYPE(self): param={ '2': '', # Linetype name '3': '', # Descriptive text for linetype #'73': 0, # The number of linetype elements #'40': 0, # Total pattern length '49': [], # Dash, dot or space length (one entry per element) } param = self.read_param(param, [0]) name = upper(param['2']) if name: self.ltype_dict[name] = param dashes = [] for i in xrange(len(param['49'])): dashes.append(abs(param['49'][i]) * self.unit_to_pt) name3 = param['3'] #print name3, dashes if name3 and dashes: style = Style() style.line_dashes = tuple(dashes) style = style.AsDynamicStyle() style.SetName(name + name3) self.dynamic_style_dict[name] = style def load_LAYER(self): param={ '2': None, # Layer name '6': None, #Linetype name '62': 0, # Color number '370': None, #Line weight } param = self.read_param(param, [0]) layer_name = param['2'] if layer_name: self.layer_dict[layer_name]=param self.layer(name = layer_name) def load_STYLE(self): param={ '2': None, # Style name '70': 0, # Flag '40': 0.0, # Fixed text height; 0 if not fixed '41': 0.0, # Width factor '42': 0.0, # Last height used '50': 0.0, # Oblique angle '71': 0, # Text generation flags '3': None, # Primary font file name '4': None, # Bigfont file name '1000': None, } param = self.read_param(param, [0]) style_name = upper(param['2']) self.style_dict[style_name] = param ################ # BLOCKS Section # def load_BLOCK(self): param={ '2': '', # Block name '10': 0.0, # X Base point '20': 0.0, # Y Base point #'30': 0.0, # Z Base point '8': self.default_layer, # Layer name 'data': [], # block data } param = self.read_param(param) block_name = param['2'] print '****', block_name line1, line2 = self.read_record() while line1 or line2: if line1 == '0' and line2 == 'ENDBLK': param = self.read_param(param) break param['data'].append(line1) param['data'].append(line2) line1, line2 = self.read_record() param['data'].reverse() self.block_dict[block_name] = param # print self.block_dict[block_name] ################ # ENTITIES Section # def load_line(self): param={ '10': None, # X coordinat '20': None, # y coordinat #'30': None, # Z coordinat '11': None, # X coordinat endpoint '21': None, # y coordinat endpoint #'31': None, # z coordinat endpoint } param.update(self.general_param) param = self.read_param(param) self.path = CreatePath() self.path.AppendLine(self.trafo(param['10'], param['20'])) self.path.AppendLine(self.trafo(param['11'], param['21'])) style = self.get_line_style(**param) self.prop_stack.AddStyle(style.Duplicate()) self.bezier(self.path,) def load_lwpolyline(self): param={ '90': 0, # Number of vertices '70': 0, # bit codes for Polyline entity '40': None, # Starting width '43': 0, '370': None, #Line weight } param.update(self.general_param) param = self.read_param(param,[10,20,42]) if param['40'] is not None: line_width = param['40'] * self.unit_to_pt else: line_width = param['43'] * self.unit_to_pt if param['370'] is not None: line_width = param['370'] * self.unit_to_pt * 72.0 / 2.54 /1000 self.curstyle = self.get_line_style(**param) # if Group 70 Flag bit value set 1 This is a closed Polyline path_flag = param['70'] vertex_path = [] for i in xrange(param['90']): vertex={ '10': None, # X coordinat '20': None, # Y coordinat '42': 0.0 # Bulge } # 10 line1, line2 = self.read_record() vertex[line1] = convert(line1, line2, self.DWGCODEPAGE) # 20 line1, line2 = self.read_record() vertex[line1] = convert(line1, line2, self.DWGCODEPAGE) # 42 line1, line2 = self.read_record() if line1 == '42': vertex[line1] = convert(line1, line2, self.DWGCODEPAGE) else: self.push_record(line1, line2) vertex_path.append((vertex['10'], vertex['20'], vertex['42'])) self.load_seqend(vertex_path, path_flag) def load_polyline(self): param={ '70': 0, # bit codes for Polyline entity '40': 0.01, #XXX FIXMY } param.update(self.general_param) param = self.read_param(param) self.vertex_path = [] self.curstyle.line_width=param['40'] * 72 # XXX self.unit_to_pt self.curstyle.line_pattern = self.get_pattern(param['62']) # if Group 70 Flag bit value set 1 This is a closed Polyline self.path_flag = param['70'] def load_vertex(self): param={#'62': 7, # color #'6': 'CONTINUOUS', # style '10': None, # X coordinat '20': None, # Y coordinat '42': 0.0 # Bulge } param = self.read_param(param) self.vertex_path.append((param['10'], param['20'], param['42'])) def load_seqend(self, line = None, path_flag = None): if line is None: line = self.vertex_path if path_flag is None: path_flag = self.path_flag if path_flag > 1: print 'FIXMY. Curves and smooth surface type', path_flag close_path = path_flag & 1 == 1 path = CreatePath() if len(line): for i in line: x, y, bulge = i #print x, y, bulge path.AppendLine(self.trafo(x, y)) if close_path: if path.Node(0) != path.Node(-1): path.AppendLine(path.Node(0)) path.ClosePath() self.prop_stack.AddStyle(self.curstyle.Duplicate()) self.bezier(path,) def load_circle(self): param={ '10': None, # X coordinat center '20': None, # Y coordinat center #'30': None, # Z coordinat center '40': 0.0 # radius } param.update(self.general_param) param = self.read_param(param) x = param['10'] y = param['20'] r = param['40'] t = self.trafo(Trafo(r,0,0,r,x,y)) style = self.get_line_style(**param) self.prop_stack.AddStyle(style.Duplicate()) apply(self.ellipse, t.coeff()) def load_arc(self): param={ '10': None, # X coordinat center '20': None, # Y coordinat center #'30': None, # Z coordinat center '40': 0.0, # radius '50': 0.0, # Start angle '51': 0.0 # End angle } param.update(self.general_param) param = self.read_param(param) cx = param['10'] cy = param['20'] rx = ry = param['40'] start_angle = param['50'] * degrees end_angle = param['51'] * degrees trafo = self.trafo(Trafo(rx, 0, 0, ry, cx, cy)) rx, w1, w2, ry, cx, cy = trafo.coeff() style = self.get_line_style(**param) self.prop_stack.AddStyle(style.Duplicate()) apply(self.ellipse, (rx, w1, w2, ry, cx, cy, start_angle, end_angle, ArcArc)) def load_ellips(self): param={ '10': 0.0, # X coordinat center '20': 0.0, # Y coordinat center #'30': 0.0, # Z coordinat center '11': 0.0, # Endpoint of major axis, relative to the center '21': 0.0, #'31': 0.0, '40': 0.0, # Ratio of minor axis to major axis '41': 0.0, # Start parameter (this value is 0.0 for a full ellipse) '42': 0.0, # End parameter (this value is 2pi for a full ellipse) } param.update(self.general_param) param = self.read_param(param) cx = param['10'] cy = param['20'] rx = sqrt(param['21']**2 + param['11']**2) ry = rx * param['40'] start_angle = param['41'] end_angle = param['42'] angle=atan2(param['21'], param['11']) center = self.trafo(cx, cy) radius = self.trafo.DTransform(rx, ry) trafo = Trafo(radius.x, 0, 0, radius.y) trafo = Rotation(angle)(trafo) trafo = Translation(center)(trafo) rx, w1, w2, ry, cx, cy = trafo.coeff() style = self.get_line_style(**param) self.prop_stack.AddStyle(style.Duplicate()) apply(self.ellipse, (rx, w1, w2, ry, cx, cy, start_angle, end_angle, ArcArc)) def load_point(self): param={ '10': None, # X coordinat center '20': None, # Y coordinat center #'30': None, # Z coordinat center } param.update(self.general_param) param = self.read_param(param) x = param['10'] y = param['20'] r = 0.3 t = self.trafo(Trafo(r,0,0,r,x,y)) style = self.curstyle.Duplicate() style.line_pattern = EmptyPattern style.fill_pattern = self.get_pattern(param['62']) self.prop_stack.AddStyle(style.Duplicate()) apply(self.ellipse, t.coeff()) def load_solid(self): param={ '10': None, '20': None, #'30': None, '11': None, '21': None, #'31': None, '12': None, '22': None, #'32': None, '13': None, '23': None, #'33': None, } param.update(self.general_param) param = self.read_param(param) style = self.curstyle.Duplicate() style.line_pattern = EmptyPattern style.fill_pattern = self.get_pattern(param['62']) self.path = CreatePath() self.path.AppendLine(self.trafo(param['10'], param['20'])) self.path.AppendLine(self.trafo(param['11'], param['21'])) self.path.AppendLine(self.trafo(param['12'], param['22'])) self.path.AppendLine(self.trafo(param['13'], param['23'])) self.path.ClosePath() self.prop_stack.AddStyle(style.Duplicate()) self.bezier(self.path,) def load_insert(self): param={ '2': None, # Block name '10': 0.0, # X coordinat '20': 0.0, # Y coordinat #'30': 0.0, # Z coordinat '41': 1.0, # X scale factor '42': 1.0, # Y scale factor #'43': 1.0, # Z scale factor '50': 0.0, # Rotation angle '66': 0, # Attributes-follow flag } param = self.read_param(param) block_name = self.default_block = param['2'] if block_name: self.stack += ['POP_TRAFO', '0'] + self.block_dict[block_name]['data'] self.push_trafo() x = param['10'] y = param['20'] block_x = self.block_dict[block_name]['10'] block_y = self.block_dict[block_name]['20'] scale_x = param['41'] * self.trafo.m11 scale_y = param['42'] * self.trafo.m22 angle = param['50'] * degrees translate = self.trafo(x, y) trafo = Trafo(1, 0, 0, 1, -block_x, -block_y) trafo = Scale(scale_x,scale_y)(trafo) trafo = Rotation(angle)(trafo) trafo = Translation(translate)(trafo) self.trafo = trafo if param['66'] != 0: line1, line2 = self.read_record() while line1 or line2: if line1 == '0' and line2 == 'SEQEND': break else: if line1 == '0': self.run(line2) line1, line2 = self.read_record() def load_text(self): param={ '10': 0.0, '20': 0.0, '40': None, # Text height '1': '', # Default value '50': 0, # Text rotation '41': 1, # Relative X scale factor—width # '8': self.default_layer, # Layer name '7': self.default_style, # Style name '72': 0, #Horizontal text justification type } param.update(self.general_param) param = self.read_param(param) x = param['10'] y = param['20'] scale_x = param['41'] scale_y = 1 angle = param['50'] * pi / 180 font_size = param['40'] * self.trafo.m11 halign = [ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT, \ ALIGN_LEFT, ALIGN_LEFT, ALIGN_LEFT][param['72']] text = unicode_decoder(param['1'], self.DWGCODEPAGE) #style = self.style_dict[param['7']] # print style style_text = self.curstyle.Duplicate() style_text.line_pattern = EmptyPattern style_text.fill_pattern = self.get_pattern(param['62']) style_name = upper(param['7']) style = self.style_dict[style_name] font_name = style['1000'] if font_name == 'Arial': # XXX font_name = 'ArialMT' style_text.font = GetFont(font_name) # print style_text.font style_text.font_size = font_size trafo_text = Translation(self.trafo(x, y))(Rotation(angle))(Scale(scale_x, scale_y)) self.prop_stack.AddStyle(style_text.Duplicate()) self.simple_text(strip(text), trafo_text, halign = halign) def load_3dface(self): param={ '10': None, '20': None, #'30': None, '11': None, '21': None, #'31': None, '12': None, '22': None, #'32': None, '13': None, '23': None, #'33': None, '70': 0, # Invisible edge flags } param.update(self.general_param) param = self.read_param(param) self.path = CreatePath() if param['70'] != 0: print 'FIXMY. 3dface Invisible edge flags', param['70'] self.path.AppendLine(self.trafo(param['10'], param['20'])) self.path.AppendLine(self.trafo(param['11'], param['21'])) self.path.AppendLine(self.trafo(param['12'], param['22'])) self.path.AppendLine(self.trafo(param['13'], param['23'])) self.path.ClosePath() style = self.get_line_style(**param) self.prop_stack.AddStyle(style.Duplicate()) self.bezier(self.path,) def load_spline(self): param={ '70': 0, # Spline flag '71': 0, # Degree of the spline curve '72': 0, # Number of knots '73': 0, # Number of control points '74': 0, # Number of fit points '40': [], # Knot value '10': [], # Control points X '20': [], # Control points Y #'30': [], # Control points Z } param.update(self.general_param) param = self.read_param(param) closed = param['70'] & 1 path = CreatePath() f13 = 1.0 / 3.0 f23 = 2.0 / 3.0 curve = path.AppendBezier straight = path.AppendLine pts = map(lambda x, y: self.trafo(x, y), param['10'],param['20']) print 'SPLINE', param['70'], len(pts) #for i in range(0, len(pts)-1): #self.ellipse(.2, 0, 0, .2, pts[i][0],pts[i][1]) if param['70'] <= 1: straight(pts[0]) for i in range(1, len(pts) / 4): node = pts[i * 4] c1 = pts[i * 4 - 3] c2 = pts[i * 4 - 2] print c1, c2, node curve(c1, c2, node) #straight(node) if closed: curve(pts[-3], pts[-2], pts[0]) else: curve(pts[-4], pts[-4], pts[-1]) if param['70'] & 4 == 4: last = pts[0] cur = pts[1] start = node = (last + cur) / 2 if closed: straight(node) else: straight(last) straight(node) last = cur for cur in pts[2:]: c1 = f13 * node + f23 * last node = (last + cur) / 2 c2 = f13 * node + f23 * last curve(c1, c2, node) last = cur if closed: curve(f13 * node + f23 * last, f13 * start + f23 * last, start) else: straight(last) if param['70'] & 8 == 8: node = pts[0] c1 = pts[1] c2 = pts[2] # first node straight(node) if len(pts) > 4: c2 = (pts[2] + pts[1]) / 2 c3 = pts[3] * f13 + pts[2] * f23 node = (c3 + c2) / 2 curve(c1, c2, node) c1 = c3 for i in range(3, len(pts) - 3): c2 = pts[i - 1] * f13 + pts[i] * f23 c3 = pts[i] * f23 + pts[i + 1] * f13 node = (c3 + c2) / 2 curve(c1, c2, node) c1 = c3 c2 = pts[-4] * f13 + pts[-3] * f23 c3 = (pts[-3] + pts[-2]) / 2 node = (c3 + c2) / 2 curve(c1, c2, node) c1 = c3 # last node curve(c1, pts[-2], pts[-1]) style = self.get_line_style(**param) self.prop_stack.AddStyle(style.Duplicate()) self.bezier(path,) def load_bypass(self): pass ########################################################################### def get_compiled(self): funclist={} for char, name in self.functions.items(): method = getattr(self, name) argc = method.im_func.func_code.co_argcount - 1 funclist[char] = (method, argc) return funclist def push_record(self, line1, line2): # save data in stack self.stack.append(line2) self.stack.append(line1) def read_record(self): # if the stack is empty read two lines from a file if self.stack: line1 = self.stack.pop() line2 = self.stack.pop() else: line1 = self.file.readline().strip() line2 = self.file.readline().strip() return line1, line2 def read_param(self, param, stop=None): # read data and fill in the dictionary if stop is None: stop = [0, 9] line1, line2 = self.read_record() while line1 or line2: if int(line1) in stop: self.push_record(line1, line2) return param else: if line1 in param: value = convert(line1, line2, self.DWGCODEPAGE) if type(param[line1]) == list: param[line1].append(value) else: param[line1] = value line1,line2 = self.read_record() return False def find_record(self, code1, code2): # read data until to not overlap line1 == code1 and line2 == code2 # return True # else return False line1, line2 = self.read_record() while line1 or line2: if line1 == code1 and line2 == code2: return True line1, line2 = self.read_record() return False def load_section(self): return_code = False file = self.file parsed = self.parsed parsed_interval = self.parsed_interval line1, line2 = self.read_record() while line1 or line2: interval_count = file.tell() / parsed_interval if interval_count > parsed: parsed += 10 # 10% progress app.updateInfo(inf2 = '%u' % parsed + _('% of file is parsed...'), inf3 = parsed) if line1 == '0' and line2 == 'ENDSEC': return_code = True break elif line1 == '0': self.run(line2) line1, line2 = self.read_record() self.parsed = parsed return return_code def load_sections(self): return_code = False param={ '2': '', # name section } param = self.read_param(param) name=param['2'] print '**',name if name == 'HEADER': return_code, header_dict = self.load_HEADER() self.process_header(header_dict) elif name == 'CLASSES': return_code = self.find_record('0','ENDSEC') elif name == 'OBJECTS': return_code = self.find_record('0','ENDSEC') elif name == 'THUMBNAILIMAGE': return_code = self.find_record('0','ENDSEC') else: return_code = self.load_section() return return_code def interpret(self): file = self.file if type(file) == StringType: file = open(file, 'r') file.seek(0) readline = file.readline fileinfo = os.stat(self.filename) totalsize = fileinfo[6] self.parsed = 0 self.parsed_interval = totalsize / 99 + 1 line1, line2 = self.read_record() while line1 or line2: if line1 == '0': if line2 == 'EOF': break elif not self.load_sections(): warn_tb(INTERNAL, _('DXFLoader: error. Non find end of sections')) line1, line2 = self.read_record() def run(self,keyword, *args): if keyword is None: return return_code = False unknown_operator = (None, None) funclist = self.funclist if keyword is not None: method, argc = funclist.get(keyword, unknown_operator) if method is not None: try: ##print '******', keyword if len(args): i = 0 while i<len(args): return_code = apply(method, args[i:argc+i]) i+=argc else: return_code = method() except: warn_tb(INTERNAL, 'DXFLoader: error') else: self.add_message(_('Not interpreted %s') % keyword) return return_code def Load(self): import time start_time = time.clock() #print ' ************ "DXF_objects" **************' self.funclist = self.get_compiled() self.document() self.layer(name = _("DXF_objects")) self.interpret() self.end_all() for style in self.dynamic_style_dict.values(): self.object.load_AddStyle(style) self.object.load_Completed() print 'times',time.clock() - start_time return self.object