Ejemplo n.º 1
0
 def query(self, cmd):
     if (self.port is not None) and (cmd is not None):
         response = ''
         try:
             self.write(cmd)
             response = self.readline()
             nRetryCount = 0
             while (len(response) == 0) and (nRetryCount < 100):
                 if self.doLog:
                     self.log('QUERY', 'read %d' % nRetryCount)
                 response = self.readline()
                 nRetryCount += 1
                 if self.doLog:
                     self.log('QUERY', 'response is '+response)
             # swallow 'ok'
             nRetryCount = 0
             ok = self.readline()
             while (len(ok) == 0) and (nRetryCount < 100):
                 ok = self.readline()
                 nRetryCount += 1
         except serial.SerialException:
             inkex.errormsg(gettext.gettext("Error reading serial data."))
         return response
     else:
         return None
Ejemplo n.º 2
0
    def get_filename_parts(self):
        '''
        Attempts to get directory and image as passed in by the inkscape
        dialog. If the boolean ignore flag is set, then it will ignore
        these settings and try to use the settings from the export
        filename.
        '''

        if self.options.ignore == False:
            if self.options.image == "" or self.options.image is None:
                inkex.errormsg("Please enter an image name")
                sys.exit(0)
            return (self.options.directory, self.options.image)
        else:
            '''
            First get the export-filename from the document, if the
            document has been exported before (TODO: Will not work if it
            hasn't been exported yet), then uses this to return a tuple
            consisting of the directory to export to, and the filename
            without extension.
            '''
            svg = self.document.getroot()
            att = '{http://www.inkscape.org/namespaces/inkscape}export-filename'
            try:
                export_file = svg.attrib[att]
            except KeyError:
                inkex.errormsg("To use the export hints option, you " +
                "need to have previously exported the document. " +
                "Otherwise no export hints exist!")
                sys.exit(-1)
            dirname, filename = os.path.split(export_file)
            filename = filename.rsplit(".", 1)[0] # Without extension
            return (dirname, filename)
Ejemplo n.º 3
0
def query( comPort, cmd ):
    if (comPort is not None) and (cmd is not None):
        response = ''
        try:
            debug('sending query:', cmd)

            comPort.write( cmd.encode('ascii')  )
            response = comPort.readline().decode('ascii')
            debug('response:', response)
            nRetryCount = 0
            while ( len(response) == 0 ) and ( nRetryCount < 100 ):
                # get new response to replace null response if necessary
                response = comPort.readline()
                nRetryCount += 1
            if cmd.strip().lower() not in ["v","i","a", "mr","pi","qm"]:
                #Most queries return an "OK" after the data requested.
                #We skip this for those few queries that do not return an extra line.
                unused_response = comPort.readline() #read in extra blank/OK line
                nRetryCount = 0
                while ( len(unused_response) == 0 ) and ( nRetryCount < 100 ):
                    # get new response to replace null response if necessary
                    unused_response = comPort.readline()
                    nRetryCount += 1
        except:
            inkex.errormsg( gettext.gettext( "Error reading serial data." ) )
        return response
    else:
        return None
Ejemplo n.º 4
0
def cspcofm(csp):
    area = csparea(csp)
    xc = 0.0
    yc = 0.0
    if abs(area) < 1.0e-8:
        inkex.errormsg(_("Area is zero, cannot calculate Center of Mass"))
        return 0, 0
    for sp in csp:
        for i in range(len(sp)):  # calculate polygon moment
            xc += (
                sp[i - 1][1][1]
                * (sp[i - 2][1][0] - sp[i][1][0])
                * (sp[i - 2][1][0] + sp[i - 1][1][0] + sp[i][1][0])
                / 6
            )
            yc += (
                sp[i - 1][1][0]
                * (sp[i][1][1] - sp[i - 2][1][1])
                * (sp[i - 2][1][1] + sp[i - 1][1][1] + sp[i][1][1])
                / 6
            )
        for i in range(1, len(sp)):  # add contribution from cubic Bezier
            vec_x = numpy.matrix([sp[i - 1][1][0], sp[i - 1][2][0], sp[i][0][0], sp[i][1][0]])
            vec_y = numpy.matrix([sp[i - 1][1][1], sp[i - 1][2][1], sp[i][0][1], sp[i][1][1]])
            vec_t = numpy.matrix(
                [
                    (vec_x * mat_cofm_0 * vec_y.T)[0, 0],
                    (vec_x * mat_cofm_1 * vec_y.T)[0, 0],
                    (vec_x * mat_cofm_2 * vec_y.T)[0, 0],
                    (vec_x * mat_cofm_3 * vec_y.T)[0, 0],
                ]
            )
            xc += (vec_x * vec_t.T)[0, 0] / 280
            yc += (vec_y * vec_t.T)[0, 0] / 280
    return -xc / area, -yc / area
    def collectAndZipImages(self, node, docname, z):
        xlink = node.get(inkex.addNS('href',u'xlink'))
        if (xlink[:4]!='data'):
            absref=node.get(inkex.addNS('absref',u'sodipodi'))
            url=urlparse.urlparse(xlink)
            href=urllib.url2pathname(url.path)
            
            if (href != None):
                absref=os.path.realpath(href)

            absref=unicode(absref, "utf-8")

            if (os.path.isfile(absref)):
                shutil.copy(absref, self.tmp_dir)
                z.write(absref, os.path.basename(absref).encode(self.encoding))
            elif (os.path.isfile(os.path.join(self.tmp_dir, absref))):
                #TODO: please explain why this clause is necessary
                shutil.copy(os.path.join(self.tmp_dir, absref), self.tmp_dir)
                z.write(os.path.join(self.tmp_dir, absref),
                        os.path.basename(absref).encode(self.encoding))
            else:
                inkex.errormsg(_('Could not locate file: %s') % absref)

            node.set(inkex.addNS('href',u'xlink'),os.path.basename(absref))
            node.set(inkex.addNS('absref',u'sodipodi'),os.path.basename(absref))
Ejemplo n.º 6
0
    def autoNumber(errorCorrectLevel, dataList):

        for tn in range (1, 40):
            
            rsBlocks = QRRSBlock.getRSBlocks(tn, errorCorrectLevel)

            buffer = QRBitBuffer();

            for i in range(len(dataList)):
                data = dataList[i]
                buffer.put(data.mode, 4)
                buffer.put(data.getLength(), QRUtil.getLengthInBits(data.mode, tn) )
                data.write(buffer)

            #// calc num max data.
            totalDataCount = 0;
            for i in range(len(rsBlocks)):
                totalDataCount += rsBlocks[i].dataCount

            if (buffer.getLengthInBits() <= totalDataCount * 8):
                return tn

        inkex.errormsg("Even the largest size won't take this much data ("
            + str(buffer.getLengthInBits())
            + ">"
            +  str(totalDataCount * 8)
            + ")")
        sys.exit()
Ejemplo n.º 7
0
	def effect(self):
		# Check version.
		scriptNodes = self.document.xpath("//svg:script[@jessyink:version='1.5.5']", namespaces=inkex.NSS)

		if len(scriptNodes) != 1:
			inkex.errormsg(_("The JessyInk script is not installed in this SVG file or has a different version than the JessyInk extensions. Please select \"install/update...\" from the \"JessyInk\" sub-menu of the \"Extensions\" menu to install or update the JessyInk script.\n\n"))

		# Remove old mouse handler
		for node in self.document.xpath("//jessyink:mousehandler", namespaces=inkex.NSS):
			node.getparent().remove(node)
		
		if self.options.mouseSettings == "noclick":
			# Create new script node.
			scriptElm = inkex.etree.Element(inkex.addNS("script", "svg"))
			scriptElm.text = open(os.path.join(os.path.dirname(__file__),	"jessyInk_core_mouseHandler_noclick.js")).read()
			groupElm = inkex.etree.Element(inkex.addNS("mousehandler", "jessyink"))
			groupElm.set("{" + inkex.NSS["jessyink"] + "}subtype", "jessyInk_core_mouseHandler_noclick")
			groupElm.append(scriptElm)
			self.document.getroot().append(groupElm)
		elif self.options.mouseSettings == "draggingZoom":
			# Create new script node.
			scriptElm = inkex.etree.Element(inkex.addNS("script", "svg"))
			scriptElm.text = open(os.path.join(os.path.dirname(__file__),	"jessyInk_core_mouseHandler_zoomControl.js")).read()
			groupElm = inkex.etree.Element(inkex.addNS("mousehandler", "jessyink"))
			groupElm.set("{" + inkex.NSS["jessyink"] + "}subtype", "jessyInk_core_mouseHandler_zoomControl")
			groupElm.append(scriptElm)
			self.document.getroot().append(groupElm)
Ejemplo n.º 8
0
	def effect(self):
		# Check version.
		scriptNodes = self.document.xpath("//svg:script[@jessyink:version='1.5.6']", namespaces=inkex.NSS)

		if len(scriptNodes) != 1:
			inkex.errormsg(_(u"JessyInk_c 还未安装到这个SVG文件,或者版本不同. 请使用 “扩展” 菜单下 “JessyInk_c” 的 “安装/升级...” 命令进行JessyInk_c 的安装。\n\n"))

		if len(self.selected) == 0:
			inkex.errormsg(_(u"没有选择操作对象。请选择一个要设置演示特效的对象。\n"))

		for id, node in list(self.selected.items()):
			if (self.options.effectIn == "appear") or (self.options.effectIn == "fade") or (self.options.effectIn == "pop") or (self.options.effectIn == "tata"):
				node.set("{" + inkex.NSS["jessyink"] + "}effectIn","name:" + self.options.effectIn  + ";order:" + self.options.effectInOrder + ";length:" + str(int(self.options.effectInDuration * 1000)))
				# Remove possible view argument.
				if "{" + inkex.NSS["jessyink"] + "}view" in node.attrib:
					del node.attrib["{" + inkex.NSS["jessyink"] + "}view"]
			else:
				if "{" + inkex.NSS["jessyink"] + "}effectIn" in node.attrib:
					del node.attrib["{" + inkex.NSS["jessyink"] + "}effectIn"]
		
			if (self.options.effectOut == "appear") or (self.options.effectOut == "fade") or (self.options.effectOut == "pop"):
				node.set("{" + inkex.NSS["jessyink"] + "}effectOut","name:" + self.options.effectOut  + ";order:" + self.options.effectOutOrder + ";length:" + str(int(self.options.effectOutDuration * 1000)))
				# Remove possible view argument.
				if "{" + inkex.NSS["jessyink"] + "}view" in node.attrib:
					del node.attrib["{" + inkex.NSS["jessyink"] + "}view"]
			else:
				if "{" + inkex.NSS["jessyink"] + "}effectOut" in node.attrib:
					del node.attrib["{" + inkex.NSS["jessyink"] + "}effectOut"]
Ejemplo n.º 9
0
    def effect(self):

        scale = self.unittouu("1px")  # convert to document units
        so = self.options

        if so.TEXT == "":  # abort if converting blank text
            inkex.errormsg(_("Please enter an input text"))
        else:

            # INKSCAPE GROUP TO CONTAIN EVERYTHING

            so.TEXT = unicode(so.TEXT, so.input_encode)
            centre = tuple(
                computePointInNode(list(self.view_center), self.current_layer)
            )  # Put in in the centre of the current view
            grp_transform = "translate" + str(centre) + " scale(%f)" % scale
            grp_name = "QR Code: " + so.TEXT
            grp_attribs = {inkex.addNS("label", "inkscape"): grp_name, "transform": grp_transform}
            grp = inkex.etree.SubElement(self.current_layer, "g", grp_attribs)  # the group to put everything in

            # GENERATE THE QRCODE
            qr = QRCode(int(so.TYPENUMBER), int(so.CORRECTIONLEVEL))
            qr.addData(so.TEXT)
            qr.make()
            qr.makeSVG(grp, so.MODULESIZE)
Ejemplo n.º 10
0
def TOC_buildList(root):
    tocList = []
    sectionIndex = 0
    subsectionIndex = 0
    for node in root:
        if node.tag == '{http://www.w3.org/2000/svg}g':
            if node.attrib['{http://www.inkscape.org/namespaces/inkscape}'+
                    'groupmode'] == 'layer':
                label = node.attrib\
                        ['{http://www.inkscape.org/namespaces/inkscape}label']
                titlePattern = re.compile("^\#(sub)?section ")
                if re.match(titlePattern, label):
                    sectionPattern = re.compile("^\#section ")
                    if re.match(sectionPattern, label):
                        sectionIndex = sectionIndex+1
                        subsectionIndex = 0
                    else:
                        if sectionIndex == 0:
                            inkex.errormsg("Subsection outside any section")
                            return []
                        subsectionIndex = subsectionIndex+1
                    index = (sectionIndex, subsectionIndex)
                    title = label.split(' ', 1)[1]
                    tocList.append({'id':node.attrib['id'],
                        'title':title, 'index':index})
    return(tocList)
Ejemplo n.º 11
0
def pack(points):
	#最初の4点は輪郭とわかっている
	segments=[]
	#外枠部分
	inkex.errormsg(u"外枠:"+str(points))
	lastv=Vertex(points[0][0],points[0][1])
	verts=[lastv]
	gVerts.append(lastv)
	for p in points[1:4]:
		v=Vertex(p[0],p[1])
		gVerts.append(v)
		segment=Segment(lastv,v)
		segment.fixed=True
		segments.append(segment)
		v.pre=segment
		lastv.post=segment
		lastv=v
	#三角形を作る
	inkex.errormsg(u"gVerts:"+str(gVerts))
	nodes=[Node(Triangle(gVerts[0],gVerts[1],gVerts[2]))]
	nodes.append(Node(Triangle(gVerts[2],gVerts[3],gVerts[0])))
	#自分で描いたパス部分
	for p in points[4:]:
		v=Vertex(p[0],p[1])
		gVerts.append(v);
		segment=Segment(lastv,v)
		segments.append(segment)
		v.pre=segment
		lastv.post=segment
		lastv=v
	return segments,nodes
Ejemplo n.º 12
0
    def effect(self):
        # Check version.
        scriptNodes = self.document.xpath("//svg:script[@jessyink:version='1.5.5']", namespaces=inkex.NSS)

        if len(scriptNodes) != 1:
            inkex.errormsg(
                _(
                    'The JessyInk script is not installed in this SVG file or has a different version than the JessyInk extensions. Please select "install/update..." from the "JessyInk" sub-menu of the "Extensions" menu to install or update the JessyInk script.\n\n'
                )
            )

        if len(self.selected) == 0:
            inkex.errormsg(
                _(
                    "No object selected. Please select the object you want to assign an effect to and then press apply.\n"
                )
            )

        for id, node in self.selected.items():
            if (
                (self.options.effectIn == "appear")
                or (self.options.effectIn == "fade")
                or (self.options.effectIn == "pop")
            ):
                node.set(
                    "{" + inkex.NSS["jessyink"] + "}effectIn",
                    "name:"
                    + self.options.effectIn
                    + ";order:"
                    + self.options.effectInOrder
                    + ";length:"
                    + str(int(self.options.effectInDuration * 1000)),
                )
                # Remove possible view argument.
                if node.attrib.has_key("{" + inkex.NSS["jessyink"] + "}view"):
                    del node.attrib["{" + inkex.NSS["jessyink"] + "}view"]
            else:
                if node.attrib.has_key("{" + inkex.NSS["jessyink"] + "}effectIn"):
                    del node.attrib["{" + inkex.NSS["jessyink"] + "}effectIn"]

            if (
                (self.options.effectOut == "appear")
                or (self.options.effectOut == "fade")
                or (self.options.effectOut == "pop")
            ):
                node.set(
                    "{" + inkex.NSS["jessyink"] + "}effectOut",
                    "name:"
                    + self.options.effectOut
                    + ";order:"
                    + self.options.effectOutOrder
                    + ";length:"
                    + str(int(self.options.effectOutDuration * 1000)),
                )
                # Remove possible view argument.
                if node.attrib.has_key("{" + inkex.NSS["jessyink"] + "}view"):
                    del node.attrib["{" + inkex.NSS["jessyink"] + "}view"]
            else:
                if node.attrib.has_key("{" + inkex.NSS["jessyink"] + "}effectOut"):
                    del node.attrib["{" + inkex.NSS["jessyink"] + "}effectOut"]
Ejemplo n.º 13
0
 def log(self, type, text):
     ts = datetime.datetime.now()
     try:
         with open("4xidraw-serial.log", "a") as myfile:
             myfile.write('--- %s\n%s\n%s\n' % (ts.isoformat(), type, escaped(text)))
     except:
         inkex.errormsg(gettext.gettext("Error logging serial data."))
def qrcode_generate(content, size, padding, version, em, ec):

    attribs = {
        'content': content,
        'size': size,
        'padding': padding,
        'em': em,
        'ec': ec,
        'format': 'svg',
        'source': 'inkscape'
    }
    
    if version > 0:
        attribs['version'] = version
    
    headers = {
        #User-Agent: QRCode/3.0 (Windows 7; Inkscape; Python 2.7.2; U; en)
        "User-Agent": "QRCode/3.0 (%s %s; Inkscape; Python %s; U; en)" % (platform.system(), platform.release(), platform.python_version()),
        "Accept":"text/plain"
    }
    
    # Make a request to server to generate a vector QR Code
    con = httplib.HTTPConnection("www.esponce.com")
    query = urllib.urlencode(attribs)
    con.request("GET", "/api/v3/generate?%s" % query, None, headers)
    
    response = con.getresponse()
    if response.status == 200:
        result = response.read()
    else:
        inkex.errormsg(_('Error during the progress. Please check parameters.'))
    con.close()
    return result
