def boundingDiamond(wid=50, inner=1500, owid=250, outer=2250, left="Left", right="Right", center="Center", centeru="?"): print "boundingDiamond" toReturn = Shape([]) v = Vector(1,1) w = Vector(1,-1) oo = outer/2. oi = (outer - owid)/2. # print outer, wid, outer-wid # print oo, oi m = (Matrix(1, -1, 1, 1)/math.sqrt(2)) rect1 = Polyline([v*oo, w*oo, -v*oo, -w*oo, v*oo, v*oi, -w*oi, -v*oi, w*oi, v*oi], True, False, 3)*m; oo = inner/2. oi = (inner - wid)/2. rect2 = Polyline([v*oo, w*oo, -v*oo, -w*oo, v*oo, v*oi, -w*oi, -v*oi, w*oi, v*oi], True, False, 3) toReturn.add(rect(Vector(-inner/2, -inner/3), Vector(-inner/2 + wid, inner/3)).setMaterial(3)) toReturn.add(rect(Vector(inner/2, -inner/3), Vector(inner/2 - wid, inner/3)).setMaterial(3)) if centeru[0] != '?': toReturn.add(rect(Vector(-inner/3, inner/2-wid), Vector(inner/3, inner/2)).setMaterial(3)) toReturn.add(rect(Vector(-inner/3, -inner/2+wid), Vector(inner/3, -inner/2)).setMaterial(3)) # rect1 = (rect(v*(-oi), v*oi)).add(rect(v*(-oo), v*oo)) # print rect1 # toReturn.add(rect(v*(-oi), v*oi)); # toReturn.add(rect(v*(-oo), v*oo)); toReturn.add(rect1.setMaterial(3)) # toReturn.add(rect2) toReturn.add((font.shapeFromStringBoundedCentered(left, wid, -1) + Vector(-inner/2. - inner/4. + 3*wid, 0)).setMaterial(3)) toReturn.add((font.shapeFromStringBoundedCentered(center, wid, -1) + Vector(0, -inner/2. - inner/4. + 4*wid)).setMaterial(3)) toReturn.add((font.shapeFromStringBoundedCentered(right, wid, -1) + Vector(inner/2. + inner/4. - 3*wid, 0)).setMaterial(3)) if centeru[0] != '?' and centeru[0] != ' ': toReturn.add((font.shapeFromStringBoundedCentered(centeru, wid, -1) + Vector(0, +inner/2. + inner/4. - 4*wid)).setMaterial(3)) mark = alignmentMark(100).setMaterial(3)*m; mx = inner - 5*wid; toReturn.add(mark + Vector(0, mx)); toReturn.add(mark + Vector(0, -mx)); toReturn.add(mark + Vector(mx, 0)); toReturn.add(mark + Vector(-mx, 0)); return toReturn
def circle(c, r, p=precision): if r < p: steps = 8 else: steps = int(math.ceil(2*math.pi*r/p)) toReturn = Polyline([], True) v = Vector(r,0) m = Matrix(2*math.pi/steps) for i in range(0,steps): v *= m toReturn.add(c + v) # print toReturn return toReturn
def set_value(self, field_name, value): """ sets an attribute value for a given field name """ if field_name in self.fields: if not value is None: self._dict['attributes'][field_name] = _unicode_convert(value) self._json = json.dumps(self._dict, default=_date_handler) else: pass elif field_name.upper() in ['SHAPE', 'SHAPE@', "GEOMETRY"]: if isinstance(value, AbstractGeometry): if isinstance(value, Point): self._dict['geometry'] = { "x": value.asDictionary['x'], "y": value.asDictionary['y'] } elif isinstance(value, MultiPoint): self._dict['geometry'] = { "points": value.asDictionary['points'] } elif isinstance(value, Polyline): self._dict['geometry'] = { "paths": value.asDictionary['paths'] } elif isinstance(value, Polygon): self._dict['geometry'] = { "rings": value.asDictionary['rings'] } else: return False self._json = json.dumps(self._dict, default=_date_handler) elif isinstance(value, arcpy.Geometry): if isinstance(value, arcpy.PointGeometry): self.set_value( field_name, Point(value, value.spatialReference.factoryCode)) elif isinstance(value, arcpy.Multipoint): self.set_value( field_name, MultiPoint(value, value.spatialReference.factoryCode)) elif isinstance(value, arcpy.Polyline): self.set_value( field_name, Polyline(value, value.spatialReference.factoryCode)) elif isinstance(value, arcpy.Polygon): self.set_value( field_name, Polygon(value, value.spatialReference.factoryCode)) else: return False return True
def linear(p0, p1, p=precision): toReturn = Polyline([], False) steps = int(math.ceil((p1-p0).norm()/p)) toReturn.add(p0.copy()) for i in range(1,steps): t = float(i)/steps toReturn.add( p0*(1.0-t) + p1*t ) toReturn.add(p1.copy()) return toReturn
def cBezier(p0, p1, p2, p3, p=precision): # See wikipedia toReturn = Polyline([], False) estimatedLength = (p1-p0).norm() + (p2-p1).norm() + (p3-p2).norm() steps = int(math.ceil(estimatedLength/p)) toReturn.add(p0.copy()) for i in range(1,steps): t = float(i)/steps toReturn.add( p0*((1.0-t)*(1.0-t)*(1.0-t)) + p1*(3*(1.0-t)*(1.0-t)*t) + p2*(3*(1.0-t)*t*t) + p3*(t*t*t) ) toReturn.add(p3.copy()) return toReturn
def qBezier(p0, p1, p2, p=precision): # See wikipedia toReturn = Polyline([], False) # Really odd bug if this is replaced with 'Polyline()' estimatedLength = (p1-p0).norm() + (p2-p1).norm() steps = int(math.ceil(estimatedLength/p)) if steps > 1e4: # Arbitrary, check this.... return Polyline([], False) toReturn.add(p0.copy()) for i in range(1,steps): t = float(i)/steps toReturn.add( p0*((1.0-t)*(1.0-t)) + p1*(2.*(1.0-t)*t) + p2*(t*t) ) toReturn.add(p2.copy()) return toReturn
def __init__(self, path, radius): #Shapes' list self.shapes = [] self.path = path #SVG file parsing : opening the file, setting up a custom parser self.svg_file = open(path) parser = etree.XMLParser(ns_clean=True, remove_comments=True, remove_blank_text=True) #Generating a parsing tree self.tree = tree = etree.parse(self.svg_file, parser) ###################################################################### ### Parsing ATTRIBUTES ## ### Height, width, unit, ... ## ###################################################################### svgNode = tree.xpath("//n:svg", namespaces={'n': NS['svg']})[0] #Parsing the width, height, and their unit (should be 'px') self.width = self.height = self.unit = None for attribute in ['width', 'height']: regexp = re.match("([\d]+)(.+)", svgNode.attrib[attribute]) if regexp: setattr(self, attribute, int(regexp.group(1))) self.unit = regexp.group(2) else: raise Exception("No {} ! Can't parse SVG.".format(attribute)) # Parsing the map's scale self.pixel_per_mm = None if 'pixel_per_mm' in svgNode.attrib: self.pixel_per_mm = float(svgNode.attrib['pixel_per_mm']) # Parsing the 'real' angle of the map's north # (What a compass would show if oriented toward the map's top) self.north_angle = None if 'north_angle' in svgNode.attrib: self.north_angle = float(svgNode.attrib['north_angle']) #Bounding rectangle ( TODO : mm -> xp, etc.) self.rect = Rectangle(-1, -1, self.width + 1, self.height + 1) self.shapes.append(self.rect) ###################################################################### ### Parsing SHAPES ## ### We search all the groups and subgroups and parse their elements ## ###################################################################### #PARSING PATHS (polylines and ellipses) paths = tree.xpath("//n:path", namespaces={'n': NS['svg']}) #We'll add the "sodipodi" namespace here because arc shapes (like ellipsis) use it sodipodi_type = add_ns('type', NS['sodipodi']) if paths: for path in paths: if sodipodi_type in path.attrib and path.attrib[ sodipodi_type] == 'arc': cx = float(path.attrib[add_ns('cx', NS['sodipodi'])]) cy = float(path.attrib[add_ns('cy', NS['sodipodi'])]) rx = float(path.attrib[add_ns('rx', NS['sodipodi'])]) ry = float(path.attrib[add_ns('ry', NS['sodipodi'])]) dx, dy = parseTransform(path) cx, cy = cx + dx, cy + dy ellipse = Ellipse(cx, cy, rx, ry) self.shapes.append(ellipse) else: print "[ ! ] Paths - except ellipses - are not implemented yet" # points = self.parse_points(path.attrib['d']) # print points #PARSING RECTANGLES rectangles = tree.xpath("//n:rect", namespaces={'n': NS['svg']}) if rectangles: for rect in rectangles: x = float(rect.attrib['x']) y = float(rect.attrib['y']) w = float(rect.attrib['width']) h = float(rect.attrib['height']) dx, dy = parseTransform(rect) x, y = x + dx, y + dy rectangle = Rectangle(x, y, w, h) self.shapes.append(rectangle) #PARSING POLYGONES polygones = tree.xpath("//n:polygone", namespaces={'n': NS['svg']}) if polygones: for polygone in polygones: points = self.parse_points(polygone.attrib['points']) dx, dy = parseTransform(polygone) for point in points: point.x += dx point.y += dy polygone = Polygone(points) self.shapes.append(polygone) #PARSING POLYLINES polylines = tree.xpath("//n:polyline", namespaces={'n': NS['svg']}) if polylines: for poly in polylines: points = self.parse_points(poly.attrib['points']) dx, dy = parseTransform(poly) for point in points: point.x += dx point.y += dy polyline = Polyline(points) self.shapes.append(polyline) if self.pixel_per_mm is not None: self.discreteMap = DiscreteMap(self, radius=int(radius * self.pixel_per_mm)) else: self.discreteMap = DiscreteMap(self)
def arc(c, i, f, chooseShortest=True, p=precision): # 'direction' : CCW=1, CW=-1, Shortest=0 r1 = (i - c).norm() r2 = (f - c).norm() # print r1 - r2 if r1 - r2 > 1e-6: # Arbitrary! print "Can't make an arc with two radii: " + str(r1) + " and " + str(r2) return Polyline([], False) if (f - i).norm2() < 1e-6: # Arbitrary! print "Start and end of arc at same place..." return Polyline([], False) r = r1 print (i - c), (f - c) dir = (i - c).cross(f - c) print "Dir: ", dir if dir == 0: # dir = 1 ang = -math.pi chooseShortest=True print "Arcs are equidistant, choosing CCW as shortest" else: ang = dir*math.acos(((i - c).Unit()) * ((f - c).Unit())) # print (i - c).Unit() # print (f - c).Unit() if not chooseShortest: if ang > 0: ang = ang - 2*math.pi else: ang = 2*math.pi + ang if r < p: steps = 8 elif r > 1000: # Arbitrary, check this.... return Polyline([], False) else: steps = int(math.ceil(abs(ang)*r/p)) # print steps, ang, r, p toReturn = Polyline([], False) if steps > 0: v = (i - c) print ang/steps m = Matrix(ang/steps) toReturn.add(i) for i in range(0,steps-1): v *= m # print center + v toReturn.add(c + v) toReturn.add(f) # print toReturn return toReturn
def thickenPolyline(polyline_, widthType_="CUBIC", # "LINEAR", "CUBIC", "SPLINE", "FUNCTION", "CONSTANT" widthParams=1.0, # Single number (constant width), or list [ i, f ], or (in the case of "FUNCTION") a string, "CONSTANT" only uses the first value. filletType_="SHARP", # "ROUND", "SHARP", "BLUNT", "QBEZIER" !! NotImplemented capType_="FLAT"): # "FLAT", "ROUND", "ROUNDRECESSED" !! NotImplemented if isinstance(polyline_, list): [polyline, di, df] = polyline_ df = -df else: polyline = polyline_ di = None df = None if not isinstance(polyline, Polyline): print "No polyline given to thicken..." return None if isinstance(widthType_, str): widthType = widthTypes[widthType_] if isinstance(filletType_, str): filletType = filletTypes[filletType_] if isinstance(capType_, str): capType = capTypes[capType_] if isinstance(widthParams, list): if widthType == 4: # CONSTANT widthParams = widthParams[0] elif isinstance(widthParams, str): if widthType != 3: print "Error, given function string, but not function type..." else: widthType = 4 # CONSTANT # print widthType, widthParams length = polyline.length() currentLength = 0 if widthType == 1 or widthType == 2 or widthType == 3: i = 1 while i < polyline.size: # Check here... segmentLength2 = (polyline.points[i] - polyline.points[i-1]).norm2() if segmentLength2 > 4*precision*precision: print "Length short, adding linear" addition = linear(polyline.points[i-1], polyline.points[i]) polyline.points = polyline.points[0:i-1] + addition.points + polyline.points[i+1:] polyline.size = len(polyline.points) i += 1 # polyline.plot() # return toReturn = Polyline([], True) # return toReturn p0 = polyline.perp(0, filletType, calcWidth(0, widthType, widthParams), di) for i in range(1, polyline.size - 1): currentLength += (polyline.points[i] - polyline.points[i-1]).norm() t = currentLength/length # print t, calcWidth(t, widthType, widthParams), (polyline.points[i] - polyline.points[i-1]) toReturn.add(polyline.perp(i, filletType, calcWidth(t, widthType, widthParams))) p1 = polyline.perp(polyline.size - 1, filletType, calcWidth(1, widthType, widthParams), df) p2 = polyline.perp(polyline.size - 1, filletType, -calcWidth(1, widthType, widthParams), df) if capType == 0: toReturn.add(p1) toReturn.add(p2) elif capType == 1: toReturn.add(arc((p1+p2)/2, p1, p2)) for i in range(polyline.size - 2, 0, -1): currentLength -= (polyline.points[i] - polyline.points[i-1]).norm() t = currentLength/length # print t, calcWidth(t, widthType, widthParams) toReturn.add(polyline.perp(i, filletType, -calcWidth(t, widthType, widthParams))) p3 = polyline.perp(0, filletType, -calcWidth(0, widthType, widthParams), di) if capType == 0: toReturn.add(p3) toReturn.add(p0) elif capType == 1: toReturn.add(arc((p0+p3)/2, p3, p0)) # print toReturn return toReturn
def connect(i_, f_, type="CIRCULAR", di=None, df=None): # "LINEAR", "QBEZIER", "CBEZIER", "CIRCULAR", "MONOCIRCULAR" if isinstance(i_, Connection): i = i_.v di = i_.dir else: i = i_ if isinstance(f_, Connection): f = f_.v df = f_.dir else: f = f_ if i == f: print "Error: There is no distance to connect..." return None if type == "LINEAR" or di == None or df == None: return Polyline([i, f], False) elif di * df == -1 and abs(di * (f-i).unit()) == 1: return Polyline([i, f], False) elif di * df == 1 and abs(di * (f-i).unit()) == 1: print "Sorry, can't make this path" return None else: # Check if norm is zero? di.Unit() df.Unit() if type == "QBEZIER": c = getIntersection(i, di, f, df) if c is not None: if (c-i)*di > 1e-10 and (c-f)*df > 1e-10: print (c-i)*di, (c-f)*df return qBezier(i, c, f) print "Error: Intersection could not be found; returning linear path" return None #Polyline([i, f], False) elif type == "CBEZIER": l = (f - i).norm()/2 # c = getIntersection(i, di, f, df) return cBezier(i, i + di*l, f + df*l, f); elif type == "CIRCULAR": # Find the Radius of the two circles (confusing math that I won't explain): D = f - i d = df.perp() - di.perp() a = (d.norm2() - 4) b = 2*(d*D) c = D.norm2() lList = [None, None, None, None] paramList = [None, None, None, None] rlist = [getRoot(a,b,c,1), getRoot(a,b,c,-1)] print rlist j = 0 for r in rlist: for s in [1, -1]: if r != None: ci = i + di.perp()*(s*r) cf = f + df.perp()*(s*r) m = (ci + cf)/2 if abs((cf - ci).norm2() - 4*r*r) < 1e-6: lList[j] = abs(r)*(abs(getArcAng(ci, i, m, (m-i)*di > 0)) + abs(getArcAng(cf, m, f, (m-f)*df > 0))) j += 1 minl = "inf" minj = -1 for j in range(0,4): # print j, lList[j] if lList[j] != None and lList[j] < minl: minl = lList[j] minj = j j = 0 for r in rlist: for s in [1, -1]: if j == minj: ci = i + di.perp()*(s*r) cf = f + df.perp()*(s*r) m = (ci + cf)/2 toReturn = Polyline() toReturn.add(arc(ci, i, m, (m-i)*di > 0)) toReturn.add(arc(cf, m, f, (m-f)*df > 0)) return toReturn j += 1 # return toReturn # r1 = getRoot(a,b,c,1) # # ci1 = i - di.perp()*r1 # cf1 = f - df.perp()*r1 # # if abs((cf1 - ci1).norm2() - 4*r1*r1) > 1e-6: # ci1 = i + di.perp()*r1 # cf1 = f + df.perp()*r1 # # m1 = (ci1 + cf1)/2 # l1 = getArcAng(ci1, i, m1, (m1-i)*di > 0) + getArcAng(cf1, m1, f, (m1-f)*df > 0) # # # r2 = getRoot(a,b,c,-1) # # ci2 = i + di.perp()*r2 # cf2 = f + df.perp()*r2 # # if abs((cf1 - ci1).norm2() - 4*r2*r2) > 1e-6: # ci2 = i - di.perp()*r2 # cf2 = f - df.perp()*r2 # # m2 = (ci1 + cf1)/2 # l2 = getArcAng(ci2, i, m2, (m2-i)*di > 0) + getArcAng(cf2, m2, f, (m2-f)*df > 0) # # if r1*l1 < r2*l2: # m = m1 # ci = ci1 # cf = cf1 # else: # m = m2 # ci = ci2 # cf = cf2 # for d in [df.perp() - di.perp()]: #, df.perp() + di.perp()]: # a = (d.norm2() - 4) # b = 2*(d*D) # c = D.norm2() # # rlist[j] = getRoot(a,b,c,1) # rlist[j-1] = getRoot(a,b,c,-1) # # j += 2 # # print rlist # # minr = "inf" # minj = -1 # for j in range(0,3): # if rlist[j] != None and abs(rlist[j]) < minr: # minr = abs(rlist[j]) # minj = j # ## minjList = [] ## ## for j in range(0,3): ## if rlist[j] != None and abs(rlist[j]) == minr: ## minjList += [j] ## ## if len(minjList) > 1: ## for j in minrList: # # # # With knowledge of the radius, find the centers # r = minr # print r # if minj == 0 or minj == 1: ## print i ## print di.perp()*r # ci = i + di.perp()*r # cf = f + df.perp()*r # # print (cf - ci).norm2()- 4*r*r # ## print (cf - ci).norm2(), 4*r*r # # if abs((cf - ci).norm2() - 4*r*r) > 1e-6: # Arbitrary error! # ci = i - di.perp()*r # cf = f - df.perp()*r # ## print (cf - ci).norm2(), 4*r*r # print (cf - ci).norm2()- 4*r*r # # if abs((cf - ci).norm2() - 4*r*r) > 1e-6: # Arbitrary error! # print "Error occured with radius checking" # return None # elif minj == 2 or minj == 3: # ci = i + di.perp()*r # cf = f - df.perp()*r # ## print (cf - ci).norm2(), 4*r*r # print (cf - ci).norm2()- 4*r*r ## print "here" # # if abs((cf - ci).norm2() - 4*r*r) > 1e-6: # Arbitrary error! ## print "here2" # ci = i - di.perp()*r # cf = f + df.perp()*r # ## print (cf - ci).norm2(), 4*r*r # print (cf - ci).norm2()- 4*r*r # # if abs((cf - ci).norm2() - 4*r*r) > 1e-6: # Arbitrary error! # print "Error occured with radius checking" # return None # else: # # No radius found... # print "Sorry, can't find two minimum circles" # return None # plotLine(i, ci) # plotLine(ci, cf) # plotLine(cf, f) # return toReturn elif type == "MONOCIRCULAR": # print "MONOCIRCULAR" intersection = getIntersection(i, di, f, df) if intersection == None: if di*df == 1: if di*i > df*f: midpoint = getIntersection(i, di.perp(), f, df) c = (midpoint + i)/2 return arc(c, i, midpoint) + Polyline([f], False) # Check arc direction!!! (removed repeated point?) else: midpoint = getIntersection(i, di, f, df.perp()) c = (midpoint + f)/2 return Polyline([i], False) + arc(c, midpoint, f) # Check arc direction!!! else: print "CIRCULAR would be better for this case because directions are antiparallell; returning linear in the meantime..." return Polyline([i, f], False) toReturn = Polyline([]) if (intersection - i)*di > 0 and (intersection - f)*df > 0: # Converging if (intersection - i)*di < (intersection - f)*df: midpoint = intersection - df*((intersection - i)*di) c = getIntersection(i, di.perp(), midpoint, df.perp()) # Check if intersection exists for all of these... return arc(c, i, midpoint) + Polyline([f], False) else: midpoint = intersection - di*((intersection - f)*df) c = getIntersection(midpoint, di.perp(), f, df.perp()) return Polyline([i], False) + arc(c, midpoint, f) elif (intersection - i)*di > 0 or (intersection - f)*df > 0: # Opposite if (i - intersection)*di < 0: midpoint = intersection - di*((intersection - f)*df) c = getIntersection(midpoint, di.perp(), f, df.perp()) return Polyline([i], False) + arc(c, midpoint, f, False) else: midpoint = intersection - df*((intersection - i)*di) c = getIntersection(i, di.perp(), midpoint, df.perp()) return arc(c, i, midpoint, False) + Polyline([f], False) else: # Diverging if (intersection - i)*di > (intersection - f)*df: # If i is shorter midpoint = intersection - di*((intersection - f)*df) c = getIntersection(midpoint, di.perp(), f, df.perp()) print c if c.norm2() < 1e6: # return Polyline([i, midpoint, c, f], False) #arc(c, i, midpoint, False) + Polyline([f], False) # return arc(c, i, midpoint, False) + Polyline([f], False) return Polyline([i], False) + arc(c, midpoint, f, False) else: midpoint = intersection - df*((intersection - i)*di) c = getIntersection(i, di.perp(), midpoint, df.perp()) print c if c.norm2() < 1e6: # return Polyline([i, c, midpoint, f], False) #+ arc(c, midpoint, f, False) # return Polyline([i], False) + arc(c, midpoint, f, False) return arc(c, i, midpoint, False) + Polyline([f], False) # if (c - i).norm2() < (c - f).norm2(): # if (c - i) * di == 0: # print "CIRCULAR would be better for this case; returning linear in the meantime..." # return Polyline([i, f], False) # elif (c - i) * di > 0 and (f - c) * df > 0: # midpoint = c - df*( (c-i).norm() ) # # toReturn.add(arc(c, i, midpoint)) # toReturn.add(f) # elif (c - i) * di < 0 and (f - c) * df < 0: # midpoint = c - df*( (c-i).norm() ) # # toReturn.add(arc(c, i, midpoint)) # toReturn.add(f) return NotImplemented
def shapeFromGlyph(self, glyph): # Save loaded glyphs for speed toReturn = Shape([],[]) if glyph.isComposite(): print "Warning: This case is broken!, it does not transform..." # print "COMPOSITE" for component in glyph.components: print component print component.getComponentInfo() [name, transform] = component.getComponentInfo() print transform print type(transform) m = Matrix(transform) print m print self.tt['glyf'][name] toReturn.add(self.shapeFromGlyph(self.tt['glyf'][name])) # for item in self.getCMAP().cmap.items(): # if item[1] == name: # toReturn.add(self.shapeFromGlyph(self.tt[ 'glyf' ][item[0]])) # break else: # print "NOT COMPOSITE" last = 0 for i in range(glyph.numberOfContours): toAdd = Polyline([], True) prevV = None prevOn = None prevprevV = None prevprevOn = None firstV = None firstOn = None secondV = None secondOn = None for j in range(last, glyph.endPtsOfContours[i] + 1): v = Vector(glyph.coordinates[j][0], glyph.coordinates[j][1])/float(self.width) # This is a temporary fix! on = glyph.flags[j] & 0x01 if firstOn == None: firstOn = on firstV = v elif secondOn == None: secondOn = on secondV = v # print v # print prevprevOn, prevOn, on # print prevprevV, prevV, v if prevOn and on: if prevprevOn == None: toAdd.add(prevV) toAdd.add(v) elif prevOn != None and prevprevOn != None: if prevprevOn and not prevOn: if on: # 101 toAdd.add(qBezier(prevprevV, prevV, v)) elif not on: # 100 # print (prevV + v) # print (prevV + v)/2 toAdd.add(qBezier(prevprevV, prevV, (prevV + v)/2)) elif not prevprevOn and not prevOn: if on: # 001 toAdd.add(qBezier((prevprevV + prevV)/2, prevV, v)) elif not on: # 000 toAdd.add(qBezier((prevprevV + prevV)/2, prevV, (prevV + v)/2)) prevprevOn = prevOn prevprevV = prevV prevOn = on prevV = v # print "toAdd: " # print toAdd # print "First Here" # print prevOn, on, firstOn # print prevprevV, v, firstV # toAdd.add(Vector(0,0)) if not on: if firstOn != None and not firstOn: if prevprevOn: toAdd.add(qBezier(prevprevV, v, (v + firstV)/2)) else: toAdd.add(qBezier((prevprevV + v)/2, v, (v + firstV)/2)) if firstOn != None and firstOn: if prevprevOn: toAdd.add(qBezier(prevprevV, v, firstV)) else: toAdd.add(qBezier((prevprevV + v)/2, v, firstV)) # if firstOn != None and secondOn != None: # print "First Second Here" # print on, firstOn, secondOn ## if on and firstOn and secondOn: # 111 # if on and not firstOn and secondOn: # 101 # toAdd.add(qBezier(v, firstV, secondV)) # if on and not firstOn and not secondOn: # 100 # toAdd.add(qBezier(v, firstV, (firstV + secondV)/2)) # if not on and not firstOn and secondOn: # 001 # toAdd.add(qBezier((v + firstV)/2, firstV, secondV)) # if not on and not firstOn and not secondOn: # 000 # toAdd.add(qBezier((v + firstV)/2, firstV, (firstV + secondV)/2)) # toAdd.add(v) last = glyph.endPtsOfContours[i] + 1 # print toAdd.area() # toAdd.add(Vector(0,0)) toReturn.add(toAdd) # print "toReturn: " # print toReturn if len(toReturn.polylines) > 1: k = 0 for i in range(0, toReturn.size): # print toReturn.polylines[i].area() if abs(toReturn.polylines[i].area()) > abs(toReturn.polylines[k].area()): # Save area for speed k = i finList = [] for i in range(0, toReturn.size): if toReturn.polylines[i].area() < 0: # print k, i # print toReturn.polylines[i] # print toReturn.polylines[k] # toReturn.polylines[i].points.reverse() m = 0 #toReturn.polylines[i].size-1 j = 0 norm = (toReturn.polylines[k].points[0] - toReturn.polylines[i].points[m]).norm2() # Possible error if empty toReturn.polylines[k].sizeCalc() for l in range(0, toReturn.polylines[k].size): # print norm, (toReturn.polylines[k].points[l] - toReturn.polylines[i].points[m]).norm2() if (toReturn.polylines[k].points[l] - toReturn.polylines[i].points[m]).norm2() < norm: j = l norm = (toReturn.polylines[k].points[l] - toReturn.polylines[i].points[m]).norm2() # print j # toReturn.polylines[k].points[j], toReturn.polylines[k].points = toReturn.polylines[k].points[0:j+1] + toReturn.polylines[i].points + [toReturn.polylines[i].points[0]] + toReturn.polylines[k].points[j:] # toReturn.polylines[k].points = toReturn.polylines[k].points[0:j+1] + [toReturn.polylines[i].points[toReturn.polylines[i].size-1]] + toReturn.polylines[i].points + toReturn.polylines[k].points[j:] toReturn.polylines[k].sizeCalc() else: finList += [ toReturn.polylines[i] ] toReturn = Shape(finList) # toReturn.polylines.remove(i) # finList = [toReturn.polylines[k]] # # for polyline in toReturn.polylines: # print polyline # if polyline != toReturn.polylines[k]: # print polyline.area() # if polyline.area() < 0: # # highest = polyline.points[0] # print "HIGHEST: ", highest # j = 0 # # for i in range(0, polyline.size): # if polyline.points[i].y > highest.y: # highest = polyline.points[i] # j = i # # polyline.points.insert(i, highest) # polyline.points.insert(i, highest + Vector(0,2)) # polyline.points.insert(i, highest) # # else: # print "extended" # finList.extend(polyline) # # toReturn.polylines[k].union(polyline) # # return Shape(finList,[]) return toReturn
def interpretToken(self, token_, f): shapesByLayer = {} print ':'.join(x.encode('hex') for x in token_) length = int(token_[0:2].encode('hex'), 16) token = int(token_[2].encode('hex'), 16) # Rename as token dataType = int(token_[3].encode('hex'), 16) DEBUG = True if DEBUG: print "LENGTH: " + str(length) + "\t" + hex(token) + " \t" # if (dataType == 0 and length != 0) or (dataType == 2 and length != 2) or (dataType == 3 and length != 4) or (dataType == 5 and length != 8): # print "Possible error; unexpected length" if token == 0x00: #02: if DEBUG: print "HEADER" if length != 6: print "Possible error; unexpected length" # self.version = read(f.read(2)) self.version = struct.unpack(">h", f.read(2))[0] print self.version elif token == 0x01: #02: if DEBUG: print "BGNLIB" vals = struct.unpack(">hhhhhhhhhhhh", f.read(24)) # self.modificationTime.year = vals[0] # self.modificationTime.month = vals[1] # self.modificationTime.day = vals[2] # self.modificationTime.hour = vals[3] # self.modificationTime.minute = vals[4] # self.modificationTime.second = vals[5] # # self.accessTime.year = vals[6] # self.accessTime.month = vals[7] # self.accessTime.day = vals[8] # self.accessTime.hour = vals[9] # self.accessTime.minute = vals[10] # self.accessTime.second = vals[11] self.modificationTime.set(vals[0], vals[1], vals[2], vals[3], vals[4], vals[5]) self.accessTime.set(vals[6], vals[7], vals[8], vals[9], vals[10], vals[11]) # self.modificationTime.set(read(f.read(2)), read(f.read(2)), read(f.read(2)), read(f.read(2)), read(f.read(2)), read(f.read(2))) # self.accessTime.set(read(f.read(2)), read(f.read(2)), read(f.read(2)), read(f.read(2)), read(f.read(2)), read(f.read(2))) print self.modificationTime print self.accessTime elif token == 0x02: #06: if DEBUG: print "LIBNAME" string = f.read(length - 4) # Error check this... print "Library Name: " + string elif token == 0x03: #05: if DEBUG: print "UNITS" # databaseUnitUser = read(f.read(8)) # Fix encoding # databaseUnitMeters = read(f.read(8)) data1 = f.read(8) data2 = f.read(8) print data1, ' '.join(format(ord(x), 'b') for x in data1) print data2, ' '.join(format(ord(x), 'b') for x in data2) databaseUnitUser = read(data1) # Fix encoding databaseUnitMeters = read(data2) if DEBUG: print databaseUnitUser print databaseUnitMeters elif token == 0x04: #00: if DEBUG: print "ENDLIB" elif token == 0x05: #02: if DEBUG: print "BGNSTR" # self.modificationTimeS.set(int(f.read(2).encode('hex'), 16), int(f.read(2).encode('hex'), 16), int(f.read(2).encode('hex'), 16), int(f.read(2).encode('hex'), 16), int(f.read(2).encode('hex'), 16), int(f.read(2).encode('hex'), 16)) # # self.accessTimeS.set(int(f.read(2).encode('hex'), 16), int(f.read(2).encode('hex'), 16), int(f.read(2).encode('hex'), 16), int(f.read(2).encode('hex'), 16), int(f.read(2).encode('hex'), 16), int(f.read(2).encode('hex'), 16)) vals = struct.unpack(">hhhhhhhhhhhh", f.read(24)) self.modificationTimeS.set(vals[0], vals[1], vals[2], vals[3], vals[4], vals[5]) self.accessTimeS.set(vals[6], vals[7], vals[8], vals[9], vals[10], vals[11]) # self.modificationTimeS.year = vals[0] # self.modificationTimeS.month = vals[1] # self.modificationTimeS.day = vals[2] # self.modificationTimeS.hour = vals[3] # self.modificationTimeS.minute = vals[4] # self.modificationTimeS.second = vals[5] # # self.accessTimeS.year = vals[6] # self.accessTimeS.month = vals[7] # self.accessTimeS.day = vals[8] # self.accessTimeS.hour = vals[9] # self.accessTimeS.minute = vals[10] # self.accessTimeS.second = vals[11] print self.modificationTimeS print self.accessTimeS elif token == 0x06: #06: if DEBUG: print "STRNAME" string = f.read(length - 4) # Error check this... print "Structure Name: " + string elif token == 0x07: #00: if DEBUG: print "ENDSTR" elif token == 0x08: #00: if DEBUG: print "BOUNDARY" elif token == 0x09: #00: if DEBUG: print "PATH" elif token == 0x0A: #00: if DEBUG: print "SREF" elif token == 0x0B: #00: if DEBUG: print "AREF" elif token == 0x0C: #00: if DEBUG: print "TEXT" elif token == 0x0D: #02: self.currentLayer = struct.unpack(">h", f.read(2))[0] # self.currentLayer = read(f.read(2)) if DEBUG: print "LAYER" print self.currentLayer elif token == 0x0F: #03: if DEBUG: print "WIDTH" pathWidth = struct.unpack(">h", f.read(2))[0] elif token == 0x10: #03: if DEBUG: print "XY" polyline = Polyline([], True, False, self.currentLayer) length -= 4 while length > 0: length -= 8 v = Vector(struct.unpack(">i", f.read(4))[0]*self.databaseUnitUser, struct.unpack(">i", f.read(4))[0]*self.databaseUnitUser) # v = Vector(int(f.read(4).encode('hex'), 16), int(f.read(4).encode('hex'), 16)) # v = Vector(read(f.read(4)), read(f.read(4))) polyline.add(v) # polyline.add(Vector(read(f.read(4)), read(f.read(4)))) # if DEBUG: print v #, bin(v.x), bin(v.y) # if self.currentLayer in self.shapes: # self.shapes[self.currentLayer].polylines += [polyline] # else: # self.shapes[self.currentLayer] = Shape([polyline]) if self.currentLayer in shapesByLayer: self.shapes[self.currentLayer].polylines += [polyline] else: self.shapes[self.currentLayer] = Shape([polyline]) elif token == 0x11: #00: if DEBUG: print "ENDEL" elif token == 0x0002: # SNAME if DEBUG: print "SNAME" elif token == 0x0002: # COLROW if DEBUG: print "COLROW" elif token == 0x0002: # NODE if DEBUG: print "NODE" elif token == 0x0002: # TEXTTYPE if DEBUG: print "TEXTTYPE" elif token == 0x0002: # PRESENTATION if DEBUG: print "PRESENTATION" elif token == 0x0002: # STRING if DEBUG: print "STRING" elif token == 0x0002: # STRANS if DEBUG: print "STRANS" elif token == 0x0002: # MAG if DEBUG: print "MAG" magnificationFactor = read(f.read(8)) elif token == 0x0002: # ANGLE if DEBUG: print "ANGLE" angleDegreesCCW = read(f.read(8)) elif token == 0x0002: # REFLIBS if DEBUG: print "REFLIBS" elif token == 0x0002: # FONTS if DEBUG: print "FONTS" elif token == 0x0002: # PATHTYPE if DEBUG: print "PATHTYPE" elif token == 0x0002: # GENERATIONS if DEBUG: print "GENERATIONS" elif token == 0x0002: # ATTRTABLE if DEBUG: print "ATTRTABLE" elif token == 0x0002: # EFLAGS if DEBUG: print "EFLAGS" elif token == 0x0002: # NODETYPE if DEBUG: print "NODETYPE" elif token == 0x0002: # PROPATTR if DEBUG: print "PROPATTR" elif token == 0x0002: # PROPVALUE if DEBUG: print "PROPVALUE" else: if DEBUG: print "token not understood..." b2 = f.read(2) print ':'.join(x.encode('hex') for x in b2) for layer in shapesByLayer: self.shapes += [shapesByLayer[layer]]