def main(): drawing = svgwrite.Drawing(filename='montecarlo1.svg', size=(page_width, page_height)) inkscape = Inkscape(drawing) inpts = [] outpts = [] for i in range(75): for j in range(75): pt = (i / 75.0 * page_width, j / 75.0 * page_height) inside = in_circle(circle_radius, pt) if inside: while 1: r = (random.random() * page_width, random.random() * page_height) if in_circle(circle_radius, r): break inpts.append(r) else: outpts.append(pt) random.shuffle(inpts) random.shuffle(outpts) # inpts.sort(key=lambda x: -distance((page_width/2, page_height/2), x)) # outpts.sort(key=lambda x: distance((page_width/2, page_height/2), x)) in_layer = inkscape.layer(label='inside circle') out_layer = inkscape.layer(label='outside circle') drawing.add(in_layer) drawing.add(out_layer) make_lines(in_layer, drawing, inpts) make_lines2(out_layer, drawing, outpts) drawing.save()
def test_add_line_to_layer(dwg): inkscape = Inkscape(dwg) layer = inkscape.layer(label="Layer one", locked=True) dwg.add(layer) line = dwg.line((100, 100), (300, 100), stroke=svgwrite.rgb(10, 10, 16, '%'), stroke_width=10) layer.add(line) text = dwg.text('Test', insert=(100, 100), font_size=100, fill='red') layer.add(text)
def main(): img = open_as_array('bobross.png') img = numpy.where(img == numpy.max(img), -10000000, img) img = img / numpy.max(img) img *= 10 img = numpy.round(img) (width, height) = img.shape print(img) print(img.shape) drawing = svgwrite.Drawing(filename='cross.svg', size=(width * 7, height * 7)) inkscape = Inkscape(drawing) layer = inkscape.layer(label='drawing') drawing.add(layer) for x in range(width): for y in range(height): cell = img[x, y] tmp = cell if cell >= 5: tmp -= 5 pts = cross(x, y, tmp) for (startpt, endpt) in pts: layer.add( drawing.line(startpt, endpt, stroke=svgwrite.rgb(0, 0, 0, '%'), stroke_width=1, stroke_linecap='round', stroke_opacity=1.0)) if 0 <= cell < 5: layer.add( drawing.circle(center=(7 * x + 3, 7 * y + 3), r=2.5, stroke=svgwrite.rgb(0, 0, 0, '%'), stroke_width=1, stroke_linecap='round', stroke_opacity=1.0, fill='none')) drawing.save()
def init_dwg(size): dwg = svgwrite.Drawing(profile='full', size=size) inkscape = Inkscape(dwg) css_name = 'svg' + '.css' mod_path = os.path.join(BASE_DIR, 'plotdot/svgDraw') css_path = os.path.join(mod_path, css_name) with open(css_path, 'r') as file: data = file.read().replace('\n', '') style_def = svgwrite.container.Style(data) dwg.defs.add(style_def) return dwg, inkscape
def main(): miss_cnt = 0 covered_pts = set([]) alleles = [] goal_coverage = PAPER_HEIGHT * PAPER_WIDTH * 0.25 while len(covered_pts) < goal_coverage: if len(alleles) % 100 == 0: print("Generated {} alleles ({} misses, {}/{} covered)...".format( len(alleles), miss_cnt, len(covered_pts), goal_coverage)) gen = Allele() if any([pt in covered_pts for pt in gen.allele_pts]): miss_cnt += 1 continue covered_pts |= set(gen.allele_pts) alleles.append(gen) print("Generated {} alleles".format(len(alleles))) rep = {} for color in COLORS: rep[color] = [] processed = 0 for allele in alleles: if processed % 100 == 0: print("Colored {} alleles...".format(processed)) pts = allele.allele_pts colors = [to_lab_color(TARGET_ARRAY[pt]) for pt in pts] color_dists = {} for color in COLORS: lab_color = to_lab_color(color) distance = sum( [color_distance(lab_color, pt_color) for pt_color in colors]) * random.gauss(1.0, 0.1) color_dists[color] = distance best_color = min(COLORS, key=lambda x: color_dists[x]) rep[best_color].append(allele) processed += 1 drawing = svgwrite.Drawing(size=(870, 695), filename='generated.svg') inkscape = Inkscape(drawing) layers = {} scale = 1.58096 for color in rep: alleles = rep[color] for allele in alleles: allele.start = allele.start[0] * scale, allele.start[1] * scale allele.end = allele.end[0] * scale, allele.end[1] * scale add_to_drawing(drawing, inkscape, layers, rep, offset=(93, 61)) drawing.save()
def main(): sw = Stopwatch() sw.start() try: os.makedirs("./tmp", exist_ok=True) pops = [Population(i) for i in range(374)] print("Gen 0 took {} to init".format(sw.reset())) for i in range(100): print(pops) drawing = svgwrite.Drawing(size=(550, 425), filename='tmp/gen-{}.svg'.format(i)) inkscape = Inkscape(drawing) layers = {} [ pop.add_best_to_drawing(drawing, inkscape, layers) for pop in pops ] drawing.save(pretty=True, indent=2) pops = [pop.next_generation() for pop in pops] print("Next gen took {}".format(sw.reset())) finally: THREAD_POOL.shutdown()
def write_svg( output: TextIO, vector_data: VectorData, page_format: Tuple[float, float] = (0.0, 0.0), center: bool = False, source_string: str = "", single_path: bool = False, layer_label_format: str = "%d", show_pen_up: bool = False, color_mode: str = "none", ) -> None: """Create a SVG from a :py:class:`VectorData` instance. If no page format is provided (or (0, 0) is passed), the SVG generated has bounds tightly fitted around the geometries. Otherwise the provided size (in pixel) is used. By default, no translation is applied on the geometry. If `center=True`, geometries are moved to the center of the page. No scaling or rotation is applied to geometries. Layers are named after `layer_label_format`, which may contain a C-style format specifier such as `%d` which will be replaced by the layer number. If `single_path=True`, a single compound path is written per layer. Otherwise, each path is exported individually. For previsualisation purposes, pen-up trajectories can be added to the SVG and path can be colored individually (``color_mode="path"``) or layer-by-layer (``color_mode="layer"``). Args: output: text-mode IO stream where SVG code will be written vector_data: geometries to be written page_format: page (width, height) tuple in pixel, or (0, 0) for tight fit center: center geometries on page before export source_string: value of the `source` metadata single_path: export geometries as a single compound path instead of multiple individual paths layer_label_format: format string for layer label naming show_pen_up: add paths for the pen-up trajectories color_mode: "none" (no formatting), "layer" (one color per layer), "path" (one color per path) (``color_mode="path"`` implies ``single_path=False``) """ # compute bounds bounds = vector_data.bounds() if bounds is None: # empty geometry, we provide fake bounds bounds = (0, 0, 1, 1) tight = page_format == (0.0, 0.0) if not tight: size = page_format else: size = (bounds[2] - bounds[0], bounds[3] - bounds[1]) if center: corrected_vector_data = copy.deepcopy(vector_data) corrected_vector_data.translate( (size[0] - (bounds[2] - bounds[0])) / 2.0 - bounds[0], (size[1] - (bounds[3] - bounds[1])) / 2.0 - bounds[1], ) elif tight: corrected_vector_data = copy.deepcopy(vector_data) corrected_vector_data.translate(-bounds[0], -bounds[1]) else: corrected_vector_data = vector_data # output SVG size_cm = tuple(f"{round(s / UNITS['cm'], 8)}cm" for s in size) dwg = svgwrite.Drawing(size=size_cm, profile="tiny", debug=False) inkscape = Inkscape(dwg) dwg.attribs.update({ "viewBox": f"0 0 {size[0]} {size[1]}", "xmlns:dc": "http://purl.org/dc/elements/1.1/", "xmlns:cc": "http://creativecommons.org/ns#", "xmlns:rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", }) # add metadata metadata = ElementTree.Element("rdf:RDF") work = ElementTree.SubElement(metadata, "cc:Work") fmt = ElementTree.SubElement(work, "dc:format") fmt.text = "image/svg+xml" source = ElementTree.SubElement(work, "dc:source") source.text = source_string date = ElementTree.SubElement(work, "dc:date") date.text = datetime.datetime.now().isoformat() dwg.set_metadata(metadata) color_idx = 0 if show_pen_up: group = inkscape.layer(label="% pen up trajectories") group.attribs["fill"] = "none" group.attribs["stroke"] = "black" group.attribs[ "style"] = "display:inline; stroke-opacity: 50%; stroke-width: 0.5" group.attribs["id"] = "pen_up_trajectories" for layer in corrected_vector_data.layers.values(): group.add(_line_to_path(dwg, layer.pen_up_trajectories())) dwg.add(group) for layer_id in sorted(corrected_vector_data.layers.keys()): layer = corrected_vector_data.layers[layer_id] group = inkscape.layer(label=str(layer_label_format % layer_id)) group.attribs["fill"] = "none" if color_mode == "layer": group.attribs["stroke"] = _COLORS[color_idx % len(_COLORS)] color_idx += 1 else: group.attribs["stroke"] = "black" group.attribs["style"] = "display:inline" group.attribs["id"] = f"layer{layer_id}" if single_path and color_mode != "path": group.add(_line_to_path(dwg, layer)) else: for line in layer: path = _line_to_path(dwg, line) if color_mode == "path": path.attribs["stroke"] = _COLORS[color_idx % len(_COLORS)] color_idx += 1 group.add(path) dwg.add(group) dwg.write(output, pretty=True)
#!/usr/bin/python3 import svgwrite from svgwrite.data.types import SVGAttribute from svgwrite.extensions import Inkscape from libShapes import * dwg = svgwrite.Drawing('oledbezel.svg', profile='full', size=('150mm','115mm'), viewBox="0 0 150 115") ink=Inkscape(dwg) def myBox(dwg, ox,oy) : p=dwg.path( d="M%d,%d l200,0 l0,50 a50,50 0 0,1 -50,50 l-150,0 l0,-100" % (ox,oy), stroke="black", fill="none", stroke_width=0.1) return(p) def outsideBox(dwg,ox,oy) : outlineBBox(dwg, ox,oy, 37,49) def mountingHoles(dwg,ox,oy) : r=7 d=6 hole(dwg,ox+r,oy+d,2) r=37-7 d=6 hole(dwg,ox+r,oy+d,2) r=7 d=49-6 hole(dwg,ox+r,oy+d,2) r=37-7 d=49-6
def __init__(self, **kwargs): """Constructor """ byA_FrozenClass.__init__(self) self._liststatures = kwargs.get('liststatures', '') self._currentStature = None self._sheetSize = kwargs.get('sheetSize', a0Size) self._filename = kwargs.get('filename', 'pattern.svg') self._dicoConstruction = dict() self._dicoMesures = kwargs.get('dicoMesures', a0Size) w = str(self._sheetSize[0]).replace("cm", "") h = str(self._sheetSize[1]).replace("cm", "") self._svgDrawing = svgwrite.Drawing( self._filename, [str(int(w)) + 'cm', str(int(h)) + 'cm'], profile='full') self._svgDrawing.viewbox(width=str(int(w)), height=str(int(h))) self._inkscape = Inkscape(self._svgDrawing) self._Stature = dict() self._FrontPattern = dict() self._BackPattern = dict() self._MiddleFront = dict() self._MiddleBack = dict() self._HipLine = dict() self._WaistLine = dict() self._BustLine = dict() self._FrontBustLineMark = dict() self._BackBustLineMark = dict() self._FrontHipLineMark = dict() self._BackHipLineMark = dict() self._FrontBodiceLenghtLine = dict() self._BackBodiceLenghtLine = dict() self._FrontDartBustLine = dict() self._BackDartBustLine = dict() self._FrontDartWaistLine = dict() self._BackDartWaistLine = dict() self._FrontSideLine = dict() self._BackSideLine = dict() self._FrontSideCurve = dict() self._BackSideCurve = dict() self._FrontDart = dict() self._BackDart = dict() svgStyle = svgwrite.container.Style() svgStyle['id'] = "LineJaquePatternStyles" svgStyle.append(' text.nomenclature {font-family: cursive;}') svgStyle.append(' text.nomenclature {font-size:' + str(200 * PXCM) + ';}') svgStyle.append(' text.nomenclature {fill:#e6e6e6;}') svgStyle.append(' text.nomenclature {stroke-width:' + str(6 * PXCM) + ';}') svgStyle.append(' text.nomenclature {opacity:0.5}') svgStyle.append(' path.middleline {stroke:black;}') svgStyle.append(' path.middleline {stroke-width:' + str(15 * PXCM) + ';}') svgStyle.append(' path.middleline {opacity:1.0; }') svgStyle.append(' path.horizline {stroke:black;}') svgStyle.append(' path.horizline {stroke-width:' + str(6 * PXCM) + ';}') svgStyle.append(' path.horizline {stroke-dasharray:' + str(6) + ',' + str(3) + '}') svgStyle.append(' path.horizline {opacity:1.0; }') svgStyle.append(' circle.constructionPoint {stroke:none;}') #svgStyle.append(' circle.constructionPoint {fill:xxx;}') svgStyle.append(' circle.constructionPoint {opacity:0.5;}') svgStyle.append(' path.constructionLine {stroke:black;}') svgStyle.append(' path.constructionLine {stroke-width:' + str(6 * PXCM) + ';}') svgStyle.append(' path.constructionLine {stroke-dasharray:' + str(2) + ',' + str(2) + '}') svgStyle.append(' path.constructionLine {opacity:1.0; }') svgStyle.append(' path.constructionCurve {stroke:black;}') svgStyle.append(' path.constructionCurve {stroke-width:' + str(6 * PXCM) + ';}') svgStyle.append(' path.constructionCurve {stroke-dasharray:' + str(2) + ',' + str(2) + '}') svgStyle.append(' path.constructionCurve {opacity:1.0; }') svgStyle.append(' circle.finalPoint {stroke:none;}') #svgStyle.append(' circle.finalPoint {fill:xxx;}') svgStyle.append(' circle.finalPoint {opacity:0.5;}') svgStyle.append(' path.finalLine {fill:none;}') #svgStyle.append(' path.finalLine {stroke:xxx;}') svgStyle.append(' path.finalLine {stroke-width:' + str(25 * PXCM) + ';}') svgStyle.append(' path.finalLine {opacity:1.0; }') svgStyle.append(' path.finalCurve {fill:none;}') #svgStyle.append(' path.finalCurve {stroke:xxx;}') svgStyle.append(' path.finalCurve {stroke-width:' + str(25 * PXCM) + ';}') svgStyle.append(' path.finalCurve {opacity:1.0; }') #svgStyle.append(' .pointCaption {fill: black; font-family: Verdana; font-size:' + str(5*PXCM) + ';}') #svgStyle.append(' .pointCircle {fill: green;}') #svgStyle.append(' line.base {stroke-width:' + str(1*PXCM) + '; opacity:0.1}') #svgStyle.append(' path.base {stroke-width:' + str(1*PXCM) + '; opacity:0.1; stroke_linejoin:round}') #svgStyle.append(' line.bodiceadjust {stroke-width:' + str(1*PXCM) + '; stroke_linejoin:round}') #svgStyle.append(' path.bodiceadjust {stroke-width:' + str(1*PXCM) + '; stroke_linejoin:round}') #svgStyle.append(' line.elarg {stroke-width:' + str(1*PXCM) + '; stroke_linejoin:round}') #svgStyle.append(' path.elarg {stroke-width:' + str(1*PXCM) + '; stroke_linejoin:round}') #svgStyle.append(' line.abdomen {stroke-width:' + str(4.5*PXCM) + '; opacity:0.1; stroke-dasharray:' + str(0.15) +','+ str(0.05) + '}') #svgStyle.append(' path.abdomen {stroke-width:' + str(4.5*PXCM) + '; opacity:0.1; stroke-dasharray:' + str(0.15) +','+ str(0.05) + '}') #svgStyle.append(' line.coat {stroke-width:' + str(6*PXCM) + ';}') #svgStyle.append(' path.coat {stroke-width:' + str(6*PXCM) + ';}') #for sizeFigure, sizeTxt in enumerate(('thin', 'normal', 'bold')): # svgStyle.append(' line.' + sizeTxt + "{stroke-width : " + str((sizeFigure+1)*PXCM) + "; stroke-dasharray:" + str(0.05) +','+ str(0.05) + '}') # svgStyle.append(' path.' + sizeTxt + "{stroke-width : " + str((sizeFigure+1)*PXCM) + "; stroke-dasharray:" + str(0.05) +','+ str(0.05) + '}') for s in self._liststatures: svgStyle.append(' circle.stature' + str(s) + " {stroke : " + self._dicoMesures['Couleur' + str(s)] + ";}") svgStyle.append(' path.stature' + str(s) + " {stroke : " + self._dicoMesures['Couleur' + str(s)] + ";}") self._svgDrawing.add(svgStyle) self._freeze(self.__class__.__name__)
class byA_LineJaquePatternGenerator(byA_FrozenClass): def __init__(self, **kwargs): """Constructor """ byA_FrozenClass.__init__(self) self._liststatures = kwargs.get('liststatures', '') self._currentStature = None self._sheetSize = kwargs.get('sheetSize', a0Size) self._filename = kwargs.get('filename', 'pattern.svg') self._dicoConstruction = dict() self._dicoMesures = kwargs.get('dicoMesures', a0Size) w = str(self._sheetSize[0]).replace("cm", "") h = str(self._sheetSize[1]).replace("cm", "") self._svgDrawing = svgwrite.Drawing( self._filename, [str(int(w)) + 'cm', str(int(h)) + 'cm'], profile='full') self._svgDrawing.viewbox(width=str(int(w)), height=str(int(h))) self._inkscape = Inkscape(self._svgDrawing) self._Stature = dict() self._FrontPattern = dict() self._BackPattern = dict() self._MiddleFront = dict() self._MiddleBack = dict() self._HipLine = dict() self._WaistLine = dict() self._BustLine = dict() self._FrontBustLineMark = dict() self._BackBustLineMark = dict() self._FrontHipLineMark = dict() self._BackHipLineMark = dict() self._FrontBodiceLenghtLine = dict() self._BackBodiceLenghtLine = dict() self._FrontDartBustLine = dict() self._BackDartBustLine = dict() self._FrontDartWaistLine = dict() self._BackDartWaistLine = dict() self._FrontSideLine = dict() self._BackSideLine = dict() self._FrontSideCurve = dict() self._BackSideCurve = dict() self._FrontDart = dict() self._BackDart = dict() svgStyle = svgwrite.container.Style() svgStyle['id'] = "LineJaquePatternStyles" svgStyle.append(' text.nomenclature {font-family: cursive;}') svgStyle.append(' text.nomenclature {font-size:' + str(200 * PXCM) + ';}') svgStyle.append(' text.nomenclature {fill:#e6e6e6;}') svgStyle.append(' text.nomenclature {stroke-width:' + str(6 * PXCM) + ';}') svgStyle.append(' text.nomenclature {opacity:0.5}') svgStyle.append(' path.middleline {stroke:black;}') svgStyle.append(' path.middleline {stroke-width:' + str(15 * PXCM) + ';}') svgStyle.append(' path.middleline {opacity:1.0; }') svgStyle.append(' path.horizline {stroke:black;}') svgStyle.append(' path.horizline {stroke-width:' + str(6 * PXCM) + ';}') svgStyle.append(' path.horizline {stroke-dasharray:' + str(6) + ',' + str(3) + '}') svgStyle.append(' path.horizline {opacity:1.0; }') svgStyle.append(' circle.constructionPoint {stroke:none;}') #svgStyle.append(' circle.constructionPoint {fill:xxx;}') svgStyle.append(' circle.constructionPoint {opacity:0.5;}') svgStyle.append(' path.constructionLine {stroke:black;}') svgStyle.append(' path.constructionLine {stroke-width:' + str(6 * PXCM) + ';}') svgStyle.append(' path.constructionLine {stroke-dasharray:' + str(2) + ',' + str(2) + '}') svgStyle.append(' path.constructionLine {opacity:1.0; }') svgStyle.append(' path.constructionCurve {stroke:black;}') svgStyle.append(' path.constructionCurve {stroke-width:' + str(6 * PXCM) + ';}') svgStyle.append(' path.constructionCurve {stroke-dasharray:' + str(2) + ',' + str(2) + '}') svgStyle.append(' path.constructionCurve {opacity:1.0; }') svgStyle.append(' circle.finalPoint {stroke:none;}') #svgStyle.append(' circle.finalPoint {fill:xxx;}') svgStyle.append(' circle.finalPoint {opacity:0.5;}') svgStyle.append(' path.finalLine {fill:none;}') #svgStyle.append(' path.finalLine {stroke:xxx;}') svgStyle.append(' path.finalLine {stroke-width:' + str(25 * PXCM) + ';}') svgStyle.append(' path.finalLine {opacity:1.0; }') svgStyle.append(' path.finalCurve {fill:none;}') #svgStyle.append(' path.finalCurve {stroke:xxx;}') svgStyle.append(' path.finalCurve {stroke-width:' + str(25 * PXCM) + ';}') svgStyle.append(' path.finalCurve {opacity:1.0; }') #svgStyle.append(' .pointCaption {fill: black; font-family: Verdana; font-size:' + str(5*PXCM) + ';}') #svgStyle.append(' .pointCircle {fill: green;}') #svgStyle.append(' line.base {stroke-width:' + str(1*PXCM) + '; opacity:0.1}') #svgStyle.append(' path.base {stroke-width:' + str(1*PXCM) + '; opacity:0.1; stroke_linejoin:round}') #svgStyle.append(' line.bodiceadjust {stroke-width:' + str(1*PXCM) + '; stroke_linejoin:round}') #svgStyle.append(' path.bodiceadjust {stroke-width:' + str(1*PXCM) + '; stroke_linejoin:round}') #svgStyle.append(' line.elarg {stroke-width:' + str(1*PXCM) + '; stroke_linejoin:round}') #svgStyle.append(' path.elarg {stroke-width:' + str(1*PXCM) + '; stroke_linejoin:round}') #svgStyle.append(' line.abdomen {stroke-width:' + str(4.5*PXCM) + '; opacity:0.1; stroke-dasharray:' + str(0.15) +','+ str(0.05) + '}') #svgStyle.append(' path.abdomen {stroke-width:' + str(4.5*PXCM) + '; opacity:0.1; stroke-dasharray:' + str(0.15) +','+ str(0.05) + '}') #svgStyle.append(' line.coat {stroke-width:' + str(6*PXCM) + ';}') #svgStyle.append(' path.coat {stroke-width:' + str(6*PXCM) + ';}') #for sizeFigure, sizeTxt in enumerate(('thin', 'normal', 'bold')): # svgStyle.append(' line.' + sizeTxt + "{stroke-width : " + str((sizeFigure+1)*PXCM) + "; stroke-dasharray:" + str(0.05) +','+ str(0.05) + '}') # svgStyle.append(' path.' + sizeTxt + "{stroke-width : " + str((sizeFigure+1)*PXCM) + "; stroke-dasharray:" + str(0.05) +','+ str(0.05) + '}') for s in self._liststatures: svgStyle.append(' circle.stature' + str(s) + " {stroke : " + self._dicoMesures['Couleur' + str(s)] + ";}") svgStyle.append(' path.stature' + str(s) + " {stroke : " + self._dicoMesures['Couleur' + str(s)] + ";}") self._svgDrawing.add(svgStyle) self._freeze(self.__class__.__name__) def set_currentStature(self, stature): self._currentStature = stature #self._Stature[self._currentStature] = svgwrite.container.Group(id="groupStature"+self._currentStature) self._Stature[self._currentStature] = self._inkscape.layer( id="groupStature" + self._currentStature, label="groupStature" + self._currentStature, locked=False) self._FrontPattern[self._currentStature] = svgwrite.container.Group( id="groupFront" + self._currentStature) self._BackPattern[self._currentStature] = svgwrite.container.Group( id="groupBack" + self._currentStature) self._svgDrawing.add(self._Stature[self._currentStature]) self._Stature[self._currentStature].add( self._FrontPattern[self._currentStature]) self._Stature[self._currentStature].add( self._BackPattern[self._currentStature]) self._svgDrawing.save() def trace_MiddleFront(self): self._MiddleFront[self._currentStature] = byA_MiddleFront( parent=self, stature=self._currentStature, sheetSize=self._sheetSize, filename=self._filename) groupMiddleFront = svgwrite.container.Group(id="groupMiddleFront" + self._currentStature) self._FrontPattern[self._currentStature].add(groupMiddleFront) self._MiddleFront[self._currentStature].addToGroup(self._svgDrawing, groupMiddleFront, id="middleFront", class_='middleline') self._svgDrawing.save() def trace_MiddleBack(self): self._MiddleBack[self._currentStature] = byA_MiddleBack( parent=self, stature=self._currentStature, sheetSize=self._sheetSize, filename=self._filename) groupMiddleBack = svgwrite.container.Group(id="groupMiddleBack" + self._currentStature, debug=False) self._BackPattern[self._currentStature].add(groupMiddleBack) self._MiddleBack[self._currentStature].addToGroup(self._svgDrawing, groupMiddleBack, id="middleBack", class_='middleline') self._svgDrawing.save() def trace_HipLine(self): self._HipLine[self._currentStature] = byA_HipLine( parent=self, stature=self._currentStature, sheetSize=self._sheetSize, filename=self._filename) for side in ('Front', 'Back'): group = svgwrite.container.Group(id="groupHipLine" + side + self._currentStature, debug=False) self.__getattribute__('_' + side + 'Pattern')[self._currentStature].add(group) self._HipLine[self._currentStature].addToGroup(self._svgDrawing, group, id="HipLine" + side, class_='horizline') self._svgDrawing.save() def trace_WaistLine(self): self._WaistLine[self._currentStature] = byA_WaistLine( parent=self, stature=self._currentStature, sheetSize=self._sheetSize, filename=self._filename) for side in ('Front', 'Back'): group = svgwrite.container.Group(id="groupWaistLine" + side + self._currentStature, debug=False) self.__getattribute__('_' + side + 'Pattern')[self._currentStature].add(group) self._WaistLine[self._currentStature].addToGroup( self._svgDrawing, group, id="WaistLine" + side, class_='horizline') self._svgDrawing.save() def trace_BustLine(self): self._BustLine[self._currentStature] = byA_BustLine( parent=self, stature=self._currentStature, sheetSize=self._sheetSize, filename=self._filename) for side in ('Front', 'Back'): group = svgwrite.container.Group(id="groupBustLine" + side + self._currentStature, debug=False) self.__getattribute__('_' + side + 'Pattern')[self._currentStature].add(group) self._BustLine[self._currentStature].addToGroup(self._svgDrawing, group, id="BustLine" + side, class_='horizline') self._svgDrawing.save() def mark_FrontBustLine(self): self._FrontBustLineMark[self._currentStature] = byA_FrontBustLineMark( parent=self, stature=self._currentStature, sheetSize=self._sheetSize, filename=self._filename) groupBustLine = None for elem in self._FrontPattern[self._currentStature].elements: if (isinstance(elem, svgwrite.container.Group) and elem.get_id().startswith("groupBustLine")): groupBustLine = elem assert (groupBustLine is not None) self._FrontBustLineMark[self._currentStature].addToGroup( self._svgDrawing, groupBustLine, id="frontBustMark") self._svgDrawing.save() def mark_BackBustLine(self): self._BackBustLineMark[self._currentStature] = byA_BackBustLineMark( parent=self, stature=self._currentStature, sheetSize=self._sheetSize, filename=self._filename) groupBustLine = None for elem in self._BackPattern[self._currentStature].elements: if (isinstance(elem, svgwrite.container.Group) and elem.get_id().startswith("groupBustLine")): groupBustLine = elem assert (groupBustLine is not None) self._BackBustLineMark[self._currentStature].addToGroup( self._svgDrawing, groupBustLine, id="backBustMark") self._svgDrawing.save() def mark_FrontHipLine(self): self._FrontHipLineMark[self._currentStature] = byA_FrontHipLineMark( parent=self, stature=self._currentStature, sheetSize=self._sheetSize, filename=self._filename) groupHipLine = None for elem in self._FrontPattern[self._currentStature].elements: if (isinstance(elem, svgwrite.container.Group) and elem.get_id().startswith("groupHipLine")): groupHipLine = elem assert (groupHipLine is not None) self._FrontHipLineMark[self._currentStature].addToGroup( self._svgDrawing, groupHipLine, id="frontHipMark") self._svgDrawing.save() def mark_BackHipLine(self): self._BackHipLineMark[self._currentStature] = byA_BackHipLineMark( parent=self, stature=self._currentStature, sheetSize=self._sheetSize, filename=self._filename) groupHipLine = None for elem in self._BackPattern[self._currentStature].elements: if (isinstance(elem, svgwrite.container.Group) and elem.get_id().startswith("groupHipLine")): groupHipLine = elem assert (groupHipLine is not None) self._BackHipLineMark[self._currentStature].addToGroup( self._svgDrawing, groupHipLine, id="backHipMark") self._svgDrawing.save() def trace_FrontBodiceLenght(self): self._FrontBodiceLenghtLine[ self._currentStature] = byA_FrontBodiceLenghtLine( parent=self, stature=self._currentStature, sheetSize=self._sheetSize, filename=self._filename) groupFrontBodiceLenghtLine = svgwrite.container.Group( id="groupFrontBodiceLenghtLine" + self._currentStature, debug=False) self._FrontPattern[self._currentStature].add( groupFrontBodiceLenghtLine) self._FrontBodiceLenghtLine[self._currentStature].addToGroup( self._svgDrawing, groupFrontBodiceLenghtLine, id="frontBodiceLenghtLine") self._svgDrawing.save() def trace_BackBodiceLenght(self): self._BackBodiceLenghtLine[ self._currentStature] = byA_BackBodiceLenghtLine( parent=self, stature=self._currentStature, sheetSize=self._sheetSize, filename=self._filename) groupBackBodiceLenghtLine = svgwrite.container.Group( id="groupBackBodiceLenghtLine" + self._currentStature, debug=False) self._BackPattern[self._currentStature].add(groupBackBodiceLenghtLine) self._BackBodiceLenghtLine[self._currentStature].addToGroup( self._svgDrawing, groupBackBodiceLenghtLine, id="backBodiceLenghtLine") self._svgDrawing.save() def mark_FrontDartBustLine(self): self._FrontDartBustLine[self._currentStature] = byA_FrontDartBustLine( parent=self, stature=self._currentStature, sheetSize=self._sheetSize, filename=self._filename) groupBustLine = None for elem in self._FrontPattern[self._currentStature].elements: if (isinstance(elem, svgwrite.container.Group) and elem.get_id().startswith("groupBustLine")): groupBustLine = elem assert (groupBustLine is not None) self._FrontDartBustLine[self._currentStature].addToGroup( self._svgDrawing, groupBustLine, id="frontDartBustMark") self._svgDrawing.save() def mark_BackDartBustLine(self): self._BackDartBustLine[self._currentStature] = byA_BackDartBustLine( parent=self, stature=self._currentStature, sheetSize=self._sheetSize, filename=self._filename) groupBustLine = None for elem in self._BackPattern[self._currentStature].elements: if (isinstance(elem, svgwrite.container.Group) and elem.get_id().startswith("groupBustLine")): groupBustLine = elem assert (groupBustLine is not None) self._BackDartBustLine[self._currentStature].addToGroup( self._svgDrawing, groupBustLine, id="backDartBustMark") self._svgDrawing.save() def mark_FrontDartWaistLine(self): self._FrontDartWaistLine[ self._currentStature] = byA_FrontDartWaistLine( parent=self, stature=self._currentStature, sheetSize=self._sheetSize, filename=self._filename) groupWaistLine = None for elem in self._FrontPattern[self._currentStature].elements: if (isinstance(elem, svgwrite.container.Group) and elem.get_id().startswith("groupWaistLine")): groupWaistLine = elem assert (groupWaistLine is not None) self._FrontDartWaistLine[self._currentStature].addToGroup( self._svgDrawing, groupWaistLine, id="frontDartWaistMark") self._svgDrawing.save() def mark_BackDartWaistLine(self): self._BackDartWaistLine[self._currentStature] = byA_BackDartWaistLine( parent=self, stature=self._currentStature, sheetSize=self._sheetSize, filename=self._filename) groupWaistLine = None for elem in self._BackPattern[self._currentStature].elements: if (isinstance(elem, svgwrite.container.Group) and elem.get_id().startswith("groupWaistLine")): groupWaistLine = elem assert (groupWaistLine is not None) self._BackDartWaistLine[self._currentStature].addToGroup( self._svgDrawing, groupWaistLine, id="backDartWaistMark") self._svgDrawing.save() def mark_FrontSideLine(self): self._FrontSideLine[self._currentStature] = byA_FrontSideLine( parent=self, stature=self._currentStature, sheetSize=self._sheetSize, filename=self._filename) groupFrontSide = svgwrite.container.Group(id="groupFrontSide" + self._currentStature, debug=False) self._FrontPattern[self._currentStature].add(groupFrontSide) self._FrontSideLine[self._currentStature].addToGroup( self._svgDrawing, groupFrontSide, id="frontSideLine") self._svgDrawing.save() def mark_BackSideLine(self): self._BackSideLine[self._currentStature] = byA_BackSideLine( parent=self, stature=self._currentStature, sheetSize=self._sheetSize, filename=self._filename) groupBackSide = svgwrite.container.Group(id="groupBackSide" + self._currentStature, debug=False) self._BackPattern[self._currentStature].add(groupBackSide) self._BackSideLine[self._currentStature].addToGroup(self._svgDrawing, groupBackSide, id="backSideLine") self._svgDrawing.save() def trace_FrontSideCurve(self): self._FrontSideCurve[self._currentStature] = byA_FrontSideCurve( parent=self, stature=self._currentStature, sheetSize=self._sheetSize, filename=self._filename) groupFrontSide = None for elem in self._FrontPattern[self._currentStature].elements: if (isinstance(elem, svgwrite.container.Group) and elem.get_id().startswith("groupFrontSide")): groupFrontSide = elem assert (groupFrontSide is not None) self._FrontSideCurve[self._currentStature].addToGroup( self._svgDrawing, groupFrontSide, id="frontSideLine") self._svgDrawing.save() def trace_BackSideCurve(self): self._BackSideCurve[self._currentStature] = byA_BackSideCurve( parent=self, stature=self._currentStature, sheetSize=self._sheetSize, filename=self._filename) groupBackSide = None for elem in self._BackPattern[self._currentStature].elements: if (isinstance(elem, svgwrite.container.Group) and elem.get_id().startswith("groupBackSide")): groupBackSide = elem assert (groupBackSide is not None) self._BackSideCurve[self._currentStature].addToGroup( self._svgDrawing, groupBackSide, id="backSideCurve") self._svgDrawing.save() def trace_FrontDart(self): self._FrontDart[self._currentStature] = byA_FrontDart( parent=self, stature=self._currentStature, sheetSize=self._sheetSize, filename=self._filename) groupFrontDart = svgwrite.container.Group(id="groupFrontDart" + self._currentStature, debug=False) self._FrontPattern[self._currentStature].add(groupFrontDart) self._FrontDart[self._currentStature].addToGroup(self._svgDrawing, groupFrontDart, id="frontSideCurve") self._svgDrawing.save() def trace_BackDart(self): self._BackDart[self._currentStature] = byA_BackDart( parent=self, stature=self._currentStature, sheetSize=self._sheetSize, filename=self._filename) groupBackDart = svgwrite.container.Group(id="groupBackDart" + self._currentStature, debug=False) self._BackPattern[self._currentStature].add(groupBackDart) self._BackDart[self._currentStature].addToGroup(self._svgDrawing, groupBackDart, id="backSideLine") self._svgDrawing.save() def trace_AllStatures(self): for stature in self._liststatures: print stature pattern.set_currentStature(stature) pattern.trace_MiddleFront() pattern.trace_MiddleBack() pattern.trace_HipLine() pattern.trace_WaistLine() pattern.trace_BustLine() pattern.mark_FrontBustLine() pattern.mark_BackBustLine() pattern.mark_FrontHipLine() pattern.mark_BackHipLine() pattern.trace_FrontBodiceLenght() pattern.trace_BackBodiceLenght() pattern.mark_FrontDartBustLine() pattern.mark_BackDartBustLine() pattern.mark_FrontDartWaistLine() pattern.mark_BackDartWaistLine() pattern.mark_FrontSideLine() pattern.mark_BackSideLine() pattern.trace_FrontSideCurve() pattern.trace_BackSideCurve() pattern.trace_BackDart() pattern.trace_FrontDart() def save(self): self._svgDrawing.save()
def write_svg( output: TextIO, document: Document, page_size: Optional[Tuple[float, float]] = None, center: bool = False, source_string: str = "", layer_label_format: str = "%d", show_pen_up: bool = False, color_mode: str = "none", ) -> None: """Create a SVG from a :py:class:`Document` instance. If no page size is provided (or (0, 0) is passed), the SVG generated has bounds tightly fitted around the geometries. Otherwise the provided size (in pixel) is used. The width and height is capped to a minimum of 1 pixel. By default, no translation is applied on the geometry. If `center=True`, geometries are moved to the center of the page. No scaling or rotation is applied to geometries. Layers are named after `layer_label_format`, which may contain a C-style format specifier such as `%d` which will be replaced by the layer number. For previsualisation purposes, pen-up trajectories can be added to the SVG and path can be colored individually (``color_mode="path"``) or layer-by-layer (``color_mode="layer"``). Args: output: text-mode IO stream where SVG code will be written document: geometries to be written page_size: if provided, overrides document.page_size center: center geometries on page before export source_string: value of the `source` metadata layer_label_format: format string for layer label naming show_pen_up: add paths for the pen-up trajectories color_mode: "none" (no formatting), "layer" (one color per layer), "path" (one color per path) """ # compute bounds bounds = document.bounds() if bounds is None: # empty geometry, we provide fake bounds bounds = (0, 0, 1, 1) if page_size: size = page_size tight = page_size == (0.0, 0.0) elif document.page_size: size = document.page_size tight = False else: size = (bounds[2] - bounds[0], bounds[3] - bounds[1]) tight = True if center: corrected_doc = copy.deepcopy(document) corrected_doc.translate( (size[0] - (bounds[2] - bounds[0])) / 2.0 - bounds[0], (size[1] - (bounds[3] - bounds[1])) / 2.0 - bounds[1], ) elif tight: corrected_doc = copy.deepcopy(document) corrected_doc.translate(-bounds[0], -bounds[1]) else: corrected_doc = document # output SVG, width/height are capped to 1px capped_size = tuple(max(1, s) for s in size) size_cm = tuple(f"{round(s / UNITS['cm'], 8)}cm" for s in capped_size) dwg = svgwrite.Drawing(size=size_cm, profile="tiny", debug=False) inkscape = Inkscape(dwg) dwg.attribs.update({ "viewBox": f"0 0 {capped_size[0]} {capped_size[1]}", "xmlns:dc": "http://purl.org/dc/elements/1.1/", "xmlns:cc": "http://creativecommons.org/ns#", "xmlns:rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", }) # add metadata metadata = ElementTree.Element("rdf:RDF") work = ElementTree.SubElement(metadata, "cc:Work") fmt = ElementTree.SubElement(work, "dc:format") fmt.text = "image/svg+xml" source = ElementTree.SubElement(work, "dc:source") source.text = source_string date = ElementTree.SubElement(work, "dc:date") date.text = datetime.datetime.now().isoformat() dwg.set_metadata(metadata) color_idx = 0 if show_pen_up: group = inkscape.layer(label="% pen up trajectories") group.attribs["fill"] = "none" group.attribs["stroke"] = "black" group.attribs[ "style"] = "display:inline; stroke-opacity: 50%; stroke-width: 0.5" group.attribs["id"] = "pen_up_trajectories" for layer in corrected_doc.layers.values(): for line in layer.pen_up_trajectories(): group.add( dwg.line((line[0].real, line[0].imag), (line[-1].real, line[-1].imag))) dwg.add(group) for layer_id in sorted(corrected_doc.layers.keys()): layer = corrected_doc.layers[layer_id] group = inkscape.layer(label=str(layer_label_format % layer_id)) group.attribs["fill"] = "none" if color_mode == "layer": group.attribs["stroke"] = _COLORS[color_idx % len(_COLORS)] color_idx += 1 else: group.attribs["stroke"] = "black" group.attribs["style"] = "display:inline" group.attribs["id"] = f"layer{layer_id}" for line in layer: if len(line) <= 1: continue if len(line) == 2: path = dwg.line((line[0].real, line[0].imag), (line[1].real, line[1].imag)) elif line[0] == line[-1]: path = dwg.polygon((c.real, c.imag) for c in line[:-1]) else: path = dwg.polyline((c.real, c.imag) for c in line) if color_mode == "path": path.attribs["stroke"] = _COLORS[color_idx % len(_COLORS)] color_idx += 1 group.add(path) dwg.add(group) dwg.write(output, pretty=True)
def unit_to_svg(representation): drawing = svgwrite.Drawing(size=(PAPER_WIDTH, PAPER_HEIGHT)) inkscape = Inkscape(drawing) layers = {} return add_to_drawing(drawing, inkscape, layers, representation)
def main(): grid = {(x, y): None for x in range(GRID_WIDTH) for y in range(GRID_HEIGHT)} squares_filled = 0 sq_counter = 0 iters = 0 lines = [] circles = [] while squares_filled < GRID_WIDTH * GRID_HEIGHT: iters += 1 if iters == 1000000: break print("iter {} filled {} / {} squares {}".format( iters, squares_filled, GRID_HEIGHT * GRID_WIDTH, sq_counter)) size = random.randint(50, 125) x1 = random.randint(0, GRID_WIDTH - 1) y1 = random.randint(0, GRID_HEIGHT - 1) if x1 + size >= GRID_WIDTH or y1 + size >= GRID_HEIGHT: continue all_free = all(grid[(x1 + x, y1 + y)] is None for x in range(size - 1) for y in range(size - 1)) if not all_free: continue squares_filled += size * size for x in range(size - 1): for y in range(size - 1): grid[(x1 + x, y1 + y)] = sq_counter sq_counter += 1 # if x1 == 0: # lines.append(((x1, y1), (x1 + size, y1))) # if y1 == 0: # lines.append(((x1, y1), (x1, y1 + size))) lines.append(((x1, y1 + size), (x1 + size, y1 + size))) lines.append(((x1 + size, y1), (x1 + size, y1 + size))) circles.append((x1 + size / 2, y1 + size / 2, size / 2)) drawing = svgwrite.Drawing(size=(1056, 816), filename='grid.svg') inkscape = Inkscape(drawing) layer = inkscape.layer("0 squares") layer2 = inkscape.layer("1 circles") opt = lines # opt = optimize_lines(lines) offset = (93, 61) for line in opt: start_pt = line[0][0] + offset[0], line[0][1] + offset[1] end_pt = line[1][0] + offset[0], line[1][1] + offset[1] layer.add( drawing.line(start_pt, end_pt, stroke_width=1, stroke=svgwrite.rgb(0, 0, 0))) circles = optimize_circles(circles) for circle in circles: layer2.add( drawing.circle(center=(circle[0] + offset[0], circle[1] + offset[1]), r=circle[2] - 1, stroke_width=1, stroke=svgwrite.rgb(0, 0, 0), fill='none')) # drawing.add(layer) drawing.add(layer2) drawing.save(pretty=True, indent=2)
# Author: mozman # Purpose: testing area for inkscape extension # Created: 06.08.2018 # Copyright (c) 2018 Manfred Moitzi based on ideas of Antonio Ospite <*****@*****.**> # License: MIT License import svgwrite from svgwrite.extensions import Inkscape dwg = svgwrite.Drawing('test-inkscape-extension.svg', profile='full', size=(640, 480)) inkscape = Inkscape(dwg) layer = inkscape.layer(label="top LAYER 1", locked=True) dwg.add(layer) line = dwg.line((100, 100), (300, 100), stroke=svgwrite.rgb(10, 10, 16, '%'), stroke_width=10) layer.add(line) text = dwg.text('Test', insert=(100, 100), font_size=100, fill='red') layer.add(text) nested_layer = inkscape.layer(label="nested LAYER 2", locked=False) layer.add(nested_layer) text = dwg.text('Test2', insert=(100, 200), font_size=100, fill='blue') nested_layer.add(text) dwg.save()
def main_func( drawing_width, drawing_height, m_rows, n_columns, n_polygons_per_panel, output_filebasename, colors=None, n_colors=None, pct_jitter_vertices=0, random_seed=None, append_datetime=False, ): if colors is None and n_colors is not None: colors = get_color_codes(n_colors, COLORS) elif colors: pass else: colors = ["#000000"] out_path_base = ( f"{output_filebasename}_{len(colors)}_colors_{n_polygons_per_panel}_perpanel" f"_jitter_{pct_jitter_vertices}_polygons_{random_seed or 'none'}") if append_datetime: d = datetime.utcnow() out_path_base = out_path_base + "_" + d.strftime("%s%f") out_path = out_path_base + ".svg" dwg = svgwrite.Drawing( OUTPUT_DIR.joinpath(out_path), profile="full", size=(drawing_width, drawing_height), ) inkscape = Inkscape(dwg) inkscape_layers = [] for c in colors: layer = inkscape.layer(label=f"Layer {c}", locked=False) inkscape_layers.append(layer) dwg.add(layer) # set random seeds if random_seed is not None: random.seed(random_seed) np.random.seed(random_seed) grid = Grid( drawing_width, drawing_height, m_rows=m_rows, n_columns=n_columns, n_polygons_per_panel=n_polygons_per_panel, colors=colors, ) grid.make_panels() # add grid objects to drawing for coords, panel in grid.panels.items(): panel.make_polygons(colors=colors, pct_jitter_vertices=pct_jitter_vertices) for polygon in panel.polygons: layer_index = 0 if len(inkscape_layers) > 1: layer_index = colors.index(polygon.attribs["stroke"]) inkscape_layers[layer_index].add(polygon) dwg.save()
def main(): drawing = svgwrite.Drawing(size=(1056, 816), filename='grid.svg') inkscape = Inkscape(drawing) layer = inkscape.layer("0 main") cns = inkscape.layer("999 construction") # layer.add(drawing.line(start_pt, end_pt, stroke_width=1, stroke=svgwrite.rgb(0, 0, 0))) center_pt = 400, 400 def rel_pt(pt): x, y = pt return x + center_pt[0], y + center_pt[1] out_circle_rad = 150 d = drawing.circle(center=center_pt, r=out_circle_rad, stroke_width=1, stroke=svgwrite.rgb(0, 0, 0), fill='none') layer.add(d) inner_circles_rad = [150 - (20 * i) for i in range(1, 7)] circle_arm = (-3/4) * math.pi cumu = -out_circle_rad for c, icr in enumerate(inner_circles_rad): m = 4 if c % 2 == 0: m = -4 cumu -= icr * m cy = math.sin(circle_arm) * (cumu) cx = math.cos(circle_arm) * (cumu) center = rel_pt((cx, cy)) c = drawing.circle(center=center, r=icr, stroke_width=1, stroke=svgwrite.rgb(0, 0, 0), fill='none') layer.add(c) cns.add(drawing.line(center_pt, center, stroke_width=1, stroke=svgwrite.rgb(0, 0, 255))) # Calculate a line perpindicular to the ray that this inner circle is on perp_rad = circle_arm - 1 * math.pi/2 run = math.cos(perp_rad) rise = math.sin(perp_rad) ie_x = run * icr + center[0] ie_y = rise * icr + center[1] cns.add(drawing.line(center, (ie_x, ie_y), stroke_width=1, stroke=svgwrite.rgb(0, 0, 255))) cns.add(drawing.circle((ie_x, ie_y), r=5, stroke_width=1, stroke=svgwrite.rgb(0, 0, 255), fill='none')) # x^2 + y^2 = (out_circle_rad)^2 # -(rise / run) x + q = y # -(rise / run) (ie_x) + q = (ie_y) perp_rad = perp_rad - math.pi / 2 run = math.cos(perp_rad) rise = math.sin(perp_rad) slope = rise / run q = ie_y - slope * ie_x t1 = (ie_x, slope * ie_x + q) t2 = (ie_x + 10, slope * (ie_x + 10) + q) cns.add(drawing.line(t1, t2, stroke_width=1, stroke=svgwrite.rgb(0, 0, 255))) q = (ie_y - center[1]) - slope * (ie_x - center[0]) a = (slope ** 2 + 1) b = 2 * q * slope c = q ** 2 - out_circle_rad ** 2 for x in real_nums(quadratic_eq(a, b, c)): y = math.sqrt(out_circle_rad ** 2 - x ** 2) + center_pt[1] x += center_pt[0] delta = abs(slope * x + q - y) print(delta) if delta < 1: break print(x, y) mx, my = mid_pt((ie_x, ie_y), (x, y)) cns.add(drawing.circle((mx, my), r=5, stroke_width=1, stroke=svgwrite.rgb(0, 0, 255), fill='none')) ln = drawing.line((ie_x, ie_y), (x, y), stroke_width=1, stroke=svgwrite.rgb(0, 0, 0)) layer.add(ln) # Now draw a vertical line to the edge of the circle dy = y - center_pt[1] uy = center_pt[1] - dy ln = drawing.line((x, y), (x, uy), stroke_width=1, stroke=svgwrite.rgb(0, 0, 0)) layer.add(ln) #cumu -= icr * m drawing.add(layer) drawing.add(cns) drawing.save(pretty=True, indent=2)
def test_layer(dwg): inkscape = Inkscape(dwg) layer = inkscape.layer(label="Layer one", locked=True) dwg.add(layer) assert layer[GROUP_MODE] == 'layer' assert layer[LABEL] == 'Layer one'