Ejemplo n.º 15
0
    def collect_images(self, docname, z):
        '''
        Collects all images in the document
        and copy them to the temporary directory.
        '''
        if locale.getpreferredencoding():
          dir_locale = locale.getpreferredencoding()
        else:
          dir_locale = "UTF-8"
        dir = unicode(self.options.image_dir, dir_locale)
        for node in self.document.xpath('//svg:image', namespaces=inkex.NSS):
            xlink = node.get(inkex.addNS('href',u'xlink'))
            if (xlink[:4] != 'data'):
                absref = node.get(inkex.addNS('absref',u'sodipodi'))
                url = urlparse.urlparse(xlink)
                href = urllib.url2pathname(url.path)
                
                if (href != None):
                    absref = os.path.realpath(href)

                absref = unicode(absref, "utf-8")
                image_path = os.path.join(dir, os.path.basename(absref))
                
                if (os.path.isfile(absref)):
                    shutil.copy(absref, self.tmp_dir)
                    z.write(absref, image_path.encode(self.encoding))
                elif (os.path.isfile(os.path.join(self.tmp_dir, absref))):
                    # TODO: please explain why this clause is necessary
                    shutil.copy(os.path.join(self.tmp_dir, absref), self.tmp_dir)
                    z.write(os.path.join(self.tmp_dir, absref), image_path.encode(self.encoding))
                else:
                    inkex.errormsg(_('Could not locate file: %s') % absref)

                node.set(inkex.addNS('href',u'xlink'), image_path)
    def convertToSegments(cls, path_node):
        path_start = None
        currentPoint = None

        # work on copy to be shure not breaking anything
        path = copy.deepcopy(path_node)

        # apply transformation info on path, otherwise dealing with transform would be a mess
        simpletransform.fuseTransform(path)

        for cmd, params in simplepath.parsePath(path.get('d')):
            print_('cmd, params', cmd, params)
            if cmd == 'M':
                if(path_start is None):
                    path_start = params
                currentPoint = params

            elif cmd == 'L':
                yield Segment(currentPoint, params)
                currentPoint = params

            elif cmd in ['A', 'Q', 'C']:
                yield Segment(currentPoint, params[-2:], command=cmd, extra_parameters=params[:-2])
                currentPoint = params[-2:]

            elif (cmd == 'Z'):
                # Z is a line between the last point and the start of the shape
                yield Segment(currentPoint, path_start)
                currentPoint = None
                path_start = None

            else:
                inkex.errormsg("Path Command %s not managed Yet" % cmd)
Ejemplo n.º 17
0
 def validate_options(self):
     #inkex.errormsg( self.options.input_encode )
     # Convert string names lists in real lists
     m = re.match('\s*(.*[^\s])\s*', self.options.month_names)
     self.options.month_names = re.split('\s+', m.group(1))
     m = re.match('\s*(.*[^\s])\s*', self.options.day_names)
     self.options.day_names = re.split('\s+', m.group(1))
     # Validate names lists
     if len(self.options.month_names) != 12:
         inkex.errormsg('The month name list "' + \
                      str(self.options.month_names) + \
                      '" is invalid. Using default.')
         self.options.month_names = ['January', 'February', 'March',
                                     'April', 'May', 'June',
                                     'July', 'August', 'September',
                                     'October', 'November', 'December']
     if len(self.options.day_names) != 7:
         inkex.errormsg('The day name list "'+
                      str(self.options.day_names)+
                      '" is invalid. Using default.')
         self.options.day_names = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu',
                                   'Fri','Sat']
     # Convert year 0 to current year
     if self.options.year == 0: self.options.year = datetime.today().year
     # Year 1 starts it's week at monday, obligatorily
     if self.options.year == 1: self.options.start_day = 'mon'
     # Set the calendar start day
     if self.options.start_day=='sun':
         calendar.setfirstweekday(6)
     else:
         calendar.setfirstweekday(0)
     # Convert string numbers with unit to user space float numbers
     self.options.month_width  = self.unittouu( self.options.month_width )
     self.options.month_margin = self.unittouu( self.options.month_margin )
Ejemplo n.º 18
0
 def effect(self):
     attr_val = []
     attr_dict = {}
     cmd_scope = None
     if self.options.tab_main == '"tab_basic"':
         cmd_scope = "in_document"
         attr_dict['preserveAspectRatio'] = ("none" if self.options.fix_scaling else "unset")
         attr_dict['image-rendering'] = ("optimizeSpeed" if self.options.fix_rendering else "unset")
     elif self.options.tab_main == '"tab_aspectRatio"':
         attr_val = [self.options.aspect_ratio]
         if self.options.aspect_clip != "unset":
             attr_val.append(self.options.aspect_clip)
         attr_dict['preserveAspectRatio'] = ' '.join(attr_val)
         cmd_scope = self.options.aspect_ratio_scope
     elif self.options.tab_main == '"tab_image_rendering"':
         attr_dict['image-rendering'] = self.options.image_rendering
         cmd_scope = self.options.image_rendering_scope
     else:  # help tab
         pass
     # dispatcher
     if cmd_scope is not None:
         try:
             change_cmd = getattr(self, 'change_{0}'.format(cmd_scope))
             change_cmd(self.selected, attr_dict)
         except AttributeError:
             inkex.errormsg('Scope "{0}" not supported'.format(cmd_scope))
 def effect(self):
     
     scale = self.unittouu('1px')    # convert to document units
     so = self.options
     
     rows = so.ROWS
     cols = so.COLS
     if (so.SYMBOL != '' and (so.SYMBOL in symbols)):
         rows = symbols[so.SYMBOL][0]
         cols = symbols[so.SYMBOL][1]
     
     if so.TEXT == '':  #abort if converting blank text
         inkex.errormsg(_('Please enter an input string'))
     else:
     
         #INKSCAPE GROUP TO CONTAIN EVERYTHING
         
         centre = tuple(computePointInNode(list(self.view_center), self.current_layer))   #Put in in the centre of the current view
         grp_transform = 'translate' + str( centre ) + ' scale(%f)' % scale
         grp_name = 'DataMatrix'
         grp_attribs = {inkex.addNS('label','inkscape'):grp_name,
                        'transform':grp_transform }
         grp = inkex.etree.SubElement(self.current_layer, 'g', grp_attribs)#the group to put everything in
         
         #GENERATE THE DATAMATRIX
         encoded = encode( so.TEXT, (rows, cols) ) #get the pattern of squares
         render_data_matrix( encoded, so.SIZE, cols*so.SIZE*1.5, grp )    # generate the SVG elements
Ejemplo n.º 20
0
    def write_month_header(self, g, m):
        txt_atts = {'style': simplestyle.formatStyle(self.style_month),
                    'x': str((self.month_w - self.day_w) / 2),
                    'y': str(self.day_h / 5 )}
        try:
            inkex.etree.SubElement(g, 'text', txt_atts).text = unicode(
                                                self.options.month_names[m-1],
                                                self.options.input_encode)
        except:
            inkex.errormsg(_('You must select a correct system encoding.'))
            exit(1)
        gw = inkex.etree.SubElement(g, 'g')
        week_x = 0
        if self.options.start_day=='sun':
            day_names = self.options.day_names[:]
        else:
            day_names = self.options.day_names[1:]
            day_names.append(self.options.day_names[0])

        if self.options.show_weeknr:
            day_names.insert(0, self.options.weeknr_name)

        for wday in day_names:
            txt_atts = {'style': simplestyle.formatStyle(self.style_day_name),
                        'x': str( self.day_w * week_x ),
                        'y': str( self.day_h ) }
            try:
                inkex.etree.SubElement(gw, 'text', txt_atts).text = unicode(
                                                    wday,
                                                    self.options.input_encode)
            except:
                inkex.errormsg(_('You must select a correct system encoding.'))
                exit(1)
            week_x += 1
Ejemplo n.º 21
0
	def effect(self):
		# Check version.
		scriptNodes = self.document.xpath("//svg:script[@jessyink:version='1.5.6']", namespaces=inkex.NSS)

		if len(scriptNodes) != 1:
			inkex.errormsg(_(u"JessyInk_c 还未安装到这个SVG文件,或者版本不同. 请使用 “扩展” 菜单下 “JessyInk_c” 的 “安装/升级...” 命令进行JessyInk_c 的安装。\n\n"))

		# Find the script node, if present
		for node in self.document.xpath("//svg:script[@id='JessyInk']", namespaces=inkex.NSS):
			if node.get("{" + inkex.NSS["jessyink"] + "}version"):
				inkex.errormsg(_(u"安装的 JessyInk_c 版本是 {0}。").format(node.get("{" + inkex.NSS["jessyink"] + "}version")))
			else:
				inkex.errormsg(_(u"JessyInk_c 已安装。"))
	
		slides = []
		masterSlide = None 

		for node in self.document.xpath("//svg:g[@inkscape:groupmode='layer']", namespaces=inkex.NSS):
			if node.get("{" + inkex.NSS["jessyink"] + "}masterSlide"):
				masterSlide = node
			else:
				slides.append(node)

		if masterSlide is not None:
			inkex.errormsg(_(u"\n幻灯片母板:"))
			self.describeNode(masterSlide, "\t", u"<幻灯片(层)序号>", str(len(slides)), u"<幻灯片(层)名字>")

		slideCounter = 1

		for slide in slides:
			inkex.errormsg(_(u"\n幻灯片 {0!s}:").format(slideCounter))
			self.describeNode(slide, "\t", str(slideCounter), str(len(slides)), slide.get("{" + inkex.NSS["inkscape"] + "}label"))
			slideCounter += 1
Ejemplo n.º 22
0
	def effect(self):
		# Check version.
		scriptNodes = self.document.xpath("//svg:script[@jessyink:version='1.5.6']", namespaces=inkex.NSS)

		if len(scriptNodes) != 1:
			inkex.errormsg(_("The JessyInk script is not installed in this SVG file or has a different version than the JessyInk extensions. Please select \"install/update...\" from the \"JessyInk\" sub-menu of the \"Extensions\" menu to install or update the JessyInk script.\n\n"))

		if len(self.selected) == 0:
			inkex.errormsg(_("No object selected. Please select the object you want to assign an effect to and then press apply.\n"))

		for id, node in list(self.selected.items()):
			if self.options.effectIn in ("appear", "fade", "pop", "matrix"):
				attribs = { inkex.addNS('href','xlink'): '#'+id }
				clone = inkex.etree.SubElement(self.current_layer, inkex.addNS('use','svg'), attribs)
				clone.set("{" + inkex.NSS["jessyink"] + "}effectIn","name:" + self.options.effectIn  + ";length:" + str(int(self.options.effectInDuration * 1000)))
				# Remove possible view argument.
				if "{" + inkex.NSS["jessyink"] + "}view" in node.attrib:
					del node.attrib["{" + inkex.NSS["jessyink"] + "}view"]
		
			if self.options.effectOut in ("appear", "fade", "pop", "matrix"):
				attribs = { inkex.addNS('href','xlink'): '#'+id }
				clone = inkex.etree.SubElement(self.current_layer, inkex.addNS('use','svg'), attribs)
				clone.set("{" + inkex.NSS["jessyink"] + "}effectOut","name:" + self.options.effectOut  + ";length:" + str(int(self.options.effectOutDuration * 1000)))
				# Remove possible view argument.
				if "{" + inkex.NSS["jessyink"] + "}view" in node.attrib:
					del node.attrib["{" + inkex.NSS["jessyink"] + "}view"]
	def effect(self):
		# Check version.
		scriptNodes = self.document.xpath("//svg:script[@jessyink:version='1.5.5']", namespaces=inkex.NSS)

		if len(scriptNodes) != 1:
			inkex.errormsg(_("The JessyInk script is not installed in this SVG file or has a different version than the JessyInk extensions. Please select \"install/update...\" from the \"JessyInk\" sub-menu of the \"Extensions\" menu to install or update the JessyInk script.\n\n"))

		# Find the script node, if present
		for node in self.document.xpath("//svg:script[@id='JessyInk']", namespaces=inkex.NSS):
			if node.get("{" + inkex.NSS["jessyink"] + "}version"):
				inkex.errormsg(_("JessyInk script version {0} installed.").format(node.get("{" + inkex.NSS["jessyink"] + "}version")))
			else:
				inkex.errormsg(_("JessyInk script installed."))
	
		slides = []
		masterSlide = None 

		for node in self.document.xpath("//svg:g[@inkscape:groupmode='layer']", namespaces=inkex.NSS):
			if node.get("{" + inkex.NSS["jessyink"] + "}masterSlide"):
				masterSlide = node
			else:
				slides.append(node)

		if masterSlide is not None:
			inkex.errormsg(_("\nMaster slide:"))
			self.describeNode(masterSlide, "\t", "<the number of the slide>", str(len(slides)), "<the title of the slide>")

		slideCounter = 1

		for slide in slides:
			inkex.errormsg(_("\nSlide {0!s}:").format(slideCounter))
			self.describeNode(slide, "\t", str(slideCounter), str(len(slides)), slide.get("{" + inkex.NSS["inkscape"] + "}label"))
			slideCounter += 1
Ejemplo n.º 24
0
 def export_img(self, el, conf):
     if not self.has_magick:
         inkex.errormsg(_("You must install the ImageMagick to get JPG and GIF."))
         conf["format"] = "png"
     img_name = os.path.join(self.options.dir, self.img_name(el, conf))
     img_name_png = img_name
     if conf["format"] != "png":
         img_name_png = img_name + ".png"
     opts = ""
     if "bg-color" in conf:
         opts += ' -b "' + conf["bg-color"] + '" -y 1'
     if "dpi" in conf:
         opts += " -d " + conf["dpi"]
     if "dimension" in conf:
         dim = conf["dimension"].split("x")
         opts += " -w " + dim[0] + " -h " + dim[1]
     (status, output) = self.get_cmd_output(
         'inkscape %s -i "%s" -e "%s" "%s"' % (opts, el.attrib["id"], img_name_png, self.tmp_svg)
     )
     if conf["format"] != "png":
         opts = ""
         if conf["format"] == "jpg":
             opts += " -quality " + str(conf["quality"])
         if conf["format"] == "gif":
             if conf["gif-type"] == "grayscale":
                 opts += " -type Grayscale"
             else:
                 opts += " -type Palette"
             if conf["palette-size"] < 256:
                 opts += " -colors " + str(conf["palette-size"])
         (status, output) = self.get_cmd_output('convert "%s" %s "%s"' % (img_name_png, opts, img_name))
         if status != 0:
             inkex.errormsg("Upss... ImageMagick error: " + output)
         os.remove(img_name_png)
Ejemplo n.º 25
0
	def effect(self):
		# Check version.
		scriptNodes = self.document.xpath("//svg:script[@jessyink:version='1.5.6']", namespaces=inkex.NSS)

		if len(scriptNodes) != 1:
			inkex.errormsg(_("The JessyInk script is not installed in this SVG file or has a different version than the JessyInk extensions. Please select \"install/update...\" from the \"JessyInk\" sub-menu of the \"Extensions\" menu to install or update the JessyInk script.\n\n"))

		if len(self.selected) == 0:
			inkex.errormsg(_("No object selected. Please select the object you want to assign an effect to and then press apply.\n"))

		for id, node in list(self.selected.items()):
			attribs = { inkex.addNS('href','xlink'): '#'+id }
			clone = inkex.etree.SubElement(self.current_layer, inkex.addNS('use','svg'), attribs)
			clone.set("{" + inkex.NSS["jessyink"] + "}effectIn","name:animate;length:-1")
			# Remove possible view argument.
			if "{" + inkex.NSS["jessyink"] + "}view" in node.attrib:
				del node.attrib["{" + inkex.NSS["jessyink"] + "}view"]

			# Add the animation
			attribs = {'attributeName':self.options.attribute,
                                'begin':self.options.begin,
                                'dur':str(self.options.duration)+"s",
                                'repeatCount':self.options.repeat,
                                'from':self.options.origin,
                                'to':self.options.to,
                                }
			if (self.options.values):
                            attribs['values'] = self.options.values
			inkex.etree.SubElement(clone, inkex.addNS('animate','svg'), attribs)
Ejemplo n.º 26
0
def format_options(options):
	'''
	Format options dictionary as therion options string.
	'''
	ret = ''
	for key,value in options.items():
		if len(ret) > 0:
			ret += ' '
		for two_arg_key in two_arg_keys:
			if key.startswith(two_arg_key + '-'):
				ret += '-' + key.replace('-', ' ', 1)
				break
		else:
			ret += '-' + key
		if value == True:
			continue
		if not isinstance(value, basestring):
			ret += ' ' + str(value)
		elif len(value) == 0:
			inkex.errormsg('error: empty value: -' + key);
		elif value[0] == '[' or needquote.search(value) is None:
			ret += ' ' + value
		else:
			ret += ' "' + value.replace('"', '\\"') + '"'
	return ret
Ejemplo n.º 27
0
    def effect(self):
        for id, node in self.selected.iteritems():
            if node.tag == inkex.addNS('path','svg'):
                p = cubicsuperpath.parsePath(node.get('d'))
                coords = []
                openPath = False
                for sub in p:
                    if sub[0][0] == sub[-1][2]:                                                
                        p0 = sub[0][1]
                        i = 0
                        while i < len(sub)-1:
                            p1 = sub[i][2]
                            p2 = sub[i+1][0]
                            p3 = sub[i+1][1]
                            bez = (p0, p1, p2, p3)
                            coords.extend(bezlinearize(bez, self.options.num_points))
                            p0 = p3
                            i+=1
                    else:
                        openPath = True
                        inkex.errormsg("Path doesn't appear to be closed")
                        

                if not openPath:
                    c = centroid(coords)
                
                    ## debug linearization
                    # many_lines(coords, self.current_layer)
                    #                
                    draw_SVG_dot(c, self.options.centroid_radius, "centroid-dot", self.current_layer)
    def effect(self):

        if not self.options.path:
            inkex.errormsg('Empty file path!')
            exit()

        for resolution in self.should_export:
            flag = getattr(self.options, resolution)
            if flag.lower() == "true":
                self.should_export[resolution] = True
            else:
                self.should_export[resolution] = False

        # Checks if a path has the correct format
        if "{}" not in self.options.path:
            inkex.errormsg('The path entered does not have a {} inside it. '
                           'Enter a path that has a {} in the place of the '
                           'resolution name. In example, if you put the path '
                           '"folder/example/{}/my_image.png", this extension '
                           'will export images for several paths: '
                           '"folder/example/mdpi/my_image.png", '
                           '"folder/example/xxhdpi/my_image.png"')
            exit()

        # Solves the paths that use "~" as the home directory
        filepath = os.path.expanduser(self.options.path)
        filepath = filepath.replace('{}', '{0}')


        area = self.get_selected_area()
        resolutions = filter(lambda res: self.should_export[res],
                             self.resolution_multipliers.keys())

        self.export_to_resolutions(filepath, area, resolutions)
Ejemplo n.º 29
0
    def effect(self):
        """ Like cut but requires no selection and does no validation for
        text nodes.
        """
        nodes = self.selected
        if not len(nodes):
            inkex.errormsg("There were no paths were selected.")
            return

        document = self.document
        if contains_text(self.selected.values()):
            document = convert_objects_to_paths(self.args[-1], self.document)

        #: If running from source
        if DEBUG:
            python = '~/inkcut/venv/bin/python'
            inkcut = '~/inkcut/main.py'
            cmd = [python, inkcut]
        else:
            cmd = ['inkcut']

        cmd += ['open', '-',
               '--nodes']+[str(k) for k in nodes.keys()]
        p = subprocess.Popen(cmd,
                             stdin=subprocess.PIPE,
                             stdout=DEVNULL,
                             stderr=subprocess.STDOUT,
                             close_fds=sys.platform != "win32")
        p.stdin.write(inkex.etree.tostring(document))
        p.stdin.close()
Ejemplo n.º 30
0
    def effect(self):
        if len(self.options.ids)<2:
            inkex.errormsg(_("This extension requires two selected paths."))
            return
        self.prepareSelectionList()
        self.tolerance=math.pow(10,self.options.space);
                    
        for id, node in self.patterns.iteritems():
            if node.tag == inkex.addNS('path','svg') or node.tag=='path':
                d = node.get('d')
                p0 = cubicsuperpath.parsePath(d)
                origin = p0[0][0][1];

                newp=[]
                for skelnode in self.skeletons.itervalues(): 
                    self.curSekeleton=cubicsuperpath.parsePath(skelnode.get('d'))
                    for comp in self.curSekeleton:
                        self.skelcomp=linearize(comp,self.tolerance)
                        for comp in self.skelcomp:
                            p=copy.deepcopy(p0)
                            for sub in p:
                                xoffset=comp[0]-origin[0]+self.options.xoffset
                                yoffset=comp[1]-origin[1]+self.options.yoffset
                                offset(sub,xoffset,yoffset)
                            newp+=p

                node.set('d', cubicsuperpath.formatPath(newp))
Ejemplo n.º 31
0
 def showDebugInfo(self, debugObject):
     # show debug information
     inkex.errormsg(
         "---------------------------------\nDebug information\n---------------------------------\n\nSettings:\n"
     )
     inkex.errormsg('  Serial Port: ' + str(self.options.serialPort))
     inkex.errormsg('  Serial baud rate: ' +
                    str(self.options.serialBaudRate))
     inkex.errormsg('  Flow control: ' + str(self.options.flowControl))
     inkex.errormsg('  Command language: ' +
                    str(self.options.commandLanguage))
     inkex.errormsg('  Resolution X (dpi): ' +
                    str(self.options.resolutionX))
     inkex.errormsg('  Resolution Y (dpi): ' +
                    str(self.options.resolutionY))
     inkex.errormsg('  Pen number: ' + str(self.options.pen))
     inkex.errormsg('  Pen force (g): ' + str(self.options.force))
     inkex.errormsg('  Pen speed (cm/s): ' + str(self.options.speed))
     inkex.errormsg('  Rotation (Clockwise): ' +
                    str(self.options.orientation))
     inkex.errormsg('  Mirror X axis: ' + str(self.options.mirrorX))
     inkex.errormsg('  Mirror Y axis: ' + str(self.options.mirrorY))
     inkex.errormsg('  Center zero point: ' + str(self.options.center))
     inkex.errormsg('  Overcut (mm): ' + str(self.options.overcut))
     inkex.errormsg('  Tool offset (mm): ' + str(self.options.toolOffset))
     inkex.errormsg('  Use precut: ' + str(self.options.precut))
     inkex.errormsg('  Curve flatness: ' + str(self.options.flat))
     inkex.errormsg('  Auto align: ' + str(self.options.autoAlign))
     inkex.errormsg('  Show debug information: ' + str(self.options.debug))
     inkex.errormsg("\nDocument properties:\n")
     version = self.document.getroot().xpath('//@inkscape:version',
                                             namespaces=inkex.NSS)
     if version:
         inkex.errormsg('  Inkscape version: ' + version[0])
     fileName = self.document.getroot().xpath('//@sodipodi:docname',
                                              namespaces=inkex.NSS)
     if fileName:
         inkex.errormsg('  Filename: ' + fileName[0])
     inkex.errormsg('  Document unit: ' + self.getDocumentUnit())
     inkex.errormsg('  Width: ' + str(debugObject.debugValues['docWidth']) +
                    ' ' + self.getDocumentUnit())
     inkex.errormsg('  Height: ' +
                    str(debugObject.debugValues['docHeight']) + ' ' +
                    self.getDocumentUnit())
     if debugObject.debugValues['viewBoxWidth'] == "-":
         inkex.errormsg('  Viewbox Width: -')
         inkex.errormsg('  Viewbox Height: -')
     else:
         inkex.errormsg('  Viewbox Width: ' + str(
             self.unittouu(
                 self.addDocumentUnit(
                     debugObject.debugValues['viewBoxWidth']))) + ' ' +
                        self.getDocumentUnit())
         inkex.errormsg('  Viewbox Height: ' + str(
             self.unittouu(
                 self.addDocumentUnit(
                     debugObject.debugValues['viewBoxHeight']))) + ' ' +
                        self.getDocumentUnit())
     inkex.errormsg("\n" + self.options.commandLanguage + " properties:\n")
     inkex.errormsg('  Drawing width: ' + str(
         self.unittouu(
             self.addDocumentUnit(
                 str(debugObject.debugValues['drawingWidthUU'])))) + ' ' +
                    self.getDocumentUnit())
     inkex.errormsg('  Drawing height: ' + str(
         self.unittouu(
             self.addDocumentUnit(
                 str(debugObject.debugValues['drawingHeightUU'])))) + ' ' +
                    self.getDocumentUnit())
     inkex.errormsg('  Drawing width: ' +
                    str(debugObject.debugValues['drawingWidth']) +
                    ' plotter steps')
     inkex.errormsg('  Drawing height: ' +
                    str(debugObject.debugValues['drawingHeight']) +
                    ' plotter steps')
     inkex.errormsg('  Offset X: ' + str(debugObject.offsetX) +
                    ' plotter steps')
     inkex.errormsg('  Offset Y: ' + str(debugObject.offsetX) +
                    ' plotter steps')
     inkex.errormsg('  Overcut: ' + str(debugObject.overcut) +
                    ' plotter steps')
     inkex.errormsg('  Tool offset: ' + str(debugObject.toolOffset) +
                    ' plotter steps')
     inkex.errormsg('  Flatness: ' + str(debugObject.flat) +
                    ' plotter steps')
     inkex.errormsg('  Tool offset flatness: ' +
                    str(debugObject.toolOffsetFlat) + ' plotter steps')
     inkex.errormsg("\n" + self.options.commandLanguage + " data:\n")
     inkex.errormsg(self.hpgl)
Ejemplo n.º 32
0
    def recursivelyTraverseSvg(self,
                               nodeList,
                               matCurrent=[[1.0, 0.0, 0.0], [0.0, -1.0, 0.0]],
                               parent_visibility='visible'):
        """
    Recursively traverse the svg file to plot out all of the
    paths.  The function keeps track of the composite transformation
    that should be applied to each path.

    This function handles path, group, line, rect, polyline, polygon,
    circle, ellipse and use (clone) elements. Notable elements not
    handled include text.  Unhandled elements should be converted to
    paths in Inkscape.

    TODO: There's a lot of inlined code in the eggbot version of this
    that would benefit from the Entities method of dealing with things.
    """
        for node in nodeList:
            # Ignore invisible nodes
            v = node.get('visibility', parent_visibility)
            if v == 'inherit':
                v = parent_visibility
            if v == 'hidden' or v == 'collapse':
                pass

            # first apply the current matrix transform to this node's transform
            matNew = composeTransform(matCurrent,
                                      parseTransform(node.get("transform")))

            if node.tag == inkex.addNS('g', 'svg') or node.tag == 'g':
                if (node.get(inkex.addNS('groupmode', 'inkscape')) == 'layer'):
                    layer_name = node.get(inkex.addNS('label', 'inkscape'))

                self.recursivelyTraverseSvg(node, matNew, parent_visibility=v)
            elif node.tag == inkex.addNS('use', 'svg') or node.tag == 'use':
                refid = node.get(inkex.addNS('href', 'xlink'))
                if refid:
                    # [1:] to ignore leading '#' in reference
                    path = '//*[@id="%s"]' % refid[1:]
                    refnode = node.xpath(path)
                    if refnode:
                        x = float(node.get('x', '0'))
                        y = float(node.get('y', '0'))
                        # Note: the transform has already been applied
                        if (x != 0) or (y != 0):
                            matNew2 = composeTransform(
                                matNew,
                                parseTransform('translate(%f,%f)' % (x, y)))
                        else:
                            matNew2 = matNew
                        v = node.get('visibility', v)
                        self.recursivelyTraverseSvg(refnode,
                                                    matNew2,
                                                    parent_visibility=v)
                    else:
                        pass
                else:
                    pass
            elif not isinstance(node.tag, basestring):
                pass
            else:
                entity = self.make_entity(node, matNew)
                if entity == None:
                    inkex.errormsg(
                        'Warning: unable to draw object, please convert it to a path first.'
                    )
Ejemplo n.º 33
0
 def load(self, node, mat):
     inkex.errormsg(
         'Warning: unable to draw text. please convert it to a path first.')
     SvgIgnoredEntity.load(self, node, mat)
Ejemplo n.º 34
0
    def effect(self):
        if len(self.options.ids)<2:
            inkex.errormsg(_("This extension requires two selected paths."))
            return
        self.prepareSelectionList()
        self.options.wave = (self.options.kind=="Ribbon")
        if self.options.copymode=="Single":
            self.options.repeat =False
            self.options.stretch=False
        elif self.options.copymode=="Repeated":
            self.options.repeat =True
            self.options.stretch=False
        elif self.options.copymode=="Single, stretched":
            self.options.repeat =False
            self.options.stretch=True
        elif self.options.copymode=="Repeated, stretched":
            self.options.repeat =True
            self.options.stretch=True

        bbox=simpletransform.computeBBox(self.patterns.values())
                    
        if self.options.vertical:
            #flipxy(bbox)...
            bbox=(-bbox[3],-bbox[2],-bbox[1],-bbox[0])

        width=bbox[1]-bbox[0]
        dx=width+self.options.space
        if dx < 0.01:
            exit(_("The total length of the pattern is too small :\nPlease choose a larger object or set 'Space between copies' > 0"))

        for id, node in self.patterns.iteritems():
            if node.tag == inkex.addNS('path','svg') or node.tag=='path':
                d = node.get('d')
                p0 = cubicsuperpath.parsePath(d)
                if self.options.vertical:
                    flipxy(p0)

                newp=[]
                for skelnode in self.skeletons.itervalues(): 
                    self.curSekeleton=cubicsuperpath.parsePath(skelnode.get('d'))
                    if self.options.vertical:
                        flipxy(self.curSekeleton)
                    for comp in self.curSekeleton:
                        p=copy.deepcopy(p0)
                        self.skelcomp,self.lengths=linearize(comp)
                        #!!!!>----> TODO: really test if path is closed! end point==start point is not enough!
                        self.skelcompIsClosed = (self.skelcomp[0]==self.skelcomp[-1])

                        length=sum(self.lengths)
                        xoffset=self.skelcomp[0][0]-bbox[0]+self.options.toffset
                        yoffset=self.skelcomp[0][1]-(bbox[2]+bbox[3])/2-self.options.noffset


                        if self.options.repeat:
                            NbCopies=max(1,int(round((length+self.options.space)/dx)))
                            width=dx*NbCopies
                            if not self.skelcompIsClosed:
                                width-=self.options.space
                            bbox=bbox[0],bbox[0]+width, bbox[2],bbox[3]
                            new=[]
                            for sub in p:
                                for i in range(0,NbCopies,1):
                                    new.append(copy.deepcopy(sub))
                                    offset(sub,dx,0)
                            p=new

                        for sub in p:
                            offset(sub,xoffset,yoffset)

                        if self.options.stretch:
                            if not width:
                                exit(_("The 'stretch' option requires that the pattern must have non-zero width :\nPlease edit the pattern width."))
                            for sub in p:
                                stretch(sub,length/width,1,self.skelcomp[0])

                        for sub in p:
                            for ctlpt in sub:
                                self.applyDiffeo(ctlpt[1],(ctlpt[0],ctlpt[2]))

                        if self.options.vertical:
                            flipxy(p)
                        newp+=p

                node.set('d', cubicsuperpath.formatPath(newp))
Ejemplo n.º 35
0
    def effect(self):

        # Get script's options values.

        # Factor to multiply in order to get user units (pixels)
        factor = self.unittouu('1' + self.options.unit)

        # document or selection
        target = self.options.target

        # boolean
        same_margins = self.options.same_margins

        # convert string to integer, in user units (pixels)
        top_margin = float(self.options.top_margin) * factor
        right_margin = float(self.options.right_margin) * factor
        bottom_margin = float(self.options.bottom_margin) * factor
        left_margin = float(self.options.left_margin) * factor

        # getting parent tag of the guides
        namedview = self.document.xpath(
            '/svg:svg/sodipodi:namedview', namespaces=inkex.NSS)[0]

        # getting the main SVG document element (canvas)
        svg = self.document.getroot()

        # if same margins, set them all to same value
        if same_margins:
            right_margin = top_margin
            bottom_margin = top_margin
            left_margin = top_margin

        # getting the width and height attributes of the canvas
        canvas_width = self.unittouu(svg.get('width'))
        canvas_height = self.unittouu(svg.get('height'))

        # If selection, draw around selection. Otherwise use document.
        if (target == "selection"):

            # If there is no selection, quit with message
            if not self.options.ids:
                inkex.errormsg(_("Please select an object first"))
                exit()

            # get bounding box
            obj_x1, obj_x2, obj_y1, obj_y2 = simpletransform.computeBBox([self.getElementById(id) for id in self.options.ids])

            # start position of guides
            top_pos = canvas_height - obj_y1 - top_margin
            right_pos = obj_x2 - right_margin
            bottom_pos = canvas_height - obj_y2 + bottom_margin
            left_pos = obj_x1 + left_margin

            # Draw the four margin guides
            # TODO: only draw if not on border
            guidetools.drawGuide(top_pos, "horizontal", namedview)
            guidetools.drawGuide(right_pos, "vertical", namedview)
            guidetools.drawGuide(bottom_pos, "horizontal", namedview)
            guidetools.drawGuide(left_pos, "vertical", namedview)

        else:

            # draw margin guides (if not zero)
            if same_margins:
                right_margin = top_margin
                bottom_margin = top_margin
                left_margin = top_margin

            # start position of guides
            top_pos = canvas_height - top_margin
            right_pos = canvas_width - right_margin
            bottom_pos = bottom_margin
            left_pos = left_margin

            # Draw the four margin guides (if margin exists)
            if top_pos != canvas_height:
                guidetools.drawGuide(top_pos, "horizontal", namedview)
            if right_pos != canvas_width:
                guidetools.drawGuide(right_pos, "vertical", namedview)
            if bottom_pos != 0:
                guidetools.drawGuide(bottom_pos, "horizontal", namedview)
            if left_pos != 0:
                guidetools.drawGuide(left_pos, "vertical", namedview)
Ejemplo n.º 36
0
                'fill': 'none'
            })
            w = 0.5  # default lineweight for POINT
            if vals[groups['370']]:  # Common Lineweight
                if vals[groups['370']][0] > 0:
                    w = 96.0 / 25.4 * vals[groups['370']][0] / 100.0
                    if w < 0.5:
                        w = 0.5
                    style = simplestyle.formatStyle({
                        'stroke': '%s' % color,
                        'fill': 'none',
                        'stroke-width': '%.1f' % w
                    })
            if vals[groups['6']]:  # Common Linetype
                if linetypes.has_key(vals[groups['6']][0]):
                    style += ';' + linetypes[vals[groups['6']][0]]
            if entities[entity]:
                entities[entity]()
        entity = line[1]
        vals = [[], [], [], [], [], [], [], [], [], [], [], [], [], [], [], [],
                [], [], [], [], [], [], [], [], []]
        seqs = []

if polylines:
    inkex.errormsg(
        _('%d ENTITIES of type POLYLINE encountered and ignored. Please try to convert to Release 13 format using QCad.'
          ) % polylines)
doc.write(inkex.sys.stdout)

# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 fileencoding=utf-8 textwidth=99
Ejemplo n.º 37
0
    def effect(self):
        # version check if enabled in options
        if (self.options.scour_version_warn_old):
            scour_version = scour.__version__
            scour_version_min = self.options.scour_version
            if (StrictVersion(scour_version) < StrictVersion(scour_version_min)):
                inkex.errormsg("The extension 'Optimized SVG Output' is designed for Scour " + scour_version_min + " and later "
                               "but you're using the older version Scour " + scour_version + ".")
                inkex.errormsg("This usually works just fine but not all options available in the UI might be supported "
                               "by the version of Scour installed on your system "
                               "(see https://github.com/scour-project/scour/blob/master/HISTORY.md for release notes of Scour).")
                inkex.errormsg("Note: You can permanently disable this message on the 'About' tab of the extension window.")
        del self.options.scour_version
        del self.options.scour_version_warn_old

        # do the scouring
        try:
            input = file(self.args[0], "r")
            self.options.infilename = self.args[0]
            sys.stdout.write(scourString(input.read(), self.options).encode("UTF-8"))
            input.close()
            sys.stdout.close()
        except Exception as e:
            inkex.errormsg("Error during optimization.")
            inkex.errormsg("\nDetails:\n" + str(e))
            inkex.errormsg("\nOS version: " + platform.platform())
            inkex.errormsg("Python version: " + sys.version)
            inkex.errormsg("Scour version: " + scour.__version__)
            sys.exit()
Ejemplo n.º 38
0
    def effect(self):

        # Viewbox handling
        self.handleViewBox()

        # First traverse the document (or selected items), reducing
        # everything to line segments.  If working on a selection,
        # then determine the selection's bounding box in the process.
        # (Actually, we just need to know it's extrema on the x-axis.)

        if self.options.ids:
            # Traverse the selected objects
            for id in self.options.ids:
                transform = self.recursivelyGetEnclosingTransform(
                    self.selected[id])
                self.recursivelyTraverseSvg([self.selected[id]], transform)
        else:
            # Traverse the entire document building new, transformed paths
            self.recursivelyTraverseSvg(
                self.document.getroot(), self.docTransform)

        # Determine the center of the drawing's bounding box
        self.cx = self.xmin + (self.xmax - self.xmin) / 2.0
        self.cy = self.ymin + (self.ymax - self.ymin) / 2.0

        # Determine which polygons lie entirely within other polygons
        try:
            full_fname = os.path.expanduser(self.options.fname)
            if '/' != os.sep:
                full_fname = full_fname.replace('/', os.sep)
            self.f = open(full_fname, 'w')

            self.f.write('''
// Module names are of the form poly_<inkscape-path-id>().  As a result,
// you can associate a polygon in this OpenSCAD program with the corresponding
// SVG element in the Inkscape document by looking for the XML element with
// the attribute id=\"inkscape-path-id\".

// fudge value is used to ensure that subtracted solids are a tad taller
// in the z dimension than the polygon being subtracted from.  This helps
// keep the resulting .stl file manifold.
fudge = 0.1;
''')

            for key in self.paths:
                self.f.write('\n')
                self.convertPath(key)

            # Come up with a name for the module based on the file name.
            name = os.path.splitext(os.path.basename(self.options.fname))[0]
            # Remove all punctuation except underscore.
            name = re.sub(
                '[' + string.punctuation.replace('_', '') + ']', '', name)

            self.f.write('\nmodule %s(h)\n{\n' % name)

            # Now output the list of modules to call
            self.f.write('\n')
            for call in self.call_list:
                self.f.write(call)

            # The module that calls all the other ones.
            self.f.write('}\n\n%s(%s);\n' % (name, self.options.height))
            self.f.close()

        except:
            inkex.errormsg('Unable to write file ' + self.options.fname)

        if self.options.scad2stl == 'true' or self.options.stlpost == 'true':
            stl_fname = re.sub(r"\.SCAD", "", full_fname, flags=re.I) + '.stl'
            cmd = self.options.scad2stlcmd.format(
                **{'SCAD': full_fname, 'STL': stl_fname})
            try:
                os.unlink(stl_fname)
            except:
                pass

            import subprocess
            try:
                proc = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
                                        stdout=subprocess.PIPE,
                                        stderr=subprocess.PIPE)
            except OSError as e:
                raise OSError("{0} failed: errno={1} {2}".format(
                              cmd, e.errno, e.strerror))
            stdout, stderr = proc.communicate()

            len = -1
            try:
                len = os.path.getsize(stl_fname)
            except:
                pass
            if len < 1000:
                print >> sys.stderr, "CMD: {0}".format(cmd)
                # pep8 enforced 80 columns limit is here: --------------------v
                print >> sys.stderr, "WARNING: {0} is very small: {1} bytes.".\
                    format(stl_fname, len)
                print >> sys.stderr, "= " * 24
                print >> sys.stderr, "STDOUT:\n", stdout, "= " * 24
                print >> sys.stderr, "STDERR:\n", stderr, "= " * 24
                if len <= 0:  # something is wrong. better stop here
                    self.options.stlpost = 'false'

            if self.options.stlpost == 'true':
                cmd = self.options.stlpostcmd.format(**{'STL': stl_fname})
                try:
                    tty = open("/dev/tty", "w")
                except:
                    tty = subprocess.PIPE

                try:
                    proc = subprocess.Popen(cmd, shell=True,
                                            stdin=tty, stdout=tty, stderr=tty)
                except OSError as e:
                    raise OSError("%s failed: errno=%d %s" %
                                  (cmd, e.errno, e.strerror))

                stdout, stderr = proc.communicate()
                if stdout or stderr:
                    print >> sys.stderr, "CMD: ", cmd, "\n", "= " * 24
                if stdout:
                    print >> sys.stderr, "STDOUT:\n", stdout, "= " * 24
                if stderr:
                    print >> sys.stderr, "STDERR:\n", stderr, "= " * 24
Ejemplo n.º 39
0
    def recursivelyTraverseSvg(self, aNodeList,
                               matCurrent=[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]],
                               parent_visibility='visible'):

        '''
        [ This too is largely lifted from eggbot.py ]

        Recursively walk the SVG document, building polygon vertex lists
        for each graphical element we support.

        Rendered SVG elements:
            <circle>, <ellipse>, <line>, <path>, <polygon>, <polyline>, <rect>

        Supported SVG elements:
            <group>, <use>

        Ignored SVG elements:
            <defs>, <eggbot>, <metadata>, <namedview>, <pattern>,
            processing directives

        All other SVG elements trigger an error (including <text>)
        '''

        for node in aNodeList:

            # Ignore invisible nodes
            v = node.get('visibility', parent_visibility)
            if v == 'inherit':
                v = parent_visibility
            if v == 'hidden' or v == 'collapse':
                pass

            # First apply the current matrix transform to this node's tranform
            matNew = simpletransform.composeTransform(
                matCurrent,
                simpletransform.parseTransform(node.get("transform")))

            if node.tag == inkex.addNS('g', 'svg') or node.tag == 'g':

                self.recursivelyTraverseSvg(node, matNew, v)

            elif node.tag == inkex.addNS('use', 'svg') or node.tag == 'use':

                # A <use> element refers to another SVG element via an
                # xlink:href="#blah" attribute.  We will handle the element by
                # doing an XPath search through the document, looking for the
                # element with the matching id="blah" attribute.  We then
                # recursively process that element after applying any necessary
                # (x,y) translation.
                #
                # Notes:
                #  1. We ignore the height and width attributes as they do not
                #     apply to path-like elements, and
                #  2. Even if the use element has visibility="hidden", SVG
                #     still calls for processing the referenced element.  The
                #     referenced element is hidden only if its visibility is
                #     "inherit" or "hidden".

                refid = node.get(inkex.addNS('href', 'xlink'))
                if not refid:
                    pass

                # [1:] to ignore leading '#' in reference
                path = '//*[@id="%s"]' % refid[1:]
                refnode = node.xpath(path)
                if refnode:
                    x = float(node.get('x', '0'))
                    y = float(node.get('y', '0'))
                    # Note: the transform has already been applied
                    if (x != 0) or (y != 0):
                        matNew2 = composeTransform(
                            matNew,
                            parseTransform('translate(%f,%f)' % (x, y)))
                    else:
                        matNew2 = matNew
                    v = node.get('visibility', v)
                    self.recursivelyTraverseSvg(refnode, matNew2, v)

            elif node.tag == inkex.addNS('path', 'svg'):

                path_data = node.get('d')
                if path_data:
                    self.getPathVertices(path_data, node, matNew)

            elif node.tag == inkex.addNS('rect', 'svg') or node.tag == 'rect':

                # Manually transform
                #
                #    <rect x="X" y="Y" width="W" height="H"/>
                #
                # into
                #
                #    <path d="MX,Y lW,0 l0,H l-W,0 z"/>
                #
                # I.e., explicitly draw three sides of the rectangle and the
                # fourth side implicitly

                # Create a path with the outline of the rectangle
                x = float(node.get('x'))
                y = float(node.get('y'))
                if (not x) or (not y):
                    pass
                w = float(node.get('width', '0'))
                h = float(node.get('height', '0'))
                a = []
                a.append(['M ', [x, y]])
                a.append([' l ', [w, 0]])
                a.append([' l ', [0, h]])
                a.append([' l ', [-w, 0]])
                a.append([' Z', []])
                self.getPathVertices(simplepath.formatPath(a), node, matNew)

            elif node.tag == inkex.addNS('line', 'svg') or node.tag == 'line':

                # Convert
                #
                #   <line x1="X1" y1="Y1" x2="X2" y2="Y2/>
                #
                # to
                #
                #   <path d="MX1,Y1 LX2,Y2"/>

                x1 = float(node.get('x1'))
                y1 = float(node.get('y1'))
                x2 = float(node.get('x2'))
                y2 = float(node.get('y2'))
                if (not x1) or (not y1) or (not x2) or (not y2):
                    pass
                a = []
                a.append(['M ', [x1, y1]])
                a.append([' L ', [x2, y2]])
                self.getPathVertices(simplepath.formatPath(a), node, matNew)

            elif node.tag == inkex.addNS('polyline', 'svg') or \
                    node.tag == 'polyline':

                # Convert
                #
                #  <polyline points="x1,y1 x2,y2 x3,y3 [...]"/>
                #
                # to
                #
                #   <path d="Mx1,y1 Lx2,y2 Lx3,y3 [...]"/>
                #
                # Note: we ignore polylines with no points

                pl = node.get('points', '').strip()
                if pl == '':
                    pass

                pa = pl.split()
                d = "".join(
                    ["M " + pa[i] if i == 0 else " L " + pa[i] for i in range(
                        0, len(pa))])
                self.getPathVertices(d, node, matNew)

            elif node.tag == inkex.addNS('polygon', 'svg') or \
                    node.tag == 'polygon':

                # Convert
                #
                #  <polygon points="x1,y1 x2,y2 x3,y3 [...]"/>
                #
                # to
                #
                #   <path d="Mx1,y1 Lx2,y2 Lx3,y3 [...] Z"/>
                #
                # Note: we ignore polygons with no points

                pl = node.get('points', '').strip()
                if pl == '':
                    pass

                pa = pl.split()
                d = "".join(
                    ["M " + pa[i] if i == 0 else " L " + pa[i] for i in range(
                        0, len(pa))])
                d += " Z"
                self.getPathVertices(d, node, matNew)

            elif node.tag == inkex.addNS('ellipse', 'svg') or \
                    node.tag == 'ellipse' or \
                    node.tag == inkex.addNS('circle', 'svg') or \
                    node.tag == 'circle':

                # Convert circles and ellipses to a path with two 180 degree
                # arcs. In general (an ellipse), we convert
                #
                #   <ellipse rx="RX" ry="RY" cx="X" cy="Y"/>
                #
                # to
                #
                #   <path d="MX1,CY A RX,RY 0 1 0 X2,CY A RX,RY 0 1 0 X1,CY"/>
                #
                # where
                #
                #   X1 = CX - RX
                #   X2 = CX + RX
                #
                # Note: ellipses or circles with a radius attribute of value 0
                # are ignored

                if node.tag == inkex.addNS('ellipse', 'svg') or \
                        node.tag == 'ellipse':
                    rx = float(node.get('rx', '0'))
                    ry = float(node.get('ry', '0'))
                else:
                    rx = float(node.get('r', '0'))
                    ry = rx
                if rx == 0 or ry == 0:
                    pass

                cx = float(node.get('cx', '0'))
                cy = float(node.get('cy', '0'))
                x1 = cx - rx
                x2 = cx + rx
                d = 'M %f,%f ' % (x1, cy) + \
                    'A %f,%f ' % (rx, ry) + \
                    '0 1 0 %f,%f ' % (x2, cy) + \
                    'A %f,%f ' % (rx, ry) + \
                    '0 1 0 %f,%f' % (x1, cy)
                self.getPathVertices(d, node, matNew)

            elif node.tag == inkex.addNS('pattern', 'svg') or \
                    node.tag == 'pattern':

                pass

            elif node.tag == inkex.addNS('metadata', 'svg') or \
                    node.tag == 'metadata':

                pass

            elif node.tag == inkex.addNS('defs', 'svg') or node.tag == 'defs':

                pass

            elif node.tag == inkex.addNS('desc', 'svg') or node.tag == 'desc':

                pass

            elif node.tag == inkex.addNS('namedview', 'sodipodi') or \
                    node.tag == 'namedview':

                pass

            elif node.tag == inkex.addNS('eggbot', 'svg') or \
                    node.tag == 'eggbot':

                pass

            elif node.tag == inkex.addNS('text', 'svg') or node.tag == 'text':

                inkex.errormsg(
                    'Warning: unable to draw text, '
                    'please convert it to a path first.')

                pass

            elif node.tag == inkex.addNS('title', 'svg') or \
                    node.tag == 'title':

                pass

            elif node.tag == inkex.addNS('image', 'svg') or \
                    node.tag == 'image':

                if 'image' not in self.warnings:
                    inkex.errormsg(
                        gettext.gettext(
                            'Warning: unable to draw bitmap images; '
                            'please convert them to line art first.  '
                            'Consider using the "Trace bitmap..." '
                            'tool of the "Path" menu.  Mac users please '
                            'note that some X11 settings may '
                            'cause cut-and-paste operations to paste in '
                            'bitmap copies.'))
                    self.warnings['image'] = 1
                pass

            elif node.tag == inkex.addNS('pattern', 'svg') or \
                    node.tag == 'pattern':

                pass

            elif node.tag == inkex.addNS('radialGradient', 'svg') or \
                    node.tag == 'radialGradient':

                # Similar to pattern
                pass

            elif node.tag == inkex.addNS('linearGradient', 'svg') or \
                    node.tag == 'linearGradient':

                # Similar in pattern
                pass

            elif node.tag == inkex.addNS('style', 'svg') or \
                    node.tag == 'style':

                # This is a reference to an external style sheet and not the
                # value of a style attribute to be inherited by child elements
                pass

            elif node.tag == inkex.addNS('cursor', 'svg') or \
                    node.tag == 'cursor':

                pass

            elif node.tag == inkex.addNS('color-profile', 'svg') or \
                    node.tag == 'color-profile':

                # Gamma curves, color temp, etc. are not relevant to single
                # color output
                pass

            elif not isinstance(node.tag, basestring):

                # This is likely an XML processing instruction such as an XML
                # comment.  lxml uses a function reference for such node tags
                # and as such the node tag is likely not a printable string.
                # Further, converting it to a printable string likely won't
                # be very useful.

                pass

            else:

                inkex.errormsg(
                    'Warning: unable to draw object <%s>, '
                    'please convert it to a path first.' % node.tag)
                pass
Ejemplo n.º 40
0
    else:
        p = Popen('uniconv', shell=True, stdout=PIPE, stderr=PIPE).wait()
        if p == 0:
            cmd = 'uniconv'
except ImportError:
    from popen2 import Popen3
    p = Popen3('uniconv', True).wait()
    if p != 32512: cmd = 'uniconv'
    p = Popen3('uniconvertor', True).wait()
    if p != 32512: cmd = 'uniconvertor'

if cmd == None:
    # there's no succeffully-returning uniconv command; try to get the module directly (on Windows)
    try:
        # cannot simply import uniconvertor, it aborts if you import it without parameters
        import imp
        imp.find_module("uniconvertor")
    except ImportError:
        inkex.localize()
        inkex.errormsg(_('You need to install the UniConvertor software.\n'+\
                     'For GNU/Linux: install the package python-uniconvertor.\n'+\
                     'For Windows: download it from\n'+\
                     'https://sk1project.net/modules.php?name=Products&product=uniconvertor&op=download\n'+\
                     'and install into your Inkscape\'s Python location\n'))
        sys.exit(1)
    cmd = 'python -c "import uniconvertor; uniconvertor.uniconv_run()"'

run((cmd + ' "%s" "%%s"') % sys.argv[1].replace("%", "%%"), "UniConvertor")

# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 fileencoding=utf-8 textwidth=99
    def effect(self):
        if not self.options.ids:
            inkex.errormsg(_("Please select an object"))
            exit()
        scale = self.unittouu('1px')  # convert to document units
        self.options.size *= scale
        self.options.border *= scale
        q = {
            'x': 0,
            'y': 0,
            'width': 0,
            'height': 0
        }  # query the bounding box of ids[0]
        for query in q.keys():
            p = Popen('inkscape --query-%s --query-id=%s "%s"' %
                      (query, self.options.ids[0], self.args[-1]),
                      shell=True,
                      stdout=PIPE,
                      stderr=PIPE)
            rc = p.wait()
            q[query] = scale * float(p.stdout.read())
        mat = simpletransform.composeParents(
            self.selected[self.options.ids[0]],
            [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
        defs = self.xpathSingle('/svg:svg//svg:defs')
        pattern = inkex.etree.SubElement(defs, inkex.addNS('pattern', 'svg'))
        pattern.set('id', 'Voronoi' + str(random.randint(1, 9999)))
        pattern.set('width', str(q['width']))
        pattern.set('height', str(q['height']))
        pattern.set(
            'patternTransform',
            'translate(%s,%s)' % (q['x'] - mat[0][2], q['y'] - mat[1][2]))
        pattern.set('patternUnits', 'userSpaceOnUse')

        # generate random pattern of points
        c = voronoi.Context()
        pts = []
        b = float(self.options.border)  # width of border
        for i in range(
                int(q['width'] * q['height'] / self.options.size /
                    self.options.size)):
            x = random.random() * q['width']
            y = random.random() * q['height']
            if b > 0:  # duplicate border area
                pts.append(voronoi.Site(x, y))
                if x < b:
                    pts.append(voronoi.Site(x + q['width'], y))
                    if y < b:
                        pts.append(
                            voronoi.Site(x + q['width'], y + q['height']))
                    if y > q['height'] - b:
                        pts.append(
                            voronoi.Site(x + q['width'], y - q['height']))
                if x > q['width'] - b:
                    pts.append(voronoi.Site(x - q['width'], y))
                    if y < b:
                        pts.append(
                            voronoi.Site(x - q['width'], y + q['height']))
                    if y > q['height'] - b:
                        pts.append(
                            voronoi.Site(x - q['width'], y - q['height']))
                if y < b:
                    pts.append(voronoi.Site(x, y + q['height']))
                if y > q['height'] - b:
                    pts.append(voronoi.Site(x, y - q['height']))
            elif x > -b and y > -b and x < q['width'] + b and y < q[
                    'height'] + b:
                pts.append(voronoi.Site(x, y))  # leave border area blank
            # dot = inkex.etree.SubElement(pattern, inkex.addNS('rect','svg'))
            # dot.set('x', str(x-1))
            # dot.set('y', str(y-1))
            # dot.set('width', '2')
            # dot.set('height', '2')
        if len(pts) < 3:
            inkex.errormsg(
                "Please choose a larger object, or smaller cell size")
            exit()

        # plot Voronoi diagram
        sl = voronoi.SiteList(pts)
        voronoi.voronoi(sl, c)
        path = ""
        for edge in c.edges:
            if edge[1] >= 0 and edge[2] >= 0:  # two vertices
                [x1, y1, x2, y2
                 ] = clip_line(c.vertices[edge[1]][0], c.vertices[edge[1]][1],
                               c.vertices[edge[2]][0], c.vertices[edge[2]][1],
                               q['width'], q['height'])
            elif edge[1] >= 0:  # only one vertex
                if c.lines[edge[0]][1] == 0:  # vertical line
                    xtemp = c.lines[edge[0]][2] / c.lines[edge[0]][0]
                    if c.vertices[edge[1]][1] > q['height'] / 2:
                        ytemp = q['height']
                    else:
                        ytemp = 0
                else:
                    xtemp = q['width']
                    ytemp = (c.lines[edge[0]][2] - q['width'] *
                             c.lines[edge[0]][0]) / c.lines[edge[0]][1]
                [x1, y1, x2, y2] = clip_line(c.vertices[edge[1]][0],
                                             c.vertices[edge[1]][1], xtemp,
                                             ytemp, q['width'], q['height'])
            elif edge[2] >= 0:  # only one vertex
                if c.lines[edge[0]][1] == 0:  # vertical line
                    xtemp = c.lines[edge[0]][2] / c.lines[edge[0]][0]
                    if c.vertices[edge[2]][1] > q['height'] / 2:
                        ytemp = q['height']
                    else:
                        ytemp = 0
                else:
                    xtemp = 0
                    ytemp = c.lines[edge[0]][2] / c.lines[edge[0]][1]
                [x1, y1, x2,
                 y2] = clip_line(xtemp, ytemp, c.vertices[edge[2]][0],
                                 c.vertices[edge[2]][1], q['width'],
                                 q['height'])
            if x1 or x2 or y1 or y2:
                path += 'M %.3f,%.3f %.3f,%.3f ' % (x1, y1, x2, y2)

        patternstyle = {'stroke': '#000000', 'stroke-width': str(scale)}
        attribs = {'d': path, 'style': simplestyle.formatStyle(patternstyle)}
        inkex.etree.SubElement(pattern, inkex.addNS('path', 'svg'), attribs)

        # link selected object to pattern
        obj = self.selected[self.options.ids[0]]
        style = {}
        if obj.attrib.has_key('style'):
            style = simplestyle.parseStyle(obj.attrib['style'])
        style['fill'] = 'url(#%s)' % pattern.get('id')
        obj.attrib['style'] = simplestyle.formatStyle(style)
        if obj.tag == inkex.addNS('g', 'svg'):
            for node in obj:
                style = {}
                if node.attrib.has_key('style'):
                    style = simplestyle.parseStyle(node.attrib['style'])
                style['fill'] = 'url(#%s)' % pattern.get('id')
                node.attrib['style'] = simplestyle.formatStyle(style)
Ejemplo n.º 42
0
class Plot(inkex.Effect):
    def __init__(self):
        inkex.Effect.__init__(self)
        self.OptionParser.add_option('--tab',
                                     action='store',
                                     type='string',
                                     dest='tab')
        self.OptionParser.add_option('--serialPort',
                                     action='store',
                                     type='string',
                                     dest='serialPort',
                                     default='COM1',
                                     help='Serial port')
        self.OptionParser.add_option('--serialBaudRate',
                                     action='store',
                                     type='string',
                                     dest='serialBaudRate',
                                     default='9600',
                                     help='Serial Baud rate')
        self.OptionParser.add_option('--flowControl',
                                     action='store',
                                     type='string',
                                     dest='flowControl',
                                     default='0',
                                     help='Flow control')
        self.OptionParser.add_option('--commandLanguage',
                                     action='store',
                                     type='string',
                                     dest='commandLanguage',
                                     default='hpgl',
                                     help='Command Language')
        self.OptionParser.add_option('--resolutionX',
                                     action='store',
                                     type='float',
                                     dest='resolutionX',
                                     default=1016.0,
                                     help='Resolution X (dpi)')
        self.OptionParser.add_option('--resolutionY',
                                     action='store',
                                     type='float',
                                     dest='resolutionY',
                                     default=1016.0,
                                     help='Resolution Y (dpi)')
        self.OptionParser.add_option('--pen',
                                     action='store',
                                     type='int',
                                     dest='pen',
                                     default=1,
                                     help='Pen number')
        self.OptionParser.add_option('--force',
                                     action='store',
                                     type='int',
                                     dest='force',
                                     default=24,
                                     help='Pen force (g)')
        self.OptionParser.add_option('--speed',
                                     action='store',
                                     type='int',
                                     dest='speed',
                                     default=20,
                                     help='Pen speed (cm/s)')
        self.OptionParser.add_option('--orientation',
                                     action='store',
                                     type='string',
                                     dest='orientation',
                                     default='90',
                                     help='Rotation (Clockwise)')
        self.OptionParser.add_option('--mirrorX',
                                     action='store',
                                     type='inkbool',
                                     dest='mirrorX',
                                     default='FALSE',
                                     help='Mirror X axis')
        self.OptionParser.add_option('--mirrorY',
                                     action='store',
                                     type='inkbool',
                                     dest='mirrorY',
                                     default='FALSE',
                                     help='Mirror Y axis')
        self.OptionParser.add_option('--center',
                                     action='store',
                                     type='inkbool',
                                     dest='center',
                                     default='FALSE',
                                     help='Center zero point')
        self.OptionParser.add_option('--overcut',
                                     action='store',
                                     type='float',
                                     dest='overcut',
                                     default=1.0,
                                     help='Overcut (mm)')
        self.OptionParser.add_option('--toolOffset',
                                     action='store',
                                     type='float',
                                     dest='toolOffset',
                                     default=0.25,
                                     help='Tool offset (mm)')
        self.OptionParser.add_option('--precut',
                                     action='store',
                                     type='inkbool',
                                     dest='precut',
                                     default='TRUE',
                                     help='Use precut')
        self.OptionParser.add_option('--flat',
                                     action='store',
                                     type='float',
                                     dest='flat',
                                     default=1.2,
                                     help='Curve flatness')
        self.OptionParser.add_option('--autoAlign',
                                     action='store',
                                     type='inkbool',
                                     dest='autoAlign',
                                     default='TRUE',
                                     help='Auto align')
        self.OptionParser.add_option('--debug',
                                     action='store',
                                     type='inkbool',
                                     dest='debug',
                                     default='FALSE',
                                     help='Show debug information')

    def effect(self):
        # get hpgl data
        myHpglEncoder = hpgl_encoder.hpglEncoder(self)
        try:
            self.hpgl, debugObject = myHpglEncoder.getHpgl()
        except Exception as inst:
            if inst.args[0] == 'NO_PATHS':
                # issue error if no paths found
                inkex.errormsg(
                    _("No paths where found. Please convert all objects you want to plot into paths."
                      ))
                return 1
            else:
                type, value, traceback = sys.exc_info()
                raise ValueError, ('', type, value), traceback
        # TODO: Get preview to work. This requires some work on the C++ side to be able to determine if it is
        # a preview or a final run. (Remember to set <effect needs-live-preview='false'> to true)
        '''
        if MAGIC:
            # reparse data for preview
            self.options.showMovements = True
            self.options.docWidth = self.uutounit(self.unittouu(self.document.getroot().get('width')), "px")
            self.options.docHeight = self.uutounit(self.unittouu(self.document.getroot().get('height')), "px")
            myHpglDecoder = hpgl_decoder.hpglDecoder(self.hpgl, self.options)
            doc, warnings = myHpglDecoder.getSvg()
            # deliver document to inkscape
            self.document = doc
        else:
        '''
        # convert to other formats
        if self.options.commandLanguage == 'HPGL':
            self.convertToHpgl()
        if self.options.commandLanguage == 'DMPL':
            self.convertToDmpl()
        if self.options.commandLanguage == 'ZING':
            self.convertToZing()
        # output
        if self.options.debug:
            self.showDebugInfo(debugObject)
        else:
            self.sendHpglToSerial()

    def convertToHpgl(self):
        # convert raw HPGL to HPGL
        hpglInit = 'IN;SP%d' % self.options.pen
        if self.options.force > 0:
            hpglInit += ';FS%d' % self.options.force
        if self.options.speed > 0:
            hpglInit += ';VS%d' % self.options.speed
        self.hpgl = hpglInit + self.hpgl + ';PU0,0;SP0;IN;'

    def convertToDmpl(self):
        # convert HPGL to DMPL
        # ;: = Initialise plotter
        # H = Home position
        # A = Absolute pen positioning
        # Ln = Line type
        # Pn = Pen select
        # Vn = velocity
        # ECn = Coordinate addressing, 1: 0.001 inch, 5: 0.005 inch, M: 0.1 mm
        # D = Pen down
        # U = Pen up
        # Z = Reset plotter
        # n,n, = Coordinate pair
        self.hpgl = self.hpgl.replace(';', ',')
        self.hpgl = self.hpgl.replace('PU', 'U')
        self.hpgl = self.hpgl.replace('PD', 'D')
        dmplInit = ';:HAL0P%d' % self.options.pen
        if self.options.speed > 0:
            dmplInit += 'V%d' % self.options.speed
        dmplInit += 'EC1'
        self.hpgl = dmplInit + self.hpgl[1:] + ',U0,0,P0Z'

    def convertToZing(self):
        # convert HPGL to Zing
        hpglInit = 'ZG;SP%d' % self.options.pen
        if self.options.force > 0:
            hpglInit += ';FS%d' % self.options.force
        if self.options.speed > 0:
            hpglInit += ';VS%d' % self.options.speed
        self.hpgl = hpglInit + self.hpgl + ';PU0,0;SP0;@'

    def sendHpglToSerial(self):
        # gracefully exit script when pySerial is missing
        try:
            import serial
        except ImportError, e:
            inkex.errormsg(
                _("pySerial is not installed." +
                  "\n\n1. Download pySerial here (not the \".exe\"!): http://pypi.python.org/pypi/pyserial"
                  +
                  "\n2. Extract the \"serial\" subfolder from the zip to the following folder: C:\\[Program files]\\inkscape\\python\\Lib\\"
                  + "\n3. Restart Inkscape."))
            return
        # send data to plotter
        mySerial = serial.Serial()
        mySerial.port = self.options.serialPort
        mySerial.baudrate = self.options.serialBaudRate
        mySerial.timeout = 0.1
        if self.options.flowControl == 'xonxoff':
            mySerial.xonxoff = True
        if self.options.flowControl == 'rtscts' or self.options.flowControl == 'dsrdtrrtscts':
            mySerial.rtscts = True
        if self.options.flowControl == 'dsrdtrrtscts':
            mySerial.dsrdtr = True
        try:
            mySerial.open()
        except Exception as inst:
            if 'ould not open port' in inst.args[0]:
                inkex.errormsg(
                    _("Could not open port. Please check that your plotter is running, connected and the settings are correct."
                      ))
                return
            else:
                type, value, traceback = sys.exc_info()
                raise ValueError, ('', type, value), traceback
        mySerial.write(self.hpgl)
        mySerial.read(2)
        mySerial.close()
Ejemplo n.º 43
0
from distutils.version import StrictVersion

import inkex

try:
    import scour
    try:
        from scour.scour import scourString
    except ImportError:  # compatibility for very old Scour (<= 0.26) - deprecated!
        try:
            from scour import scourString
            scour.__version__ = scour.VER
        except:
            raise
except Exception as e:
    inkex.errormsg("Failed to import Python module 'scour'.\nPlease make sure it is installed (e.g. using 'pip install scour' or 'sudo apt-get install python-scour') and try again.")
    inkex.errormsg("\nDetails:\n" + str(e))
    sys.exit()

try:
    import six
except Exception as e:
    inkex.errormsg("Failed to import Python module 'six'.\nPlease make sure it is installed (e.g. using 'pip install six' or 'sudo apt-get install python-six') and try again.")
    inkex.errormsg("\nDetails:\n" + str(e))
    sys.exit()


class ScourInkscape (inkex.Effect):

    def __init__(self):
        inkex.Effect.__init__(self)
def get_parameters(nrow, ncol):

    #SQUARE SYMBOLS
    if ( nrow ==  10 and ncol ==  10 ):
        return  8,  8, 1, 1, 3, 5, 1
    elif ( nrow ==  12 and ncol ==  12 ):
        return 10, 10, 1, 1, 5, 7, 1
    elif ( nrow ==  14 and ncol ==  14 ):
        return 12, 12, 1, 1, 8, 10, 1
    elif ( nrow ==  16 and ncol ==  16 ):
        return 14, 14, 1, 1, 12, 12, 1
    elif ( nrow ==  18 and ncol ==  18 ):
        return 16, 16, 1, 1, 18, 14, 1
    elif ( nrow ==  20 and ncol ==  20 ):
        return 18, 18, 1, 1, 22, 18, 1
    elif ( nrow ==  22 and ncol ==  22 ):
        return 20, 20, 1, 1, 30, 20, 1
    elif ( nrow ==  24 and ncol ==  24 ):
        return 22, 22, 1, 1, 36, 24, 1
    elif ( nrow ==  26 and ncol ==  26 ):
        return 24, 24, 1, 1, 44, 28, 1
    elif ( nrow ==  32 and ncol ==  32 ):
        return 14, 14, 2, 2, 62, 36, 1
    elif ( nrow ==  36 and ncol ==  36 ):
        return 16, 16, 2, 2, 86, 42, 1
    elif ( nrow ==  40 and ncol ==  40):
        return 18, 18, 2, 2, 114, 48, 1
    elif ( nrow ==  44 and ncol ==  44):
        return 20, 20, 2, 2, 144, 56, 1
    elif ( nrow ==  48 and ncol ==  48 ):
        return 22, 22, 2, 2, 174, 68, 1
        
    elif ( nrow ==  52 and ncol ==  52 ):
        return 24, 24, 2, 2, 102, 42, 2
    elif ( nrow ==  64 and ncol ==  64 ):
        return 16, 16, 4, 4, 140, 56, 2
        
    elif ( nrow ==  72 and ncol ==  72 ):
        return 16, 16, 4, 4, 92, 36, 4
    elif ( nrow ==  80 and ncol ==  80 ):
        return 18, 18, 4, 4, 114, 48, 4
    elif ( nrow ==  88 and ncol ==  88 ):
        return 20, 20, 4, 4, 144, 56, 4
    elif ( nrow ==  96 and ncol ==  96 ):
        return 22, 22, 4, 4, 174, 68, 4
        
    elif ( nrow ==  104 and ncol ==  104 ):
        return 24, 24, 4, 4, 136, 56, 6    
    elif ( nrow ==  120 and ncol ==  120):
        return 18, 18, 6, 6, 175, 68, 6
        
    elif ( nrow ==  132 and ncol ==  132):
        return 20, 20, 6, 6, 163, 62, 8
        
    elif (nrow == 144 and ncol == 144):
        return 22, 22, 6, 6, 0, 0, 0        #there are two separate sections of the data matrix with
                                            #different interleaving and reed-solomon parameters.
                                            #this will be handled separately
    
    #RECTANGULAR SYMBOLS
    elif ( nrow ==  8 and ncol ==  18 ):
        return  6, 16, 1, 1, 5, 7, 1
    elif ( nrow ==  8 and ncol ==  32 ):
        return  6, 14, 1, 2, 10, 11, 1
    elif ( nrow ==  12 and ncol ==  26 ):
        return  10, 24, 1, 1, 16, 14, 1
    elif ( nrow ==  12 and ncol ==  36 ):
        return  10, 16, 1, 2, 22, 18, 1
    elif ( nrow ==  16 and ncol ==  36 ):
        return  14, 16, 1, 2, 32, 24, 1
    elif ( nrow ==  16 and ncol ==  48 ):
        return  14, 22, 1, 2, 49, 28, 1
    
    #RETURN ERROR
    else:
        inkex.errormsg(_('Unrecognised DataMatrix size'))
        exit(0)
    
    return None
Ejemplo n.º 45
0
# local library
import inkex
import simplestyle
import simpletransform
import cubicsuperpath
import coloreffect
import dxf_templates

try:
    from numpy import *
    from numpy.linalg import solve
except:
    # Initialize gettext for messages outside an inkex derived class
    inkex.localize()
    inkex.errormsg(
        _("Failed to import the numpy or numpy.linalg modules. These modules are required by this extension. Please install them and try again."
          ))
    inkex.sys.exit()


def pointdistance((x1, y1), (x2, y2)):
    return math.sqrt(((x2 - x1)**2) + ((y2 - y1)**2))


def get_fit(u, csp, col):
    return (1 - u)**3 * csp[0][col] + 3 * (1 - u)**2 * u * csp[1][col] + 3 * (
        1 - u) * u**2 * csp[2][col] + u**3 * csp[3][col]


def get_matrix(u, i, j):
    if j == i + 2:
Ejemplo n.º 46
0
            return None

        file_name = os.path.splitext(os.path.basename(png_file))[0]
        output_file = os.path.join(output_dir, file_name + '.jpeg')
        command = ['convert', png_file, output_file]
        p = subprocess.Popen(command,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE)
        if p.wait() != 0:
            raise Exception('Is ImageMagick installed?\n'
                            'Failed to convert %s to JPEG' % png_file)

        return output_file


@contextlib.contextmanager
def _make_temp_directory():
    temp_dir = tempfile.mkdtemp(prefix='tmp-inkscape')
    try:
        yield temp_dir
    finally:
        shutil.rmtree(temp_dir)


if __name__ == '__main__':
    try:
        LayerExport().affect(output=False)
    except Exception as e:
        inkex.errormsg(str(e))
        sys.exit(1)
Ejemplo n.º 47
0
#!/usr/bin/env python

# We will use the inkex module with the predefined Effect base class.
import inkex
import simpletransform
import cubicsuperpath
import bezmisc
# The simplestyle module provides functions for style parsing.
import simplestyle

# third party
try:
    import numpy
except:
    inkex.errormsg(
        _("Failed to import the numpy modules. These modules are required by this extension. Please install them and try again.  On a Debian-like system this can be done with the command, sudo apt-get install python-numpy."
          ))
    exit()

mat_area = numpy.matrix([[0, 2, 1, -3], [-2, 0, 1, 1], [-1, -1, 0, 2],
                         [3, -1, -2, 0]])
mat_cofm_0 = numpy.matrix([[0, 35, 10, -45], [-35, 0, 12, 23],
                           [-10, -12, 0, 22], [45, -23, -22, 0]])
mat_cofm_1 = numpy.matrix([[0, 15, 3, -18], [-15, 0, 9, 6], [-3, -9, 0, 12],
                           [18, -6, -12, 0]])
mat_cofm_2 = numpy.matrix([[0, 12, 6, -18], [-12, 0, 9, 3], [-6, -9, 0, 15],
                           [18, -3, -15, 0]])
mat_cofm_3 = numpy.matrix([[0, 22, 23, -45], [-22, 0, 12, 10],
                           [-23, -12, 0, 35], [45, -10, -35, 0]])

Ejemplo n.º 48
0
    def effect(self):

        current_file = self.args[-1]
        bg_color = self.options.bg_color

        ##Implementare check_dir

        if (os.path.isdir(self.options.directory)) == True:

            ##CODICE SE ESISTE LA DIRECTORY
            #inkex.errormsg("OK") #DEBUG

            #Aggiungo un suffisso al nomefile per non sovrascrivere dei file
            if self.options.add_numeric_suffix_to_filename:
                dir_list = os.listdir(
                    self.options.directory
                )  #List di tutti i file nella directory di lavoro
                temp_name = self.options.filename
                max_n = 0
                for s in dir_list:
                    r = re.match(
                        r"^%s_0*(\d+)%s$" % (re.escape(temp_name), '.png'), s)
                    if r:
                        max_n = max(max_n, int(r.group(1)))
                self.options.filename = temp_name + "_" + (
                    "0" * (4 - len(str(max_n + 1))) + str(max_n + 1))

            #genero i percorsi file da usare

            suffix = ""
            if self.options.conversion_type == 1:
                suffix = "_BWfix_" + str(self.options.BW_threshold) + "_"
            elif self.options.conversion_type == 2:
                suffix = "_BWrnd_"
            elif self.options.conversion_type == 3:
                suffix = "_H_"
            elif self.options.conversion_type == 4:
                suffix = "_Hrow_"
            elif self.options.conversion_type == 5:
                suffix = "_Hcol_"
            else:
                if self.options.grayscale_resolution == 1:
                    suffix = "_Gray_256_"
                elif self.options.grayscale_resolution == 2:
                    suffix = "_Gray_128_"
                elif self.options.grayscale_resolution == 4:
                    suffix = "_Gray_64_"
                elif self.options.grayscale_resolution == 8:
                    suffix = "_Gray_32_"
                elif self.options.grayscale_resolution == 16:
                    suffix = "_Gray_16_"
                elif self.options.grayscale_resolution == 32:
                    suffix = "_Gray_8_"
                else:
                    suffix = "_Gray_"

            pos_file_png_exported = os.path.join(
                self.options.directory, self.options.filename + ".png")
            pos_file_png_BW = os.path.join(
                self.options.directory,
                self.options.filename + suffix + "preview.png")
            pos_file_gcode = os.path.join(
                self.options.directory,
                self.options.filename + suffix + "gcode.gcode")

            #Esporto l'immagine in PNG
            self.exportPage(pos_file_png_exported, current_file, bg_color)

            #DA FARE
            #Manipolo l'immagine PNG per generare il file Gcode
            self.PNGtoGcode(pos_file_png_exported, pos_file_png_BW,
                            pos_file_gcode)

        else:
            inkex.errormsg(
                "Directory does not exist! Please specify existing directory!")
Ejemplo n.º 49
0
options.outdir = os.path.expanduser(options.outdir)
if options.outdir is None:
    error("No output directory specified")
if not os.path.isdir(options.outdir):
    error("Bad output directory specified:\n'%s' is no dir" % options.outdir)
if not os.access(options.outdir, os.W_OK):
    error("Bad output directory specified:\nCould not write to '%s'" %
          options.outdir)

if options.source not in ('"selected_ids"', '"page"'):
    error("Select something to export (selected items or whole page)")
if options.source == '"selected_ids"' and options.ids is None:
    error("Select at least one item to export")
if options.source == '"page"' and not options.pageName:
    error("Please enter a page name")

if not checkForPath("inkscape"):
    error("Make sure you have 'inkscape' on your PATH")
if options.strip and not checkForPath("convert"):
    error(
        "Make sure you have 'convert' on your PATH if you want to reduce the image size using ImageMagick"
    )
if options.optimize and not checkForPath("optipng"):
    error(
        "Make sure you have 'optipng' on your PATH if you want to reduce the image size using OptiPNG"
    )

export(svg, options)

inkex.errormsg("done")
Ejemplo n.º 50
0
    def effect(self):
        global parent,nomTab,equalTabs,thickness,correction, Z, unit 
        
            # Get access to main SVG document element and get its dimensions.
        svg = self.document.getroot()
        
            # Get the attibutes:
        widthDoc  = self.svg.unittouu(svg.get('width'))
        heightDoc = self.svg.unittouu(svg.get('height'))

            # Create a new layer.
        layer = etree.SubElement(svg, 'g')
        layer.set(inkex.addNS('label', 'inkscape'), 'newlayer')
        layer.set(inkex.addNS('groupmode', 'inkscape'), 'layer')
        
        parent=self.svg.get_current_layer()
        
            # Get script's option values.
        unit=self.options.unit
        inside=self.options.inside
        X = self.svg.unittouu( str(self.options.length)  + unit )
        Y = self.svg.unittouu( str(self.options.width) + unit )
        Z = self.svg.unittouu( str(self.options.height)  + unit )
        thickness = self.svg.unittouu( str(self.options.thickness)  + unit )
        nomTab = self.svg.unittouu( str(self.options.tab) + unit )
        equalTabs=self.options.equal
        kerf = self.svg.unittouu( str(self.options.kerf)  + unit )
        clearance = self.svg.unittouu( str(self.options.clearance)  + unit )
        layout=self.options.style
        spacing = self.svg.unittouu( str(self.options.spacing)  + unit )
        ring = 1
        hingeOpt = self.options.hingeOpt
        hingeThick = self.options.hingeThick
        thumbTab = self.options.thumbTab 
            
        if inside: # if inside dimension selected correct values to outside dimension
            X+=thickness*2
            Y+=thickness*2
            Z+=thickness*2

        correction=kerf-clearance

        # check input values mainly to avoid python errors
        # TODO restrict values to *correct* solutions
        # TODO -- Do what the origial author suggested I do. QUALITY!
        error=0
        
        if min(X,Y,Z)==0:
            inkex.errormsg('Error: Dimensions must be non zero')
            error=1
        if max(X,Y,Z)>max(widthDoc,heightDoc)*10: # crude test
            inkex.errormsg('Error: Dimensions Too Large')
            error=1
        if min(X,Y,Z)<3*nomTab:
            inkex.errormsg('Error: Tab size too large')
            error=1
        if nomTab<thickness:
            inkex.errormsg('Error: Tab size too small')
            error=1
        if thickness==0:
            inkex.errormsg('Error: Thickness is zero')
            error=1
        if thickness>min(X,Y,Z)/3: # crude test
            inkex.errormsg('Error: Material too thick')
            error=1
        if correction>min(X,Y,Z)/3: # crude test
            inkex.errormsg('Error: Kerf/Clearence too large')
            error=1
        if spacing>max(X,Y,Z)*10: # crude test
            inkex.errormsg('Error: Spacing too large')
            error=1
        if spacing<kerf: #if spacing is less then kerf, the laser cuts will overlap and blast meaningful material.
            inkex.errormsg('Error: Spacing too small')
            error=1

        if error: exit()
    
        # layout format:(rootx),(rooty),Xlength,Ylength,tabInfo
        # root= (spacing,X,Y,Z) * values in tuple
        # tabInfo= <abcd> 0=holes 1=tabs
        if layout==0: # Diagramatic Layout TRBL
            pieces=[         #center low row
                    [(2,0,0,1),(3,0,1,1),X,Z,0b1000,-2],
                            #left middle row
                    [(1,0,0,0),(2,0,0,1),Z,Y,0b1111,0],
                            #center middle row
                    [(2,0,0,1),(2,0,0,1),X,Y,0b0000,0],
                            #right middle row
                    [(3,1,0,1),(2,0,0,1),Z+(EllipseCircumference(X/2, Z/2)/4)+thickness,Y,0b1011,1],
                            #center top row
                    [(2,0,0,1),(1,0,0,0),X,Z,0b0010,-1]]
        elif layout==1: # Inline(compact) Layout
            pieces=[#Base
                    [(1,0,0,0),(1,0,0,0),X,Y,0b0000,0],
                    #Front panel
                    [(2,1,0,0),(1,0,0,0),Z,Y,0b1111,0],
                    #Sides with curves
                    [(3,1,0,1),(1,0,0,0),X,Z,0b1000,-2],
                    [(4,2,0,1),(1,0,0,0),X,Z,0b0010,-1],
                    #Long piece w/ hinge  
                    [(5,3,0,1),(1,0,0,0),Z+(EllipseCircumference(X/2, Z/2)/4)+thickness,Y,0b1011,1]
                    ]

        for piece in pieces: # generate and draw each piece of the box
            (xs,xx,xy,xz)=piece[0]
            (ys,yx,yy,yz)=piece[1]
            x=xs*spacing+xx*X+xy*Y+xz*Z  # root x co-ord for piece
            y=ys*spacing+yx*X+yy*Y+yz*Z  # root y co-ord for piece
            dx=piece[2]
            dy=piece[3]
            tabs=piece[4]
            a=tabs>>3&1; b=tabs>>2&1; c=tabs>>1&1; d=tabs&1 # extract tab status for each side. It's a nasty packed binary flag format, but I'm not fixing it now.
            longSide = 0
            shortSide = 0
            skew = 0

            if piece[5] == 1:
                longSide = Z
            elif piece[5] < 0:
                shortSide = Z   
            
            # generate and draw the sides of each piece
            if piece[5] != -1:
                drawS(side(x,y,d,a,-b,a,-thickness if a else thickness,dx,1,0,a,longSide))          # side a (top)
            else:
                drawS(side(x,y,d,a,-b,a,-thickness if a else thickness,dx/2,1,0,a,-1))          # side a (top) when the top participates in a curve

            if piece[5] != -1 and piece[5] != 1:
                drawS(side(x+dx+skew,y,-b,a,-b,-c,thickness if b else -thickness,dy,0,1,b,shortSide, False if piece[5] != -2 else True, False if piece[5] != 1 else True))     # side b (right) except for side with living hinge or curves
            elif piece[5] == -1:
                drawS(side(x+dx+skew,y+dy,-b,-c,-b,a,thickness if b else -thickness,dy,0,-1,b,shortSide, True))     # side b (right) when the right side participates in a curve
            else: 
                #It is a cardnal sin to compare floats, so assume <0.0005 is 0 since the front end only gives you 3 digits of precision
                if float(0.0005) <= float(self.options.thumbTab):
                    side(x+dx+skew,y,-b,a,-b,-c,thickness if b else -thickness,dy,0,1,b,shortSide, False, True, True) #The one call to side that doesn't actually draw. Instead, side draws boxes on its own
                    drawS(box(x+dx+skew,y+thickness,x+dx+skew+self.svg.unittouu( thumbTab + unit ),y+dy-thickness, True))
                else:
                    drawS(side(x+dx+skew,y,-b,a,-b,-c,thickness if b else -thickness,dy,0,1,b,shortSide, False, True)) #side b (right) on the right side of a living hinge


            if piece[5] != -2:
                drawS(side(x,y+dy,d,-c,-b,-c,thickness if c else -thickness,dx,1,0,c,longSide)) # side c (bottom)
            else:
                drawS(side(x,y+dy,d,-c,-b,-c,thickness if c else -thickness,dx/2,1,0,c,-1)) # side c (bottom) when the bottom participates in a curve

            drawS(side(x,y+dy,d,-c,d,a,-thickness if d else thickness,dy,0,-1,d,0))      # side d (left)

            if piece[5] < 0:
                draw_SVG_ellipse(x+(dx/2), y+(dy/2), (dx/2), (dy/2), [(1.5*math.pi), 0] if piece[5] == -1 else [0, 0.5*math.pi]) #draw the curve

            if piece[5] == 1: #Piece should contain a living hinge
                if hingeOpt == 0: #Traditional parallel slit
                    self.livingHinge2(x+(Z/2), y, x+(Z/2)+(EllipseCircumference(X/2, Z/2)/4), y + (dy), hingeThick)
                elif hingeOpt == 1: #Single spiral
                    if not inside:
                        self.livingHinge3(x+(Z/2), y+thickness, x+(Z/2)+(EllipseCircumference(X/2, Z/2)/4), y + dy - thickness, 1, hingeThick)
                    else:
                        self.livingHinge3(x+(Z/2), y + 2*thickness, x+(Z/2)+(EllipseCircumference(X/2, Z/2)/4), y + dy - 2*thickness, 1, hingeThick)

                elif hingeOpt == 2: #Double spiral
                    self.livingHinge3(x+(Z/2), y+thickness, x+(Z/2)+(EllipseCircumference(X/2, Z/2)/4), y + (dy/2), 1, hingeThick)
                    self.livingHinge3(x+(Z/2), y+(dy/2), x+(Z/2)+(EllipseCircumference(X/2, Z/2)/4), y + dy - thickness, -1, hingeThick)
                elif hingeOpt == 3 or hingeOpt == 4: #Both snake-based designs
                    self.livingHinge4(x+(Z/2), y, x+(Z/2)+(EllipseCircumference(X/2, Z/2)/4), y + (dy), False if hingeOpt == 3 else True, 0, hingeThick)
                elif hingeOpt == 5: #Double snake design
                    self.livingHinge4(x+(Z/2), y, x+(Z/2)+EllipseCircumference(X/2, Z/2)/4, y + (dy/2) + thickness, True, 0, hingeThick) #Add thickness as a cheat so design 4 doesn't have to know if it's a short or long variant
                    self.livingHinge4(x+(Z/2), y + (dy/2) - thickness, (x+(Z/2)+(EllipseCircumference(X/2, Z/2)/4)), y + dy, True, 1, hingeThick) 
	def effect( self ):

		# Viewbox handling
		self.handleViewBox()

		# First traverse the document (or selected items), reducing
		# everything to line segments.  If working on a selection,
		# then determine the selection's bounding box in the process.
		# (Actually, we just need to know it's extrema on the x-axis.)

		if self.options.ids:
			# Traverse the selected objects
			for id in self.options.ids:
				transform = self.recursivelyGetEnclosingTransform( self.selected[id] )
				self.recursivelyTraverseSvg( [self.selected[id]], transform )
		else:
			# Traverse the entire document building new, transformed paths
			self.recursivelyTraverseSvg( self.document.getroot(), self.docTransform )

		# Determine the center of the drawing's bounding box
		self.cx = self.xmin + ( self.xmax - self.xmin ) / 2.0
		self.cy = self.ymin + ( self.ymax - self.ymin ) / 2.0

		# Determine which polygons lie entirely within other polygons
		try:
			if '/' == os.sep:
				self.f = open( os.path.expanduser( self.options.fname ), 'w')
			else:
				self.f = open( os.path.expanduser( self.options.fname ).replace('/', os.sep), 'w')

			self.f.write('''
// Module names are of the form poly_<inkscape-path-id>().  As a result,
// you can associate a polygon in this OpenSCAD program with the corresponding
// SVG element in the Inkscape document by looking for the XML element with
// the attribute id=\"inkscape-path-id\".

// fudge value is used to ensure that subtracted solids are a tad taller
// in the z dimension than the polygon being subtracted from.  This helps
// keep the resulting .stl file manifold.
fudge = 0.1;

			
			    /// Global parameters
grid = ''')
			if self.options.grid :
				self.f.write('''true''')
			else:
				self.f.write('''false''')
			
			self.f.write(''' ;   //Use grid for multi elements cutters
full= ''')			
			if self.options.thickness :
				self.f.write('''false''')
			else:
				self.f.write('''true''')
			
			self.f.write(''' ;  //For build full or empty objects (see instuctables for details)
borderThick = %s  ;    //border thickness (mm)
cutterThick = borderThick ;     //cookiecutter wall thickness
h=   %s  ;    //total height of the cookie cutter (mm)
borderType=  %s   ;    //type of border, 0 none, 1-classic, 2-cone
Lreb = %s;     //Width of border (en mm)
Hreb = %s ;    //Thickness of border (mm)




                /// Grid parameters
gridX=300;      //Maximum X dimension Change only if you build cookies bigger than 30cm
gridY=300;      //Maximum Y dimension Change only if you build cookies bigger than 30cm
meshSolid=%s;    //width of solid part of grid
meshSpace=%s;    //width of blank part of grid 
gridThickness=Hreb; //thickness of grid
moveGridX=0;    //X shift for adujustments
moveGridY=0;    //Y shift for adjustments
rotateGridZ=%s;  //Z rotation for adjtments
$fn = 10;


''' % (self.options.thickness, self.options.height, self.options.Flanges_type, self.options.Flange_width, self.options.Flange_height, self.options.gridBThick, self.options.gridBSpace, self.options.rotateZ ) )

 
 

			for key in self.paths:
				self.f.write( '\n' )
				self.convertPath( key )

		# Now output the list of modules to call
			self.f.write( '\n' )
			self.f.write('''
module shape(h){ ''' )

			for call in self.call_list:
				self.f.write( call )
			self.f.write('''
}

//-------------------------------------------------

/// Module grid have been imported from the Openscad grid creator by Glyn
/// Orininaly published on http://www.thingiverse.com/thing:29211
/// Under the terms of Creative Commons By-Sa (08.26.2012)

module grid(meshSolid, meshSpace, gridThickness, gridX, gridY){

meshX=gridX;
meshY=gridY;
nX=meshX/(meshSolid+meshSpace);
nY=meshY/(meshSolid+meshSpace);

for (i=[0:nX]) {
	 	 translate([-(meshX/2)+i*(meshSolid+meshSpace),-meshY/2,-gridThickness/2]) cube(size=[meshSolid,meshY,gridThickness],center=false);
}

for (i=[0:nY]) {
	 	translate([-meshX/2,-(meshY/2)+i*(meshSolid+meshSpace),-gridThickness/2]) cube(size=[meshX,meshSolid,gridThickness],center=false);
    }
}


module rebords(borderType,borderThick,Lreb,Hreb){
if (borderType==0){}
if (borderType==1){
    cylinder(h = Hreb, r=(borderThick+Lreb));} 
if (borderType==2) {
    cylinder(h = Hreb, r1=(borderThick+Lreb),r2=(borderThick));}
}


module borders(h){
cylinder(r=cutterThick,h=h*.75);
cylinder(r=cutterThick/2,h=h);
}



module fullVolume (borderType,borderThick,Lreb,Hreb,h) {
minkowski(){
    shape(0.001);
    union(){
       borders(h);
       rebords(borderType,borderThick,Lreb,Hreb);
    }}}


module finalShape(){
if (full == false){
    difference(){
      fullVolume(borderType,borderThick,Lreb,Hreb,h);
      translate([0,0,(-0.5*h)]) shape(3*h);
}}
else{
          fullVolume(borderType,borderThick,Lreb,Hreb,h);
}
}


if (grid==true){
union (){
  finalShape();
  intersection() {
   translate([moveGridX,moveGridY,(0.5*gridThickness)]) rotate([0,0,rotateGridZ]) grid(meshSolid, meshSpace, gridThickness, gridX, gridY);
    shape();
}}
}
else{
    finalShape();
}

// Enjoy your cookies ! :)

''')

		except:
			inkex.errormsg( 'Unable to open the file ' + self.options.fname )
Ejemplo n.º 52
0
def printError(string):
    inkex.errormsg(_(str(string)))
Ejemplo n.º 53
0
def command(comPort, cmd):
    if (comPort is not None) and (cmd is not None):
        try:
            comPort.write(cmd)
            response = comPort.readline()
            nRetryCount = 0
            while (len(response) == 0) and (nRetryCount < 100):
                # get new response to replace null response if necessary
                response = comPort.readline()
                nRetryCount += 1
                inkex.errormsg("Retry" + str(nRetryCount))
            if response.strip().startswith("OK"):
                pass  # 	inkex.errormsg( 'OK after command: ' + cmd ) #Debug option: indicate which command.
            else:
                if (response != ''):
                    inkex.errormsg('Error: Unexpected response from EBB.')
                    inkex.errormsg('   Command: ' + cmd.strip())
                    inkex.errormsg('   Response: ' + str(response.strip()))
                else:
                    inkex.errormsg('EBB Serial Timeout after command: ' + cmd)

# 		except Exception,e:
# 			inkex.errormsg(  str(e))	#For debugging: one may wish to display the error.
        except:
            inkex.errormsg('Failed after command: ' + cmd)
            pass
Ejemplo n.º 54
0
    def effect(self):
        thickness = self.svg.unittouu(
            str(self.options.thickness) + self.options.unit)
        kerf = self.svg.unittouu(
            str(self.options.kerf) +
            self.options.unit) / 2  #kerf is diameter in UI and radius in lib

        spaceing = self.svg.unittouu(
            str(self.options.spaceing) + self.options.unit)
        XYZ = [
            self.svg.unittouu(str(self.options.X_size) + self.options.unit),
            self.svg.unittouu(str(self.options.Y_size) + self.options.unit),
            self.svg.unittouu(str(self.options.Z_size) + self.options.unit)
        ]

        if (
                self.options.inside == '0'
        ):  #if the sizes are outside sizes reduce the size by thickness if the side gets drawn
            draw = (self.options.d_left, self.options.d_front,
                    self.options.d_top, self.options.d_right,
                    self.options.d_back, self.options.d_bottom
                    )  #order in XYZXYZ
            for i in range(6):
                XYZ[i % 3] -= (thickness if draw[i] else 0
                               )  #remove a thickness if drawn

#compartments on the X axis, devisons in Y direction
        X_divisions_distances = []
        if (self.options.X_compartments > 1):
            if (self.options.X_mode == 'even'):  #spliting in even compartments
                X_divisions_distances = [
                    ((XYZ[0]) - (self.options.X_compartments - 1) *
                     (thickness)) / self.options.X_compartments
                ]
            else:
                for dist in self.options.X_divisions.replace(
                        ",",
                        ".").split(";"):  #fixing seperator, spliting string
                    X_divisions_distances += [
                        float(self.svg.unittouu(dist + self.options.unit))
                    ]  #translate into universal units
            X_divisions_distances[0] += kerf  #fixing for kerf
            if self.options.X_mode != 'absolut':  #for even and relative fix list lenght and offset compartments to absolut distances
                while (len(X_divisions_distances) <
                       self.options.X_compartments +
                       1):  #making the list long enought for relative offsets
                    X_divisions_distances += X_divisions_distances
                for i in range(1, self.options.X_compartments
                               ):  #offset to absolut distances
                    X_divisions_distances[i] += X_divisions_distances[
                        i - 1] + thickness - kerf
            X_divisions_distances = X_divisions_distances[
                0:self.options.X_compartments]  #cutting excesive lenght off

            if (X_divisions_distances[-2] + thickness >
                    XYZ[0]) and not self.options.X_fit:
                inkex.errormsg("X Axis compartments outside of plate")
            if self.options.X_fit:
                XYZ[0] = X_divisions_distances[-1] - kerf
            X_divisions_distances = X_divisions_distances[
                0:-1]  #cutting the last of

        Y_divisions_distances = []
        if (self.options.Y_compartments > 1):
            if (self.options.Y_mode == 'even'):  #spliting in even compartments
                Y_divisions_distances = [
                    ((XYZ[1]) - (self.options.Y_compartments - 1) *
                     (thickness)) / self.options.Y_compartments
                ]
            else:
                for dist in self.options.Y_divisions.replace(
                        ",",
                        ".").split(";"):  #fixing seperator, spliting string
                    Y_divisions_distances += [
                        float(self.svg.unittouu(dist + self.options.unit))
                    ]  #translate into universal units
            Y_divisions_distances[0] += kerf  #fixing for kerf
            if self.options.Y_mode != 'absolut':  #for even and relative fix list lenght and offset compartments to absolut distances
                while (len(Y_divisions_distances) <
                       self.options.Y_compartments +
                       1):  #making the list long enought for relative offsets
                    Y_divisions_distances += Y_divisions_distances
                for i in range(1, self.options.Y_compartments
                               ):  #offset to absolut distances
                    Y_divisions_distances[i] += Y_divisions_distances[
                        i - 1] + thickness - kerf
            Y_divisions_distances = Y_divisions_distances[
                0:self.options.Y_compartments]  #cutting excesive lenght off

            if (Y_divisions_distances[-2] + thickness >
                    XYZ[1]) and not self.options.X_fit:
                inkex.errormsg("Y Axis compartments outside of plate")
            if self.options.Y_fit:
                XYZ[1] = Y_divisions_distances[-1] - kerf
            Y_divisions_distances = Y_divisions_distances[
                0:-1]  #cutting the last of

        if (self.options.tab_mode == 'number'):  #fixed number of tabs
            Tabs_XYZ = [
                self.options.X_tabs, self.options.Y_tabs, self.options.Z_tabs
            ]
        else:  #compute apropriate number of tabs for the edges
            tab_size = float(
                self.svg.unittouu(
                    str(self.options.tab_size) + self.options.unit))
            Tabs_XYZ = [
                max(1,
                    int(XYZ[0] / (tab_size)) / 2),
                max(1,
                    int(XYZ[1] / (tab_size)) / 2),
                max(1,
                    int(XYZ[2] / (tab_size)) / 2)
            ]

#top and bottom plate
        tabs_tb = (Tabs_XYZ[0] if self.options.d_back else 0,
                   Tabs_XYZ[1] if self.options.d_right else 0,
                   Tabs_XYZ[0] if self.options.d_front else 0,
                   Tabs_XYZ[1] if self.options.d_left else 0)
        start_tb = (True if self.options.d_back else False,
                    True if self.options.d_right else False,
                    True if self.options.d_front else False,
                    True if self.options.d_left else False)
        Plate_tb = mehr_plate.Mehr_plate((XYZ[0], XYZ[1]), tabs_tb, start_tb,
                                         thickness,
                                         kerf)  #top and bottom plate
        for d in X_divisions_distances:
            Plate_tb.add_holes('Y', d, Tabs_XYZ[1])
        for d in Y_divisions_distances:
            Plate_tb.add_holes('X', d, Tabs_XYZ[0])
#left and right plate
        tabs_lr = (Tabs_XYZ[2] if self.options.d_back else 0,
                   Tabs_XYZ[1] if self.options.d_top else 0,
                   Tabs_XYZ[2] if self.options.d_front else 0,
                   Tabs_XYZ[1] if self.options.d_bottom else 0)
        start_lr = (True if self.options.d_back else False, False,
                    True if self.options.d_front else False, False)
        Plate_lr = mehr_plate.Mehr_plate((XYZ[2], XYZ[1]), tabs_lr, start_lr,
                                         thickness,
                                         kerf)  #left and right plate
        for d in Y_divisions_distances:
            Plate_lr.add_holes('X', d, Tabs_XYZ[2])


#front and back plate
        tabs_fb = (Tabs_XYZ[0] if self.options.d_top else 0,
                   Tabs_XYZ[2] if self.options.d_right else 0,
                   Tabs_XYZ[0] if self.options.d_bottom else 0,
                   Tabs_XYZ[2] if self.options.d_left else 0)  #
        start_fb = (False, False, False, False)
        Plate_fb = mehr_plate.Mehr_plate((XYZ[0], XYZ[2]), tabs_fb, start_fb,
                                         thickness, kerf)  #font and back plate
        for d in X_divisions_distances:
            Plate_fb.add_holes('Y', d, Tabs_XYZ[2])

        Plate_xc = mehr_plate.Mehr_plate(
            (XYZ[2], XYZ[1]), tabs_lr, (False, False, False, False), thickness,
            kerf)
        for d in Y_divisions_distances:
            Plate_xc.holes += [
                Plate_xc.rect(
                    [0, Plate_xc.corner_offset[1] + d + kerf],
                    [Plate_xc.AABB[0] / 2 - kerf, thickness - 2 * kerf])
            ]

        Plate_yc = mehr_plate.Mehr_plate(
            (XYZ[0], XYZ[2]), tabs_fb, (False, False, False, False), thickness,
            kerf)
        for d in X_divisions_distances:
            Plate_yc.holes += [
                Plate_yc.rect(
                    [Plate_yc.corner_offset[0] + d + kerf, 0],
                    [thickness - 2 * kerf, Plate_yc.AABB[1] / 2 - kerf])
            ]

        X_offset = 0
        Y_offset = 0
        if (self.options.d_top):
            Plate_tb.draw(
                [X_offset + spaceing, spaceing], ["#000000", "#ff0000"],
                self.svg.get_current_layer()
            )  #drawing a plate using black for the outline and red for holes
            X_offset += Plate_tb.AABB[0] + spaceing
            Y_offset = max(Y_offset, Plate_tb.AABB[1])
        if (self.options.d_bottom):
            Plate_tb.draw([X_offset + spaceing, spaceing],
                          ["#000000", "#ff0000"], self.svg.get_current_layer())
            X_offset += Plate_tb.AABB[0] + spaceing
            Y_offset = max(Y_offset, Plate_tb.AABB[1])

        if (self.options.d_left):
            Plate_lr.draw([X_offset + spaceing, spaceing],
                          ["#000000", "#ff0000"], self.svg.get_current_layer())
            X_offset += Plate_lr.AABB[0] + spaceing
            Y_offset = max(Y_offset, Plate_lr.AABB[1])
        if (self.options.d_right):
            Plate_lr.draw([X_offset + spaceing, spaceing],
                          ["#000000", "#ff0000"], self.svg.get_current_layer())
            X_offset += Plate_lr.AABB[0] + spaceing
            Y_offset = max(Y_offset, Plate_lr.AABB[1])

        if (self.options.d_front):
            Plate_fb.draw([X_offset + spaceing, spaceing],
                          ["#000000", "#ff0000"], self.svg.get_current_layer())
            X_offset += Plate_fb.AABB[0] + spaceing
            Y_offset = max(Y_offset, Plate_fb.AABB[1])
        if (self.options.d_back):
            Plate_fb.draw([X_offset + spaceing, spaceing],
                          ["#000000", "#ff0000"], self.svg.get_current_layer())
            X_offset += Plate_fb.AABB[0] + spaceing
            Y_offset = max(Y_offset, Plate_fb.AABB[1])
        X_offset = 0
        for i in range(self.options.X_compartments - 1):
            Plate_xc.draw([X_offset + spaceing, spaceing + Y_offset],
                          ["#000000", "#ff0000"], self.svg.get_current_layer())
            X_offset += Plate_xc.AABB[0] + spaceing
        X_offset = 0
        Y_offset += spaceing + Plate_xc.AABB[1]
        for i in range(self.options.Y_compartments - 1):
            Plate_yc.draw([X_offset + spaceing, spaceing + Y_offset],
                          ["#000000", "#ff0000"], self.svg.get_current_layer())
            X_offset += Plate_yc.AABB[0] + spaceing
import numpy as np

import inkex
from lxml import etree

try:
    inkex.localization.localize()
except:
    import gettext
    _ = gettext.gettext

try:
    from PIL import Image
except:
    inkex.errormsg(
        _("The python module PIL is required for this extension.\n\n" +
          "Technical details:\n%s" % (e, )))
    sys.exit()


class raster_to_svg_ordered_dithering(inkex.Effect):
    def __init__(self):
        inkex.Effect.__init__(self)

        self.arg_parser.add_argument(
            "-t",
            "--width",
            action="store",
            type=int,
            dest="width",
            default=200,
def printDebug(string):
    inkex.errormsg(_(string))
Ejemplo n.º 57
0
    def recursivelyTraverseSvg(self,
                               aNodeList,
                               matCurrent=[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]],
                               parent_visibility='visible'):
        '''
		Recursively walk the SVG document, building polygon vertex lists
		for each graphical element we support.

		Rendered SVG elements:
			<circle>, <ellipse>, <line>, <path>, <polygon>, <polyline>, <rect>

		Supported SVG elements:
			<group>, <use>

		Ignored SVG elements:
			<defs>, <eggbot>, <metadata>, <namedview>, <pattern>

		All other SVG elements trigger an error (including <text>)
		'''

        for node in aNodeList:

            # Ignore invisible nodes
            v = node.get('visibility', parent_visibility)
            if v == 'inherit':
                v = parent_visibility
            if v == 'hidden' or v == 'collapse':
                pass

            # first apply the current matrix transform to this node's tranform
            matNew = simpletransform.composeTransform(
                matCurrent,
                simpletransform.parseTransform(node.get("transform")))

            if node.tag == inkex.addNS('g', 'svg') or node.tag == 'g':

                self.recursivelyTraverseSvg(node, matNew, parent_visibility=v)

            elif node.tag == inkex.addNS('use', 'svg') or node.tag == 'use':

                # A <use> element refers to another SVG element via an xlink:href="#blah"
                # attribute.  We will handle the element by doing an XPath search through
                # the document, looking for the element with the matching id="blah"
                # attribute.  We then recursively process that element after applying
                # any necessary (x,y) translation.
                #
                # Notes:
                #  1. We ignore the height and width attributes as they do not apply to
                #     path-like elements, and
                #  2. Even if the use element has visibility="hidden", SVG still calls
                #     for processing the referenced element.  The referenced element is
                #     hidden only if its visibility is "inherit" or "hidden".

                refid = node.get(inkex.addNS('href', 'xlink'))
                if not refid:
                    pass

                # [1:] to ignore leading '#' in reference
                path = '//*[@id="%s"]' % refid[1:]
                refnode = node.xpath(path)
                if refnode:
                    x = float(node.get('x', '0'))
                    y = float(node.get('y', '0'))
                    # Note: the transform has already been applied
                    if (x != 0) or (y != 0):
                        matNew2 = composeTransform(
                            matNew,
                            parseTransform('translate(%f,%f)' % (x, y)))
                    else:
                        matNew2 = matNew
                    v = node.get('visibility', v)
                    self.recursivelyTraverseSvg(refnode,
                                                matNew2,
                                                parent_visibility=v)

            elif node.tag == inkex.addNS('path', 'svg'):

                path_data = node.get('d')
                if path_data:
                    self.addPathVertices(path_data, node, matNew)

            elif node.tag == inkex.addNS('rect', 'svg') or node.tag == 'rect':

                # Manually transform
                #
                #    <rect x="X" y="Y" width="W" height="H"/>
                #
                # into
                #
                #    <path d="MX,Y lW,0 l0,H l-W,0 z"/>
                #
                # I.e., explicitly draw three sides of the rectangle and the
                # fourth side implicitly

                # Create a path with the outline of the rectangle
                x = float(node.get('x'))
                y = float(node.get('y'))
                if (not x) or (not y):
                    pass
                w = float(node.get('width', '0'))
                h = float(node.get('height', '0'))
                a = []
                a.append(['M ', [x, y]])
                a.append([' l ', [w, 0]])
                a.append([' l ', [0, h]])
                a.append([' l ', [-w, 0]])
                a.append([' Z', []])
                self.addPathVertices(simplepath.formatPath(a), node, matNew)

            elif node.tag == inkex.addNS('line', 'svg') or node.tag == 'line':

                # Convert
                #
                #   <line x1="X1" y1="Y1" x2="X2" y2="Y2/>
                #
                # to
                #
                #   <path d="MX1,Y1 LX2,Y2"/>

                x1 = float(node.get('x1'))
                y1 = float(node.get('y1'))
                x2 = float(node.get('x2'))
                y2 = float(node.get('y2'))
                if (not x1) or (not y1) or (not x2) or (not y2):
                    pass
                a = []
                a.append(['M ', [x1, y1]])
                a.append([' L ', [x2, y2]])
                self.addPathVertices(simplepath.formatPath(a), node, matNew)

            elif node.tag == inkex.addNS('polyline',
                                         'svg') or node.tag == 'polyline':

                # Convert
                #
                #  <polyline points="x1,y1 x2,y2 x3,y3 [...]"/>
                #
                # to
                #
                #   <path d="Mx1,y1 Lx2,y2 Lx3,y3 [...]"/>
                #
                # Note: we ignore polylines with no points

                pl = node.get('points', '').strip()
                if pl == '':
                    pass

                pa = pl.split()
                d = "".join([
                    "M " + pa[i] if i == 0 else " L " + pa[i]
                    for i in range(0, len(pa))
                ])
                self.addPathVertices(d, node, matNew)

            elif node.tag == inkex.addNS('polygon',
                                         'svg') or node.tag == 'polygon':

                # Convert
                #
                #  <polygon points="x1,y1 x2,y2 x3,y3 [...]"/>
                #
                # to
                #
                #   <path d="Mx1,y1 Lx2,y2 Lx3,y3 [...] Z"/>
                #
                # Note: we ignore polygons with no points

                pl = node.get('points', '').strip()
                if pl == '':
                    pass

                pa = pl.split()
                d = "".join([
                    "M " + pa[i] if i == 0 else " L " + pa[i]
                    for i in range(0, len(pa))
                ])
                d += " Z"
                self.addPathVertices(d, node, matNew)

            elif node.tag == inkex.addNS( 'ellipse', 'svg' ) or \
             node.tag == 'ellipse' or \
             node.tag == inkex.addNS( 'circle', 'svg' ) or \
             node.tag == 'circle':

                # Convert circles and ellipses to a path with two 180 degree arcs.
                # In general (an ellipse), we convert
                #
                #   <ellipse rx="RX" ry="RY" cx="X" cy="Y"/>
                #
                # to
                #
                #   <path d="MX1,CY A RX,RY 0 1 0 X2,CY A RX,RY 0 1 0 X1,CY"/>
                #
                # where
                #
                #   X1 = CX - RX
                #   X2 = CX + RX
                #
                # Note: ellipses or circles with a radius attribute of value 0 are ignored

                if node.tag == inkex.addNS('ellipse',
                                           'svg') or node.tag == 'ellipse':
                    rx = float(node.get('rx', '0'))
                    ry = float(node.get('ry', '0'))
                else:
                    rx = float(node.get('r', '0'))
                    ry = rx
                if rx == 0 or ry == 0:
                    pass

                cx = float(node.get('cx', '0'))
                cy = float(node.get('cy', '0'))
                x1 = cx - rx
                x2 = cx + rx
                d = 'M %f,%f ' % ( x1, cy ) + \
                 'A %f,%f ' % ( rx, ry ) + \
                 '0 1 0 %f,%f ' % ( x2, cy ) + \
                 'A %f,%f ' % ( rx, ry ) + \
                 '0 1 0 %f,%f' % ( x1, cy )
                self.addPathVertices(d, node, matNew)

            elif node.tag == inkex.addNS('pattern',
                                         'svg') or node.tag == 'pattern':

                pass

            elif node.tag == inkex.addNS('metadata',
                                         'svg') or node.tag == 'metadata':

                pass

            elif node.tag == inkex.addNS('defs', 'svg') or node.tag == 'defs':

                pass

            elif node.tag == inkex.addNS(
                    'namedview', 'sodipodi') or node.tag == 'namedview':

                pass

            elif node.tag == inkex.addNS('eggbot',
                                         'svg') or node.tag == 'eggbot':

                pass

            elif node.tag == inkex.addNS('text', 'svg') or node.tag == 'text':

                inkex.errormsg(
                    'Warning: unable to draw text, please convert it to a path first.'
                )

                pass

            elif not isinstance(node.tag, basestring):

                pass

            else:

                inkex.errormsg(
                    'Warning: unable to draw object <%s>, please convert it to a path first.'
                    % node.tag)
                pass
Ejemplo n.º 58
0
    def effect(self):
        # Adjust the document view for the desired sticker size
        root = self.svg.getElement("//svg:svg")

        subline_fontsize = 40  #px; one line of bottom text (id and owner) creates a box of that height

        #our DataMatrix has size 16x16, each cube is sized by 16x16px -> total size is 256x256px. We use 4px padding for all directions
        DataMatrix_xy = 16
        DataMatrix_height = 16 * DataMatrix_xy
        DataMatrix_width = DataMatrix_height
        sticker_padding = 4
        sticker_height = DataMatrix_height + subline_fontsize + 3 * sticker_padding
        sticker_width = 696

        #configure font sizes and box heights to define how large the font size may be at maximum (to omit overflow)
        objectNameMaxHeight = sticker_height - 2 * subline_fontsize - 4 * sticker_padding
        objectNameMaxLines = 5
        objectNameFontSize = objectNameMaxHeight / objectNameMaxLines  #px; generate main font size from lines and box size

        root.set("width", str(sticker_width) + "px")
        root.set("height", str(sticker_height) + "px")
        root.set("viewBox",
                 "%f %f %f %f" % (0, 0, sticker_width, sticker_height))

        #clean the document (make it blank) to avoid printing duplicated things
        ct = 0
        for node in self.document.xpath('//*', namespaces=inkex.NSS):
            ct = ct + 1
            if ct > 3:  #we keep svg:svg, sodipodi:namedview and svg:defs which defines the default canvas without any content inside
                #inkex.errormsg(str(node))
                try:
                    root.remove(node)
                except Exception as e:
                    pass

        #set the document units
        self.document.getroot().find(inkex.addNS("namedview", "sodipodi")).set(
            "inkscape:document-units", "px")

        # Download the recent inventory CSV file and parse line by line to create an inventory sticker
        password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
        password_mgr.add_password(None, self.options.server_address,
                                  self.options.htuser, self.options.htpassword)
        handler = urllib.request.HTTPBasicAuthHandler(password_mgr)
        opener = urllib.request.build_opener(handler)

        try:
            inventoryData = opener.open(
                self.options.server_address).read().decode("utf-8")
            urllib.request.install_opener(opener)

            inventoryCSVParent = os.path.join(self.options.export_dir,
                                              "InventorySticker")
            inventoryCSV = os.path.join(inventoryCSVParent, "inventory.csv")

            # To avoid messing with old stickers we remove the directory on Client before doing something new
            shutil.rmtree(inventoryCSVParent, ignore_errors=True
                          )  #remove the output directory before doing new job

            # we are going to write the imported Server CSV file temporarily. Otherwise CSV reader seems to mess with the file if passed directly
            if not os.path.exists(inventoryCSVParent):
                os.mkdir(inventoryCSVParent)
            with open(inventoryCSV, 'w', encoding="utf-8") as f:
                f.write(inventoryData)
                f.close()

            #parse sticker Ids from user input
            if self.options.sticker_ids != "*":
                sticker_ids = self.options.sticker_ids.split(",")
            else:
                sticker_ids = None

            with open(inventoryCSV, 'r', encoding="utf-8") as csv_file:
                csv_reader = csv.reader(csv_file, delimiter=",")
                for row in csv_reader:
                    internal_id = row[0]
                    doc_title = row[1]
                    sticker_id = row[2]
                    level = row[3]
                    zone = row[4]

                    if sticker_ids is None or sticker_id in sticker_ids:
                        #create new sub directories for each non-existent FabLab zone (if flat export is disabled)
                        if self.options.flat_export == False:
                            if not zone:
                                zoneDir = os.path.join(
                                    inventoryCSVParent,
                                    "Keinem Bereich zugeordnet")
                            else:
                                zoneDir = os.path.join(
                                    inventoryCSVParent,
                                    get_valid_filename(zone)
                                )  #remove invalid charaters from zone
                            if not os.path.exists(zoneDir):
                                os.mkdir(zoneDir)
                        else:
                            zoneDir = inventoryCSVParent  #use top directory

                        #Generate the recent sticker content
                        stickerGroup = self.document.getroot().add(
                            inkex.Group(
                                id="InventorySticker_Id" +
                                sticker_id))  #make a new group at root level
                        DataMatrixStyle = inkex.Style({
                            "stroke": "none",
                            "stroke-width": "1",
                            "fill": "#000000"
                        })
                        DataMatrixAttribs = {
                            "style": str(DataMatrixStyle),
                            "height": str(DataMatrix_xy) + "px",
                            "width": str(DataMatrix_xy) + "px"
                        }

                        # 1 - create DataMatrix (create a 2d list corresponding to the 1"s and 0s of the DataMatrix)
                        encoded = self.encode(self.options.target_url + "/" +
                                              sticker_id)
                        DataMatrixGroup = stickerGroup.add(
                            inkex.Group(
                                id="DataMatrix_Id" +
                                sticker_id))  #make a new group at root level
                        for x, y in self.render_data_matrix(
                                encoded, DataMatrix_xy):
                            DataMatrixAttribs.update({
                                "x":
                                str(x + sticker_padding),
                                "y":
                                str(y + sticker_padding)
                            })
                            etree.SubElement(DataMatrixGroup,
                                             inkex.addNS("rect", "svg"),
                                             DataMatrixAttribs)

                        inline_size = sticker_width - DataMatrix_width - 3 * sticker_padding  #remaining width for objects next to the DataMatrix
                        x_pos = DataMatrix_width + 2 * sticker_padding

                        # 2 - Add Object Name Text
                        objectName = etree.SubElement(
                            stickerGroup,
                            inkex.addNS("text", "svg"),
                            {
                                "font-size":
                                str(objectNameFontSize) + "px",
                                "x":
                                str(x_pos) + "px",
                                #"xml:space": "preserve", #we cannot add this here because InkScape throws an error
                                #"y": "4px", #if set it does not correctly apply
                                "text-align":
                                "left",
                                "text-anchor":
                                "left",
                                "vertical-align":
                                "bottom",
                                #style: inline-size required for text wrapping inside box; letter spacing is required to remove the additional whitespaces. The letter spacing depends to the selected font family (Miso)
                                "style":
                                str(
                                    inkex.Style(
                                        {
                                            "fill": "#000000",
                                            "inline-size":
                                            str(inline_size) + "px",
                                            "stroke": "none",
                                            "font-family": "Miso",
                                            "font-weight": "bold",
                                            "letter-spacing": "-3.66px"
                                        }))
                            })
                        objectName.set("id", "objectName_Id" + sticker_id)
                        objectName.set(
                            "xml:space", "preserve"
                        )  #so we add it here instead .. if multiple whitespaces in text are coming after each other just render them (preserve!)
                        objectNameTextSpan = etree.SubElement(
                            objectName, inkex.addNS("tspan", "svg"), {})
                        objectNameTextSpan.text = splitAt(
                            doc_title, 1
                        )  #add 1 whitespace after each chacter. So we can simulate a in-word line break (break by char instead by word)

                        # 3 - Add Object Id Text - use the same position but revert text anchors/align
                        objectId = etree.SubElement(
                            stickerGroup,
                            inkex.addNS("text", "svg"),
                            {
                                "font-size":
                                str(subline_fontsize) + "px",
                                "x":
                                str(sticker_padding) + "px",
                                "transform":
                                "translate(0," +
                                str(sticker_height - subline_fontsize) + ")",
                                "text-align":
                                "left",
                                "text-anchor":
                                "left",
                                "vertical-align":
                                "bottom",
                                "style":
                                str(
                                    inkex.Style(
                                        {
                                            "fill": "#000000",
                                            "inline-size":
                                            str(inline_size) + "px",
                                            "stroke": "none",
                                            "font-family": "Miso",
                                            "font-weight": "bold"
                                        })
                                )  #inline-size required for text wrapping
                            })
                        objectId.set("id", "objectId_Id" + sticker_id)
                        objectIdTextSpan = etree.SubElement(
                            objectId, inkex.addNS("tspan", "svg"), {})
                        objectIdTextSpan.text = "Thing #" + sticker_id

                        # 4 - Add Owner Text
                        owner = etree.SubElement(
                            stickerGroup,
                            inkex.addNS("text", "svg"),
                            {
                                "font-size":
                                str(subline_fontsize) + "px",
                                "x":
                                str(x_pos) + "px",
                                "transform":
                                "translate(0," +
                                str(sticker_height - subline_fontsize) + ")",
                                "text-align":
                                "right",
                                "text-anchor":
                                "right",
                                "vertical-align":
                                "bottom",
                                "style":
                                str(
                                    inkex.Style(
                                        {
                                            "fill": "#000000",
                                            "inline-size":
                                            str(inline_size) + "px",
                                            "stroke": "none",
                                            "font-family": "Miso",
                                            "font-weight": "300"
                                        })
                                )  #inline-size required for text wrapping
                            })
                        owner.set("id", "owner_Id" + sticker_id)
                        ownerTextSpan = etree.SubElement(
                            owner, inkex.addNS("tspan", "svg"), {})
                        ownerTextSpan.text = self.options.target_owner

                        # 5 - Add Level Text
                        levelText = etree.SubElement(
                            stickerGroup,
                            inkex.addNS("text", "svg"),
                            {
                                "font-size":
                                str(subline_fontsize) + "px",
                                "x":
                                str(x_pos) + "px",
                                "transform":
                                "translate(0," +
                                str(sticker_height - subline_fontsize -
                                    subline_fontsize) + ")",
                                "text-align":
                                "right",
                                "text-anchor":
                                "right",
                                "vertical-align":
                                "bottom",
                                "style":
                                str(
                                    inkex.Style(
                                        {
                                            "fill": "#000000",
                                            "inline-size":
                                            str(inline_size) + "px",
                                            "stroke": "none",
                                            "font-family": "Miso",
                                            "font-weight": "bold"
                                        })
                                )  #inline-size required for text wrapping
                            })
                        levelText.set("id", "level_Id" + sticker_id)
                        levelTextTextSpan = etree.SubElement(
                            levelText, inkex.addNS("tspan", "svg"), {})
                        levelTextTextSpan.text = level

                        # 6 - Add horizontal divider line
                        line_thickness = 2  #px
                        line_x_pos = 350  #px; start of the line (left coord)
                        line_length = sticker_width - line_x_pos
                        divider = etree.SubElement(
                            stickerGroup,
                            inkex.addNS("path", "svg"),
                            {
                                "d":
                                "m " + str(line_x_pos) + "," +
                                str(sticker_height - subline_fontsize -
                                    subline_fontsize) + " h " +
                                str(line_length),
                                "style":
                                str(
                                    inkex.Style(
                                        {
                                            "fill": "none",
                                            "stroke": "#000000",
                                            "stroke-width":
                                            str(line_thickness) + "px",
                                            "stroke-linecap": "butt",
                                            "stroke-linejoin": "miter",
                                            "stroke-opacity": "1"
                                        })
                                )  #inline-size required for text wrapping
                            })
                        divider.set("id", "divider_Id" + sticker_id)

                        if self.options.preview == False:
                            export_file_name = sticker_id + "_" + get_valid_filename(
                                doc_title)
                            export_file_path = os.path.join(
                                zoneDir, export_file_name)

                            #"Export" as SVG by just copying the recent SVG document to the target directory. We need to remove special characters to have valid file names on Windows/Linux
                            export_file_svg = open(export_file_path + ".svg",
                                                   "w",
                                                   encoding="utf-8")
                            export_file_svg.write(
                                str(etree.tostring(self.document), "utf-8"))
                            export_file_svg.close()

                            if self.options.export_png == False and self.options.export_svg == False:
                                inkex.errormsg(
                                    "Nothing to export. Generating preview only ..."
                                )
                                break

                            if self.options.export_png == True:  #we need to generate SVG before to get PNG. But if user selected PNG only we need to remove SVG afterwards
                                #Make PNG from SVG (slow because each file is picked up separately. Takes about 10 minutes for 600 files
                                inkscape(
                                    export_file_path + ".svg",
                                    actions=
                                    "export-dpi:96;export-background:white;export-filename:{file_name};export-do;FileClose"
                                    .format(file_name=export_file_path +
                                            ".png"))

                            #fix for "usb.core.USBError: [Errno 13] Access denied (insufficient permissions)"
                            #echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="04f9", ATTR{idProduct}=="2044", MODE="666"' > /etc/udev/rules.d/99-garmin.rules && sudo udevadm trigger
                            if self.options.print_png > 0:
                                if self.options.export_png == False:
                                    inkex.errormsg(
                                        "No file output for printing. Please set 'Export PNG' to true first."
                                    )
                                else:
                                    for x in range(self.options.print_png):
                                        command = "brother_ql -m QL-720NW --backend pyusb --printer usb://" + self.options.print_device + " print -l 62 --600dpi -r auto " + export_file_path + ".png"
                                        p = Popen(command,
                                                  shell=True,
                                                  stdout=PIPE,
                                                  stderr=PIPE
                                                  )  #forr Windows: shell=False
                                        stdout, stderr = p.communicate()
                                        p.wait()
                                        if p.returncode != 0:
                                            inkex.errormsg(
                                                "brother_ql returned: %d %s %s"
                                                %
                                                (p.returncode, stdout, stderr))

                            if self.options.export_svg != True:  #If user selected PNG only we need to remove SVG again
                                os.remove(export_file_path + ".svg")

                            self.document.getroot().remove(
                                stickerGroup)  #remove the stickerGroup again
                        else:  #create preview by just breaking the for loop without executing remove(stickerGroup)
                            break
                csv_file.close()
        except Exception as e:
            inkex.errormsg(e)
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

"""
# standard library
import random
# local library
import inkex
import simplestyle, simpletransform
import voronoi

try:
    from subprocess import Popen, PIPE
except:
    inkex.errormsg(
        _("Failed to import the subprocess module. Please report this as a bug at: https://bugs.launchpad.net/inkscape."
          ))
    inkex.errormsg(_("Python version is: ") + str(inkex.sys.version_info))
    exit()


def clip_line(x1, y1, x2, y2, w, h):
    if x1 < 0 and x2 < 0:
        return [0, 0, 0, 0]
    if x1 > w and x2 > w:
        return [0, 0, 0, 0]
    if x1 < 0:
        y1 = (y1 * x2 - y2 * x1) / (x2 - x1)
        x1 = 0
    if x2 < 0:
        y2 = (y1 * x2 - y2 * x1) / (x2 - x1)
Ejemplo n.º 60
0
def die(msg="Dying!"):
    inkex.errormsg(msg)
    sys.exit(0)