Esempio n. 1
0
def optimal_rotations(node):
    step = pi / float(STEPS)
    bbox = simpletransform.computeBBox([node])
    min_width = bbox[1] - bbox[0]
    min_width_angle = None
    min_bbox_area = min_width * (bbox[3] - bbox[2])
    min_bbox_area_angle = None

    for i in range(STEPS):
        angle = -pi / 2.0 + i * step
        rotated = simpletransform.computeBBox([node],
                                              rotate_matrix(node, angle))

        width = rotated[1] - rotated[0]
        height = rotated[3] - rotated[2]
        bbox_area = width * height

        if width < min_width:
            min_width = width
            min_width_angle = angle
        if bbox_area < min_bbox_area:
            if width > height:
                # To keep results similar to min_width_angle, rotate by an
                # additional 90 degrees which doesn't affect bbox area.
                angle -= copysign(pi / 2.0, angle)

            min_bbox_area = bbox_area
            min_bbox_area_angle = angle

    return min_width_angle, min_bbox_area_angle
Esempio n. 2
0
def linearizeEnvelopes(envs):
    bbox1 = simpletransform.computeBBox([envs[0]])
    bbox2 = simpletransform.computeBBox([envs[1]])
    
    comps1, lengths1 = linearize(modifySkeletonPath(cubicsuperpath.parsePath(envs[0].get('d'))))
    comps2, lengths2 = linearize(modifySkeletonPath(cubicsuperpath.parsePath(envs[1].get('d'))))
    
    correctness, shouldSwap = checkCompatibility(bbox1, bbox2, comps1, comps2)
    
    if not shouldSwap:
        return (comps1, lengths1, comps2, lengths2, bbox1, bbox2, correctness)
    else:
        return (comps2, lengths2, comps1, lengths1, bbox2, bbox1, correctness)
Esempio n. 3
0
def rotate_matrix(node, a):
    bbox = simpletransform.computeBBox([node])
    cx = (bbox[0] + bbox[1]) / 2.0
    cy = (bbox[2] + bbox[3]) / 2.0
    return simpletransform.composeTransform(
        [[cos(a), -sin(a), cx], [sin(a), cos(a), cy]],
        [[1, 0, -cx], [0, 1, -cy]])
    def parseArc(self,node,parent):

        #self.parsing_context = 'arc'

        style = node.get('style')
        style = self.parseStyleAttribute(style)

        arc = {
            'id':node.get('id',''),
            'svg':'arc',
            'label':str(node.get(inkex.addNS('label', 'inkscape'),'')),
            'cx': node.get(inkex.addNS('cx', 'sodipodi'),''),
            'cy':node.get(inkex.addNS('cy', 'sodipodi'),''),
            'rx':node.get(inkex.addNS('rx', 'sodipodi'),''),
            'ry':node.get(inkex.addNS('ry', 'sodipodi'),''),
            'path':simplepath.parsePath(node.get('d')),
            'd':node.get('d',''),
            'box':list(simpletransform.computeBBox([node])),
            'fill':style.get('fill',''),
            'fill-opacity':style.get('fillOpacity',''),
            'stroke':style.get('stroke',''),
            'stroke-width':style.get('strokeWidth',''),
            'stroke-opacity':style.get('strokeOpacity',''),
            'transform':node.get('transform','')
        }


        if(self.reposition):
            arc['path'] = self.movePath(node,0,0,'tl')
        else:
            arc['path'] = arc['d']

        parent.append(arc)
    def movePath(self, node, x, y, origin):
        tagName = self.getTagName(node)

        if tagName != "path":
            inkex.debug('movePath only works on SVG Path elements. Argument was of type "' + tagName + '"')
            return False

        path = simplepath.parsePath(node.get("d"))
        id = node.get("id")

        box = list(simpletransform.computeBBox([node]))

        offset_x = box[0] - x
        offset_y = box[2] - (y)

        for cmd in path:
            params = cmd[1]
            i = 0

            while i < len(params):
                if i % 2 == 0:
                    # inkex.debug('x point at ' + str( round( params[i] )))
                    params[i] = params[i] - offset_x
                    # inkex.debug('moved to ' + str( round( params[i] )))
                else:
                    # inkex.debug('y point at ' + str( round( params[i]) ))
                    params[i] = params[i] - offset_y
                    # inkex.debug('moved to ' + str( round( params[i] )))
                i = i + 1

        return simplepath.formatPath(path)
    def processSelected(self):
        """Iterate trough nodes and find the bounding coordinates of the selected area"""
        startx=None
        starty=None
        endx=None
        endy=None
        nodelist=[]

        root=self.document.getroot();

        toty=self.getUnittouu(root.attrib['height'])

        props=['x','y','width','height']

        for id in self.selected:

            if self.options.fast == "true":  # uses simpletransform

                nodelist.append(self.getElementById(id))

            else:  # uses command line
                rawprops=[]

                for prop in props:

                    command=("inkscape", "--without-gui", "--query-id", id, "--query-"+prop,self.args[-1])
                    proc=subprocess.Popen(command,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
                    proc.wait()
                    rawprops.append(math.ceil(self.getUnittouu(proc.stdout.read())))

                nodeEndX=rawprops[0]+rawprops[2]
                nodeStartY=toty-rawprops[1]-rawprops[3]
                nodeEndY=toty-rawprops[1]

                if rawprops[0] < startx or startx is None:
                    startx=rawprops[0]

                if nodeStartY < starty or starty is None:
                    starty = nodeStartY

                if nodeEndX > endx or endx is None:
                    endx = nodeEndX

                if nodeEndY > endy or endy is None:
                    endy = nodeEndY


        if self.options.fast == "true":  # uses simpletransform

            bbox=simpletransform.computeBBox(nodelist)

            startx=math.ceil(bbox[0])
            endx=math.ceil(bbox[1])
            h=-bbox[2]+bbox[3]
            starty=toty-math.ceil(bbox[2])-h
            endy=toty-math.ceil(bbox[2])

        coords=[startx,starty,endx,endy]
        return coords
Esempio n. 7
0
    def fill_row(self, node):
        max_line_width = self.unittouu('450mm')

        x_gap = y_gap = self.unittouu('10mm')
        x_start = self.unittouu('3mm')
        y_start = self.unittouu('1600mm') - self.unittouu('3mm')

        total_width = 0
        total_height = self.total_height

        group = etree.SubElement(self.current_layer, addNS('g', 'svg'))

        bbox = computeBBox([node])
        x, _, y, _ = bbox
        node_width = x_gap + self.width(bbox)

        while total_width + node_width < max_line_width:
            node_copy = deepcopy(node)
            group.append(node_copy)

            x_dest = x_start + total_width
            y_dest = y_start - (total_height + self.height(bbox))

            # translation logic
            if node_copy.tag == addNS('path', 'svg'):
                x_delta = x_dest - x
                y_delta = y_dest - y

                path = parsePath(node_copy.attrib['d'])
                translatePath(path, x_delta, y_delta)
                node_copy.attrib['d'] = formatPath(path)
            elif node_copy.tag == addNS('g', 'svg'):
                x_delta = x_dest - x
                y_delta = y_dest - y

                translation_matrix = [[1.0, 0.0, x_delta], [0.0, 1.0, y_delta]]
                applyTransformToNode(translation_matrix, node_copy)

            else:
                node_copy.attrib['x'] = str(x_dest)
                node_copy.attrib['y'] = str(y_dest)

            total_width += node_width

        self.total_height += self.height(computeBBox(group)) + y_gap
    def fill_row(self, node):
        max_line_width = self.unittouu('450mm')

        x_gap = y_gap = self.unittouu('10mm')
        x_start = self.unittouu('3mm')
        y_start = self.unittouu('1600mm') - self.unittouu('3mm')

        total_width = 0
        total_height = self.total_height

        group = etree.SubElement(self.current_layer, addNS('g','svg'))

        bbox = computeBBox([node])
        x, _, y, _ = bbox
        node_width = x_gap + self.width(bbox)

        while total_width + node_width < max_line_width:
            node_copy = deepcopy(node)
            group.append(node_copy)

            x_dest = x_start + total_width
            y_dest = y_start - (total_height + self.height(bbox))

            # translation logic
            if node_copy.tag == addNS('path','svg'):
                x_delta = x_dest - x
                y_delta = y_dest - y

                path = parsePath(node_copy.attrib['d'])
                translatePath(path, x_delta, y_delta)
                node_copy.attrib['d'] = formatPath(path)
            elif node_copy.tag == addNS('g','svg'):
                x_delta = x_dest - x
                y_delta = y_dest - y

                translation_matrix = [[1.0, 0.0, x_delta], [0.0, 1.0, y_delta]]
                applyTransformToNode(translation_matrix, node_copy)

            else:
                node_copy.attrib['x'] = str(x_dest)
                node_copy.attrib['y'] = str(y_dest)

            total_width += node_width

        self.total_height += self.height(computeBBox(group)) + y_gap
    def parseGroup(self,node,parent):
        #inkex.debug(self.debug_tab + 'Parsing group' + node.get('id'))
        self.debug_tab += '    '
        matrix_list = []
        self.parsing_context = 'g'
        transform = node.get('transform','')
        id = node.get('id')

        if(transform!=''):
            transform = simpletransform.parseTransform(node.get('transform',''))
            transform = self.matrixToList(transform)
            transform = self.normalizeMatrix(transform)

        label = str(node.get(inkex.addNS('label', 'inkscape'),''))

        elements = node.xpath('./*',namespaces=inkex.NSS)

        #box = simpletransform.computeBBox(elements)
        #box = list(box) if box != None else []

        box =list(simpletransform.computeBBox([node]))

        box[1] = (box[1]-box[0])
        box[3] = (box[3]-box[2])

        origin_x = float(node.get(inkex.addNS('transform-center-x', 'inkscape'),0))
        origin_y = float(node.get(inkex.addNS('transform-center-y', 'inkscape'),0))
        origin_x = origin_x + ( box[1] / 2)
        origin_y = (origin_y * -1) + ( box[3] / 2)

        group = {
            'id':id,
            'name':label,
            'label':label,
            'svg':'g',
            'transform':transform,
            'origin':{
                'x':origin_x,
                'y':origin_y,
            },
            'box':box,
            'elements':[]
        }

        parent.append(group)

        self.parse_stack.append(group)

        #inkex.debug('Loop through all grouped elements')

        for child in elements:
            self.parseElement(child,group["elements"])

        self.debug_tab = self.debug_tab[:-4]

        self.parsing_context = ''
        self.parse_stack.pop()
Esempio n. 10
0
    def effect(self):

        # if self.options.mformat == '"presets"':
        #     self.setPreset()

        # njj: hack some options
        # get number of digits
        # prec = int(self.options.precision)
        prec = 2
        self.options.fontsize = 20
        self.options.unit = 'mm'
        self.options.scale = 1
        self.options.angle = 0
        self.options.offset = -6

        scale = self.unittouu('1px')  # convert to document units
        # self.options.offset *= scale
        factor = 1.0
        doc = self.document.getroot()
        if doc.get('viewBox'):
            (viewx, viewy, vieww,
             viewh) = re.sub(' +|, +|,', ' ',
                             doc.get('viewBox')).strip().split(' ', 4)
            factor = self.unittouu(doc.get('width')) / float(vieww)
            if self.unittouu(doc.get('height')) / float(viewh) < factor:
                factor = self.unittouu(doc.get('height')) / float(viewh)
            factor /= self.unittouu('1px')
            self.options.fontsize /= factor
        factor *= scale / self.unittouu('1' + self.options.unit)

        # Gather paths
        debug(dir(self))
        paths = self.document.findall('.//{0}'.format(nspath))
        # Act on paths
        for node in paths:
            mat = simpletransform.composeParents(
                node, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
            p = cubicsuperpath.parsePath(node.get('d'))
            simpletransform.applyTransformToPath(mat, p)
            stotal = abs(measure.csparea(p) * factor * self.options.scale)
            self.group = inkex.etree.SubElement(node.getparent(),
                                                inkex.addNS('text', 'svg'))

            # Format the area as string
            resultstr = locale.format(
                "%(len)25." + str(prec) + "f", {
                    'len': round(stotal * factor * self.options.scale, prec)
                }).strip()
            # Fixed text, in the center of each path
            bbox = simpletransform.computeBBox([node])
            tx = bbox[0] + (bbox[1] - bbox[0]) / 2.0
            ty = bbox[2] + (bbox[3] - bbox[2]) / 2.0
            anchor = 'middle'
            self.addTextWithTspan(
                self.group, tx, ty, resultstr + ' ' + self.options.unit + '^2',
                id, anchor, -int(self.options.angle),
                -self.options.offset + self.options.fontsize / 2)
Esempio n. 11
0
 def effect(self):
     distance = self.unittouu(
         str(self.options.distance) + self.options.unit)
     if len(self.options.ids) != 2:
         print >> sys.stderr, "you must select exactly two objects"
         return
     id1 = self.options.ids[0]
     id2 = self.options.ids[1]
     b1 = simpletransform.computeBBox([
         self.selected[id1],
     ])
     b2 = simpletransform.computeBBox([
         self.selected[id2],
     ])
     if b1[2] > b2[2]:
         b1, b2 = (b2, b1)
         id1, id2 = (id2, id1)
     # id1,b1 is for the top element
     # id2,b2 is for the bottom element
     if self.options.top == 't':
         top = b1[2]
     else:
         top = b1[3]
     if self.options.bottom == 't':
         bottom = b2[2]
     else:
         bottom = b2[3]
     if self.options.moving == 't':
         moving = self.selected[id1]
         delta = (bottom - top) - distance
     else:
         moving = self.selected[id2]
         delta = -(bottom - top) + distance
     #print >>sys.stderr,distance,top,bottom,delta
     #print >>sys.stderr,self.selected,b1,b2,delta,distance
     # translate
     #print >>sys.stderr,self.selected[id2].attrib['transform']
     m = re.search('translate.*\([0-9-.]+,([0-9-.]+).*\)',
                   moving.attrib.get('transform', ''))
     #print >>sys.stderr,"match is:",m
     if m != None:
         delta = delta + float(m.group(1))
     #print >>sys.stderr,"delta is:",delta
     moving.attrib['transform'] = 'translate(0,' + str(delta) + ')'
Esempio n. 12
0
    def get_frame(self, mat=[[1,0,0],[0,1,0]]):
        """
        Determine the node's size and position. It's accounting for the coordinates of all paths in the node's children.

        :return: x position, y position, width, height
        """
        min_x, max_x, min_y, max_y = st.computeBBox([self._node], mat)
        width = max_x - min_x
        height = max_y - min_y
        return min_x, min_y, width, height
Esempio n. 13
0
    def effect(self):
        if len(self.options.ids)!=1:
            inkex.errormsg(_("This extension requires one selected path."))
            return
        self.prepareSelectionList()

        bbox=simpletransform.computeBBox(self.patterns.values())

        width=bbox[1]-bbox[0]
        dx=width+self.options.padding
        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)

                newp=[]
                for skelnode in self.skeletons.itervalues(): 
                    self.curSekeleton=cubicsuperpath.parsePath(skelnode.get('d'))
                    for comp in self.curSekeleton:
                        p=copy.deepcopy(p0)
                        self.skelcomp,self.lengths=linearize(comp)
                        self.skelcompIsClosed = (self.skelcomp[0]==self.skelcomp[-1])

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

                        NbCopies=max(1,int(round((length+self.options.padding)/dx)))
                        width=dx*NbCopies
                        if not self.skelcompIsClosed:
                            width-=self.options.padding
                        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)

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

                        newp+=p

                node.set('d', cubicsuperpath.formatPath(newp))

        for selected_element in self.selected.itervalues():
            self.remove(selected_element)
Esempio n. 14
0
 def effect(self):
     distance=self.unittouu(str(self.options.distance)+self.options.unit)
     if len(self.options.ids)!=2:
         print >>sys.stderr,"you must select exactly two objects"
         return
     id1=self.options.ids[0]
     id2=self.options.ids[1]
     b1=simpletransform.computeBBox([self.selected[id1],])
     b2=simpletransform.computeBBox([self.selected[id2],])        
     if b1[0]>b2[0]:
         b1,b2=(b2,b1)
         id1,id2=(id2,id1)
     # id1,b1 is for the left element
     # id2,b2 is for the right element
     if self.options.left=='l':
         left=b1[0]
     else:
         left=b1[1]
     if self.options.right=='l':
         right=b2[0]
     else:
         right=b2[1]
     # left is the reference coord for the left element
     # right ..............................right.......        
     if self.options.moving=='l':
         moving=self.selected[id1]
         delta=(right-left)-distance
     else:
         moving=self.selected[id2]
         delta=-(right-left)+distance
     #print >>sys.stderr,distance,left,right,delta         
     #print >>sys.stderr,self.selected,b1,b2,delta,distance
     # translate
     #print >>sys.stderr,self.selected[id2].attrib['transform']
     m=re.search('translate.*\(([0-9-.]+),.*',moving.attrib.get('transform',''))
     #print >>sys.stderr,"match is:",m
     if m!=None:
         delta=delta+float(m.group(1))
     #print >>sys.stderr,"delta is:",delta
     moving.attrib['transform']='translate('+str(delta)+',0)'
    def processSelected(self):
        """Iterate trough nodes and find the bounding coordinates of the selected area"""
        startx = None
        starty = None
        endx = None
        endy = None
        nodelist = []
        root = self.document.getroot()
        toty = self.getUnittouu(root.attrib['height'])
        scale = self.getUnittouu('1px')
        props = ['x', 'y', 'width', 'height']

        for id in self.selected:
            if self.options.fast == True:  # uses simpletransform
                nodelist.append(self.getElementById(id))
            else:  # uses command line
                rawprops = []
                for prop in props:
                    command = ("inkscape", "--without-gui", "--query-id", id,
                               "--query-" + prop, self.args[-1])
                    proc = subprocess.Popen(command,
                                            stdout=subprocess.PIPE,
                                            stderr=subprocess.PIPE)
                    proc.wait()
                    rawprops.append(
                        math.ceil(self.getUnittouu(proc.stdout.read())))
                nodeEndX = rawprops[0] + rawprops[2]
                nodeStartY = toty - rawprops[1] - rawprops[3]
                nodeEndY = toty - rawprops[1]

                if rawprops[0] < startx or startx is None:
                    startx = rawprops[0]

                if nodeStartY < starty or starty is None:
                    starty = nodeStartY

                if nodeEndX > endx or endx is None:
                    endx = nodeEndX

                if nodeEndY > endy or endy is None:
                    endy = nodeEndY

        if self.options.fast == True:  # uses simpletransform
            bbox = simpletransform.computeBBox(nodelist)
            startx = math.ceil(bbox[0])
            endx = math.ceil(bbox[1])
            h = -bbox[2] + bbox[3]
            starty = toty - math.ceil(bbox[2]) - h
            endy = toty - math.ceil(bbox[2])

        coords = [startx / scale, starty / scale, endx / scale, endy / scale]
        return coords
Esempio n. 16
0
    def effect(self):
        if len(self.options.ids) == 0:
            inkex.errormsg("Please select an object.")
            exit()

            # Collect document ids
        doc_ids = {}
        docIdNodes = self.document.xpath("//@id")
        for m in docIdNodes:
            doc_ids[m] = 1

        grpname = "axis"
        # Make sure that the id/name is inique
        index = 0
        while doc_ids.has_key(grpname):
            grpname = "axis" + str(index)
            index = index + 1

        grp_name = grpname
        grp_attribs = {inkex.addNS("label", "inkscape"): grp_name}
        # The group to put everything in
        grp = inkex.etree.SubElement(self.current_layer, "g", grp_attribs)

        # Get the bounding box
        bbox = simpletransform.computeBBox(self.selected.values())
        width = int(bbox[1] - bbox[0])
        height = int(bbox[3] - bbox[2])
        x_pos = bbox[0]
        y_pos = bbox[3]

        self.draw_axis(
            x_pos,
            y_pos,
            width,
            height,
            self.options.axis_from,
            self.options.axis_to,
            self.options.num_ticks,
            self.options.sub_ticks,
            self.options.axis_offset,
            self.options.decimals,
            self.options.text,
            self.options.text_font,
            self.options.text_size_axis,
            self.options.text_size_title,
            self.options.direction,
            grp,
        )
    def translateElement(self, node, x, y, relative=False):

        # Grab transform attribute if it exists.
        transform = node.get("transform", "")

        # Compute the nodes bounding box
        box = list(simpletransform.computeBBox([node]))

        pos_x = box[0]
        pos_y = box[2]

        # rotation center is not a breeze to calculate from the matrix, so thanks inkscape ;)
        origin_x = float(node.get(inkex.addNS("transform-center-x", "inkscape"), 0))
        origin_y = float(node.get(inkex.addNS("transform-center-y", "inkscape"), 0))
        origin_x = origin_x + (box[1] / 2)
        origin_y = (origin_y * -1) + (box[3] / 2)

        if transform == "":
            # If there is no transform attribute on the node we add one
            node.attrib["transform"] = ""

        # simpletransform returns a multi dim array of matrix values
        transform = simpletransform.parseTransform(transform)

        transformObject = self.normalizeMatrix(transform)
        inkex.debug(transformObject)
        # offset_x = (transform[0][2]-pos_x)
        # offset_y = (transform[1][2]-pos_y)
        offset_x = pos_x * -1
        offset_y = pos_y * -1

        inkex.debug([offset_x, offset_y])

        transform = simpletransform.parseTransform(
            ("translate(" + str(offset_x) + " " + str(offset_y) + ")"), transform
        )

        transformObject = self.normalizeMatrix(transform)
        inkex.debug(transformObject)

        inkex.debug(transform)

        if relative == False:
            matrix = simpletransform.formatTransform(transform)
            node.set("transform", matrix)
            inkex.debug(matrix)
        else:
            simpletransform.applyTransformToNode(transform, node)
Esempio n. 18
0
    def effect(self):
        """
        Apply the transformation. If an element already has a transformation
        attribute, it will be combined with the transformation matrix for the
        requested conversion.
        """

        if self.options.reverse == "true":
            conversion = "from_" + self.options.conversion
        else:
            conversion = "to_" + self.options.conversion

        if len(self.selected) == 0:
            inkex.errormsg(
                _("Please select an object to perform the " +
                  "isometric projection transformation on."))
            return

        # Default to the flat 2D to isometric top down view conversion if an
        # invalid identifier is passed.
        effect_matrix = self.transformations.get(
            conversion, self.transformations.get('to_top'))

        for id, node in self.selected.items():
            bbox = computeBBox([node])
            midpoint = self.getMidPoint(bbox, node)
            center_old = self.getTransformCenter(midpoint, node)
            transform = node.get("transform")
            # Combine our transformation matrix with any pre-existing
            # transform.
            matrix = parseTransform(transform, effect_matrix)

            # Compute the location of the transformation center after applying
            # the transformation matrix.
            center_new = center_old[:]
            applyTransformToPoint(matrix, center_new)
            applyTransformToPoint(matrix, midpoint)

            # Add a translation transformation that will move the object to
            # keep its transformation center in the same place.
            self.translateBetweenPoints(matrix, center_new, center_old)

            node.set('transform', formatTransform(matrix))

            # Adjust the transformation center.
            self.moveTransformationCenter(node, midpoint, center_new)
    def effect(self):
        """
        Apply the transformation. If an element already has a transformation
        attribute, it will be combined with the transformation matrix for the
        requested conversion.
        """

        if self.options.reverse == "true":
            conversion = "from_" + self.options.conversion
        else:
            conversion = "to_" + self.options.conversion

        if len(self.selected) == 0:
            inkex.errormsg(_("Please select an object to perform the " +
                             "isometric projection transformation on."))
            return

        # Default to the flat 2D to isometric top down view conversion if an
        # invalid identifier is passed.
        effect_matrix = self.transformations.get(
            conversion, self.transformations.get('to_top'))

        for id, node in self.selected.iteritems():
            bbox = computeBBox([node])
            midpoint = self.getMidPoint(bbox, node)
            center_old = self.getTransformCenter(midpoint, node)
            transform = node.get("transform")
            # Combine our transformation matrix with any pre-existing
            # transform.
            matrix = parseTransform(transform, effect_matrix)

            # Compute the location of the transformation center after applying
            # the transformation matrix.
            center_new = center_old[:]
            applyTransformToPoint(matrix, center_new)
            applyTransformToPoint(matrix, midpoint)

            # Add a translation transformation that will move the object to
            # keep its transformation center in the same place.
            self.translateBetweenPoints(matrix, center_new, center_old)

            node.set('transform', formatTransform(matrix))

            # Adjust the transformation center.
            self.moveTransformationCenter(node, midpoint, center_new)
Esempio n. 20
0
	def effect(self):
		if len(self.options.ids) == 0:
			inkex.errormsg("Please select an object.")
			exit()
			
		# Collect document ids
		doc_ids = {}
		docIdNodes = self.document.xpath('//@id')
		for m in docIdNodes:
			doc_ids[m] = 1

		grpname = 'axis'
		# Make sure that the id/name is inique
		index = 0
		while (doc_ids.has_key(grpname)):
			grpname = 'axis' + str(index)
			index = index + 1

		grp_name = grpname
		grp_attribs = {inkex.addNS('label','inkscape'):grp_name}
		# The group to put everything in
		grp = inkex.etree.SubElement(self.current_layer, 'g', grp_attribs)
		
		# Get the bounding box
		bbox = simpletransform.computeBBox(self.selected.values())
		width = int(bbox[1] - bbox[0])
		height = int(bbox[3] - bbox[2])
		x_pos = bbox[0]
		y_pos = bbox[3]

		self.draw_axis(x_pos, y_pos, width, height, 
				self.options.axis_from, self.options.axis_to, 
				self.options.num_ticks, self.options.sub_ticks, 
				self.options.axis_offset, self.options.decimals,
				self.options.text, self.options.text_font,
				self.options.text_size_axis, self.options.text_size_title,
				self.options.direction, grp)
Esempio n. 21
0
 def effect(self):
     if len(self.options.ids) != 2:
         inkex.errormsg(_("This extension requires two selected paths."))
         return
     
     self.prepareSelectionList()
     envs = self.envelopes.values()
     
     s = envs[0].get('style')
     parent = envs[0].getparent()
     
     fstEnvComps, fstEnvLengths, sndEnvComps, sndEnvLengths, fstEnvBbox, sndEnvBbox, isCorrect = linearizeEnvelopes(envs)
     
     if not isCorrect:
         inkex.errormsg(_("Selected paths are not compatible."))
         return
     
     areNested = isSkeletonClosed(fstEnvComps) and isSkeletonClosed(sndEnvComps)
     
     self.skelComp = None
     self.lengths = None
     
     countOfSkelPaths = 1
     distBetweenFirstPts = 1
     funcSeries = self.options.series
     
     isLine = True if self.options.patternFunction == 'line' else False
     
     if (isLine and self.options.offset > 0):
         distBetweenFirstPts = getDistBetweenFirstPts(fstEnvComps, sndEnvComps, fstEnvBbox, sndEnvBbox, areNested)
         countOfSkelPaths = int(distBetweenFirstPts / self.options.offset)
         funcSeries = 1
     
     for cnt in range(0, countOfSkelPaths):
         curOffset = (cnt + 1) * self.options.offset / distBetweenFirstPts
         
         if areNested:
             self.skelComp, self.lengths = getClosedLinearizedSkeletonPath(fstEnvComps, sndEnvComps, curOffset, isLine)
         elif (fstEnvBbox[0] == sndEnvBbox[0] and fstEnvBbox[1] == sndEnvBbox[1]):
             self.skelComp, self.lengths = getHorizontalLinearizedSkeletonPath(fstEnvComps, sndEnvComps, curOffset, isLine)
         elif (fstEnvBbox[2] == sndEnvBbox[2] and fstEnvBbox[3] == sndEnvBbox[3]):
             self.skelComp, self.lengths = getVerticalLinearizedSkeletonPath(fstEnvComps, sndEnvComps, curOffset, isLine)
         
         self.skelCompIsClosed = isSkeletonClosed(self.skelComp)
         length = sum(self.lengths)
         patternWidth = length / self.options.frequency
         funcOffsetStep = 100 / funcSeries
         
         resPath = ''
         
         pattern = inkex.etree.Element(inkex.addNS('path','svg'))
         
         self.options.strokeHexColor, self.strokeOpacity = getColorAndOpacity(self.options.strokeColor)
         
         if s:
             pattern.set('style', setColorAndOpacity(s, self.options.strokeHexColor, self.strokeOpacity))
         
         for j in range(funcSeries):
             selectedFunction = self.getFunction(self.options.patternFunction, j * funcOffsetStep)
             
             pattern.set('d', simplepath.formatPath(drawfunction(self.options.nodes, patternWidth, selectedFunction)))
             
             # Add path into SVG structure
             parent.append(pattern)
             
             # Compute bounding box
             bbox = simpletransform.computeBBox([pattern])
             
             width = bbox[1] - bbox[0]
             height = bbox[3] - bbox[2]
             dx = width
             
             if dx < 0.01:
                 exit(_("The total length of the pattern is too small."))
             
             patternPath = cubicsuperpath.parsePath(pattern.get('d'))
             curPath = deepcopy(patternPath)
             
             xoffset = self.skelComp[0][0] - bbox[0]
             yoffset = self.skelComp[0][1] - (bbox[2] + bbox[3]) / 2
             
             patternCopies = max(1, int(round(length / dx)))
             width = dx * patternCopies
             
             newPath = []
             
             # Repeat pattern to cover whole skeleton
             for subPath in curPath:
                 for i in range(0, patternCopies, 1):
                     newPath.append(deepcopy(subPath))
                     offset(subPath, dx, 0)
             
             # Offset pattern to the first node of the skeleton
             for subPath in newPath:
                 offset(subPath, xoffset, yoffset)
             
             curPath = deepcopy(newPath)
             
             # Stretch pattern to whole skeleton
             for subPath in curPath:
                 stretch(subPath, length / width, 1, self.skelComp[0])
             
             for subPath in curPath:
                 for ctlpt in subPath:
                     self.applyDiffeo(ctlpt[1], (ctlpt[0], ctlpt[2]))
             
             # Check if there is a need to close path manually
             if self.skelCompIsClosed:
                 firstPtX = round(curPath[0][0][1][0], 8)
                 firstPtY = round(curPath[0][0][1][1], 8)
                 finalPtX = round(curPath[-1][-1][1][0], 8)
                 finalPtY = round(curPath[-1][-1][1][1], 8)
                 
                 if (firstPtX != finalPtX or firstPtY != finalPtY):
                     curPath[-1].append(curPath[0][0])
             
             curPathComps, curPathLengths = linearize(modifySkeletonPath(curPath))
             
             if not isLine:
                 curPathComps = stretchComps(self.skelComp, curPathComps, fstEnvComps, sndEnvComps, fstEnvBbox, sndEnvBbox, areNested, height / 2, self.options.amplitude / 100.0, self.options.offset)
             
             resPath += compsToSVGd(curPathComps)
         
         pattern.set('d', resPath)
     
     if self.options.remove:
         parent.remove(envs[0])
         parent.remove(envs[1])
Esempio n. 22
0
    def effect(self):
        thickness = self.unittouu(
            str(self.options.thickness) + self.options.unit)
        height = self.unittouu(str(self.options.height) + self.options.unit)
        iheight = self.unittouu(str(self.options.iheight) + self.options.unit)
        if len(self.options.ids) != 1:
            print >> sys.stderr, "you must select exactly one object"
            return
        id = self.options.ids[0]
        node = self.selected[id]  # Element
        (xmin, xmax, ymin, ymax) = simpletransform.computeBBox([node])  # Tuple
        width = xmax - xmin
        depth = ymax - ymin
        nodes = []
        if (node.tag == inkex.addNS('path', 'svg')):
            nodes = [simplepath.parsePath(node.get('d'))]
        if (node.tag == inkex.addNS('g', 'svg')):
            nodes = []
            for n in node.getchildren():
                if (n.tag == inkex.addNS('rect', 'svg')):
                    x = float(n.get('x'))
                    y = float(n.get('y'))
                    h = float(n.get('height'))
                    w = float(n.get('width'))
                    nodes.append([['M', [x, y]], ['L', [x + w, y]],
                                  ['L', [x + w, y + h]], ['L', [x, y + h]]])
                else:
                    nodes.append(simplepath.parsePath(n.get('d')))

        # inkex.debug(nodes)
        if (nodes == []):
            print >> sys.stderr, "selected object must be a path or a group of paths"
            return

        # Create main SVG element
        tr = 'translate(' + str(xmin + thickness) + ',' + str(ymax -
                                                              thickness) + ')'
        g_attribs = {
            inkex.addNS('label', 'inkscape'): 'Boxify' + str(width) + \
            "x" + str(height) , 'transform': tr }
        g = inkex.etree.SubElement(self.current_layer, 'g', g_attribs)

        # Create SVG Path for plate
        style = formatStyle({ 'stroke': '#000000', \
                              'fill': 'none', \
                              'stroke-width': str(self.unittouu('1px')) })

        # Create main box
        vdivs = max(int(height / (2 * thickness)) - 1, 1)
        lc.insert_box(g, (width, depth, height), (int(
            width / (2 * thickness)), int(depth / (2 * thickness)), vdivs),
                      thickness, False, False, style)

        # Insert remaining edges
        # inkex.debug(nodes)
        edges = lc.decompose(nodes)

        # Position border edges (*after* having translated)
        e = edges.pop(0)
        e.position((xmax - xmin - thickness, 0), 'w')
        e = edges.pop(0)
        e.position((-thickness, ymin - ymax + 2 * thickness), 'e')
        e = edges.pop(0)
        e.position((xmax - xmin - 2 * thickness, ymin - ymax + thickness), 's')
        e = edges.pop(0)
        e.position((0, thickness), 'n')

        # Handle remaining edges
        numedges = 0
        for e in edges:
            # inkex.debug("==========================")
            # inkex.debug(str(e) + "\n")
            # style = formatStyle({ 'stroke': "#%06x" % random.randint(0, 0xFFFFFF), \
            #                       'fill': 'none', \
            #                       'stroke-width': str(self.unittouu('3px')) })
            numedges += 1

            # Determine edge direction in the main plate
            dir = e.getdir()

            # Middle holes
            leng = e.getlen()
            for (f, df) in e.touch:
                if not (f.bnd):
                    leng += thickness / 2

            num = int((leng - 2 * thickness) / (2 * thickness))

            if (dir == 's') or (dir == 'n'):  # Vertical edge
                dims = (thickness, (leng - 2 * thickness) / (2 * num + 1))
                if (dir == 's'):
                    st = (e.p_from[0] - xmin - thickness,
                          e.p_from[1] - ymax - dims[1] / 2 + thickness)
                else:
                    st = (e.p_from[0] - xmin - thickness,
                          e.p_from[1] - ymax + 2 * thickness + dims[1] / 2)
                if not ((abs(e.p_from[1] - ymin) < 0.1) or
                        (abs(e.p_from[1] - ymax) <
                         0.1)):  # Is the start point on the border ?
                    st = (st[0], st[1] - thickness / 2)
                else:
                    st = (st[0], st[1])
            else:  # Horizontal edge
                dims = ((leng - 2 * thickness) / (2 * num + 1), thickness)
                if (dir == 'e'):
                    st = (e.p_from[0] - xmin + dims[0] / 2,
                          e.p_from[1] - ymax + thickness)
                else:
                    st = (e.p_from[0] - xmin - 2 * thickness - dims[0] / 2,
                          e.p_from[1] - ymax + thickness)
                if not ((abs(e.p_from[0] - xmin) < 0.1) or
                        (abs(e.p_from[0] - xmax) <
                         0.1)):  # Is the start point on the border ?
                    if (dir == 'e'):
                        st = (st[0] - thickness / 2, st[1])
                    else:
                        st = (st[0] + thickness / 2, st[1])

            lc.insert_holes(g, st, dims, num + 1, dir, style)

            # Do we need to split the joins of the edge ?
            tm_from = 0
            tm_to = 0
            for (f, df) in e.touch:
                tm_from += len(
                    filter((lambda q: ((q[0] - e.p_from[0])**2 +
                                       (q[1] - e.p_from[1]))**2 < 0.1),
                           f.attch))
                tm_to += len(
                    filter((lambda q: ((q[0] - e.p_to[0])**2 +
                                       (q[1] - e.p_to[1]))**2 < 0.1), f.attch))

            vdivs = max(int((height - iheight) / (2 * thickness)) - 1, 1)
            points = lc.make_plate(
                (height - thickness - iheight, leng), (True, False), thickness,
                vdivs, num, 'm' if tm_to <= 1 else
                ('x' if (e.getdir() == 'w') or (e.getdir() == 'n') else 'w'),
                False, 'm' if tm_from <= 1 else
                ('x' if (e.getdir() == 'w') or (e.getdir() == 'n') else 'w'),
                False, '-', False, 'f', True)
            (dpx, dpy) = (xmax - xmin - 2 * thickness + numedges *
                          (height - iheight) + iheight, 0)
            points = lc.translate_points(points, dpx, dpy)
            lc.insert_path(g, points, style)
            e.position((xmax - xmin + (height - iheight) *
                        (numedges + 1) + iheight - 2 * thickness, thickness),
                       'n')

            # Left parts
            for (f, df) in e.touch:
                # inkex.debug("Touch " + str(f) + " -- DIST= " + str(df) + "\n")

                vdir = lc.rotatedir(f.dir)
                if (vdir == 's') or (vdir == 'n'):
                    xdim = thickness
                    ydim = (height - iheight - thickness) / (2 * vdivs + 1.)
                    dyf = -2 * thickness - 3 * ydim / 2 if vdir == 'n' else +3 * ydim / 2
                    df = 1 - df
                    stf = (f.r_from[0] + df * (f.r_to[0] - f.r_from[0]),
                           f.r_from[1] + df * (f.r_to[1] - f.r_from[1]) +
                           thickness + dyf)
                    vdir = 's' if vdir == 'n' else 'n'
                else:
                    ydim = thickness
                    xdim = (height - iheight - thickness) / (2 * vdivs + 1.)
                    df = 1 - df
                    dxf = 2 * thickness + 3 * xdim / 2 if vdir == 'e' else -3 * xdim / 2
                    stf = (f.r_from[0] + df * (f.r_to[0] - f.r_from[0]) -
                           thickness + dxf,
                           f.r_from[1] + df * (f.r_to[1] - f.r_from[1]))

                lc.insert_holes(g, stf, (xdim, ydim), vdivs, vdir, style)
    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

        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:
                            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))
Esempio n. 24
0
    def effect(self):

        if len(self.options.ids) < 1 and len(self.options.ids) > 1:
            inkex.errormsg(
                _("This extension requires only one selected paths."))
            return

#liste des chemins, preparation
        idList = self.options.ids
        idList = pathmodifier.zSort(self.document.getroot(), idList)
        id = idList[-1]
        idpoint = id + '-' + str(random.randint(
            1, 99))  #id du paterns creer a partir du chemin selectionner

        for id, node in self.selected.iteritems():
            style = simplestyle.parseStyle(
                node.get('style'))  #je recupere l'ancien style
            style['stroke'] = '#00ff00'  #je modifie la valeur
            node.set('style',
                     simplestyle.formatStyle(style))  #j'applique la modifi

        #gestion du skelte (le chemin selectionner)
        self.skeletons = self.selected
        self.expandGroupsUnlinkClones(self.skeletons, True, False)
        self.objectsToPaths(self.skeletons)

        for skelnode in self.skeletons.itervalues(
        ):  #calcul de la longeur du chemin
            self.curSekeleton = cubicsuperpath.parsePath(skelnode.get('d'))
            for comp in self.curSekeleton:
                self.skelcomp, self.lengths = linearize(comp)
                longeur = sum(self.lengths)

        distance = self.unittouu(self.options.space)
        taille = self.unittouu(self.options.diamlong)

        if self.options.autoRepeat:  #gestion du calcul auto
            nbrRepeat = int(round((longeur) / distance))
        else:
            nbrRepeat = self.options.nrepeat

        if self.options.autoOffset:  #gestion du decallage automatique
            tOffset = ((longeur - (nbrRepeat - 1) * distance) / 2) - taille / 2
        else:
            tOffset = self.unittouu(self.options.toffset)

        #gestion du paterns
        labelpoint = 'Point:' + self.options.diamlong + ' Ecart:' + self.options.space + ' Decallage:' + str(
            round(self.uutounit(tOffset, 'mm'),
                  2)) + 'mm' + ' Nbr:' + str(nbrRepeat) + ' longueur:' + str(
                      round(self.uutounit(longeur, 'mm'), 2)) + 'mm'
        addDot(self, idpoint, labelpoint, self.options.diamlong,
               self.options.typePoint)  #creation du cercle de base
        self.patterns = {
            idpoint: self.getElementById(idpoint)
        }  #ajout du point dans le paterns de base

        bbox = simpletransform.computeBBox(self.patterns.values())
        #liste des chemins, fin de preparation

        if distance < 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)
                newp = []
                for skelnode in self.skeletons.itervalues():
                    self.curSekeleton = cubicsuperpath.parsePath(
                        skelnode.get('d'))
                    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] + tOffset
                        yoffset = self.skelcomp[0][1] - (bbox[2] + bbox[3]) / 2
                        if self.options.textInfos:
                            addText(self, xoffset, yoffset, labelpoint)
                        MaxCopies = max(
                            1, int(round((length + distance) / distance)))
                        NbCopies = nbrRepeat  #nombre de copie desirer a intergrer dans les choix a modifier pour ne pas depasser les valeurs maxi
                        if NbCopies > MaxCopies:
                            NbCopies = MaxCopies  #on limitte le nombre de copie au maxi possible sur le chemin
                        width = distance * NbCopies
                        if not self.skelcompIsClosed:
                            width -= distance

                        new = []
                        for sub in p:  #creation du nombre de patern
                            for i in range(0, NbCopies, 1):
                                new.append(
                                    copy.deepcopy(sub)
                                )  #realise une copie de sub pour chaque nouveau element du patern
                                offset(sub, distance, 0)
                        p = new
                        for sub in p:
                            offset(sub, xoffset, yoffset)
                        for sub in p:  #une fois tous creer, on les mets en place
                            for ctlpt in sub:  #pose le patern sur le chemin
                                self.applyDiffeo(ctlpt[1],
                                                 (ctlpt[0], ctlpt[2]))

                        newp += p

                node.set('d', cubicsuperpath.formatPath(newp))
Esempio n. 25
0
    def _process_bbox(self):
        left, right, top, bottom = simpletransform.computeBBox(self.node.iterdescendants())

        self.width = right - left
        self._min_x = left
Esempio n. 26
0
    def effect(self):

        if len(self.options.ids) < 1 and len(self.options.ids) > 1:
            inkex.errormsg("This extension requires only one selected paths.")
            return
        #liste des chemins, preparation
        idList = self.options.ids
        idList = pathmodifier.zSort(self.document.getroot(), idList)
        id = idList[-1]
        idpoint = id + '-' + str(random.randint(
            1, 99))  #id du paterns creer a partir du chemin selectionner
        idpointMark = id + '-' + str(random.randint(1, 99))

        for id, node in self.selected.iteritems():
            if node.tag == inkex.addNS('path', 'svg'):
                style = simplestyle.parseStyle(
                    node.get('style'))  #je recupere l'ancien style
                style['stroke'] = '#00ff00'  #je modifie la valeur
                if self.options.autoMask == True:
                    style['display'] = 'none'
                node.set('style',
                         simplestyle.formatStyle(style))  #j'applique la modifi

                #gestion du skelete (le chemin selectionner)
                self.skeletons = self.selected
                self.expandGroupsUnlinkClones(self.skeletons, True, False)
                self.objectsToPaths(self.skeletons)

                for skelnode in self.skeletons.itervalues(
                ):  #calcul de la longeur du chemin
                    self.curSekeleton = cubicsuperpath.parsePath(
                        skelnode.get('d'))
                    for comp in self.curSekeleton:
                        self.skelcomp, self.lengths = linearize(comp)
                        longeur = sum(self.lengths)

                distance = self.unittouu(self.options.space)
                taille = self.unittouu(self.options.diamlong)
                MaxCopies = max(1, int(round((longeur + distance) / distance)))

                NbCopies = self.options.nrepeat  #nombre de copie desirer a integrer dans les choix a modifier pour ne pas depasser les valeurs maxi

                if NbCopies > MaxCopies:
                    NbCopies = MaxCopies  #on limitte le nombre de copie au maxi possible sur le chemin

                if self.options.autoRepeat:  #gestion du calcul auto
                    NbCopies = MaxCopies

                if self.options.autoOffset:  #gestion du decallage automatique
                    tOffset = ((longeur -
                                (NbCopies - 1) * distance) / 2) - taille / 2
                else:
                    tOffset = self.unittouu(self.options.toffset)

                #gestion du paterns
                labelpoint = 'Point: ' + idpoint + ' Nbr:' + str(
                    NbCopies) + ' longueur:' + str(
                        round(self.uutounit(longeur, 'mm'), 2)) + 'mm'
                addDot(self, idpoint, labelpoint, self.options.diamlong,
                       self.options.typePoint, 0)  #creation du cercle de base
                self.patterns = {
                    idpoint: self.getElementById(idpoint)
                }  #ajout du point dans le paterns de base

                bbox = simpletransform.computeBBox(self.patterns.values())
                #liste des chemins, fin de preparation

                if distance < 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)
                        newp = []
                        for skelnode in self.skeletons.itervalues():
                            self.curSekeleton = cubicsuperpath.parsePath(
                                skelnode.get('d'))
                            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])

                                xoffset = self.skelcomp[0][0] - bbox[
                                    0] + tOffset
                                yoffset = self.skelcomp[0][1] - (bbox[2] +
                                                                 bbox[3]) / 2
                                if self.options.textInfos:
                                    addText(self, xoffset, yoffset, labelpoint)
                                width = distance * NbCopies
                                if not self.skelcompIsClosed:
                                    width -= distance

                                new = []
                                for sub in p:  #creation du nombre de patern
                                    for i in range(0, NbCopies, 1):
                                        new.append(
                                            copy.deepcopy(sub)
                                        )  #realise une copie de sub pour chaque nouveau element du patern
                                        offset(sub, distance, 0)
                                p = new
                                for sub in p:
                                    offset(sub, xoffset, yoffset)
                                for sub in p:  #une fois tous creer, on les mets en place
                                    for ctlpt in sub:  #pose le patern sur le chemin
                                        self.applyDiffeo(
                                            ctlpt[1], (ctlpt[0], ctlpt[2]))

                                newp += p

                        node.set('d', cubicsuperpath.formatPath(newp))
                    else:
                        inkex.errormsg(
                            "This extension need a path, not groups.")

        if self.options.autoMark:
            if self.options.typeMark == "markFraction":
                Fraction = self.options.nrepeat2  #en mode fraction 1= au debut et a la fin, 2= un demi, 3= 1/3 etc
                distance = (width) / Fraction  #distance inter point
                NbrMark = max(1, int(round((width + distance) / distance)))
                infos = " Marquage 1/" + str(Fraction)
                couleur = '#ff0000'
            else:
                Repeat = self.options.nrepeat2  #en mode fraction 1= au debut et a la fin, 2= un demi, 3= 1/3 etc
                NbrMark = max(1, int(round((NbCopies / Repeat))))
                distance = distance * Repeat  #distance inter point
                infos = " Marquage tous les " + str(Repeat) + " points"
                couleur = '#ffaa00'

            labelMark = "Mark: " + idpoint + infos
            addMark(self, 0, 0, idpointMark, labelMark, self.options.diamlong,
                    couleur)
            self.patternsMark = {
                idpointMark: self.getElementById(idpointMark)
            }  #ajout du point dans le paterns de base

            bbox = simpletransform.computeBBox(self.patternsMark.values())
            #liste des chemins, fin de preparation
            if distance < 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.patternsMark.iteritems():

                if node.tag == inkex.addNS('path',
                                           'svg') or node.tag == 'path':
                    d = node.get('d')
                    p0 = cubicsuperpath.parsePath(d)
                    newp = []
                    for skelnode in self.skeletons.itervalues():
                        self.curSekeleton = cubicsuperpath.parsePath(
                            skelnode.get('d'))
                        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])
                            # a tester si les point au dessus sont utilisable pour positionner les autres a upoi ressemble skelcomp ??
                            xoffset = self.skelcomp[0][0] - bbox[
                                0] + tOffset + taille / 2
                            yoffset = self.skelcomp[0][1] - (bbox[2] +
                                                             bbox[3]) / 2

                            width = distance * NbrMark
                            if not self.skelcompIsClosed:
                                width -= distance

                            new = []
                            for sub in p:  #creation du nombre de patern
                                for i in range(0, NbrMark, 1):
                                    new.append(
                                        copy.deepcopy(sub)
                                    )  #realise une copie de sub pour chaque nouveau element du patern
                                    offset(sub, distance, 0)
                            p = new
                            for sub in p:
                                offset(sub, xoffset, yoffset)
                            for sub in p:  #une fois tous creer, on les mets en place
                                for ctlpt in sub:  #pose le patern sur le chemin
                                    self.applyDiffeo(ctlpt[1],
                                                     (ctlpt[0], ctlpt[2]))

                            newp += p

                    node.set('d', cubicsuperpath.formatPath(newp))
                else:
                    inkex.errormsg("This extension need a path, not groups.")
Esempio n. 27
0
    def effect(self):
        thickness=self.unittouu(str(self.options.thickness)+self.options.unit)
        height=self.unittouu(str(self.options.height)+self.options.unit)
        iheight=self.unittouu(str(self.options.iheight)+self.options.unit)
        if len(self.options.ids)!=1:
            print >> sys.stderr,"you must select exactly one object"
            return
        id=self.options.ids[0]
        node=self.selected[id]                   # Element
        (xmin,xmax,ymin,ymax)=simpletransform.computeBBox([node]) # Tuple
        width=xmax-xmin
        depth=ymax-ymin
        nodes=[]
        if (node.tag == inkex.addNS('path','svg')):
            nodes = [simplepath.parsePath(node.get('d'))]
        if (node.tag == inkex.addNS('g','svg')):
            nodes = []
            for n in node.getchildren():
                if (n.tag == inkex.addNS('rect','svg')):
                    x = float(n.get('x'))
                    y = float(n.get('y'))
                    h = float(n.get('height'))
                    w = float(n.get('width'))
                    nodes.append([['M', [x,y]],['L', [x+w,y]],['L', [x+w,y+h]],['L', [x,y+h]]])
                else:
                    nodes.append(simplepath.parsePath(n.get('d')))

        # inkex.debug(nodes)
        if (nodes == []):
            print >> sys.stderr,"selected object must be a path or a group of paths"
            return

        # Create main SVG element
        tr= 'translate(' + str(xmin+thickness) + ',' + str(ymax-thickness) + ')'
        g_attribs = {
            inkex.addNS('label', 'inkscape'): 'Boxify' + str(width) + \
            "x" + str(height) , 'transform': tr }
        g = inkex.etree.SubElement(self.current_layer, 'g', g_attribs)

        # Create SVG Path for plate
        style = formatStyle({ 'stroke': '#000000', \
                              'fill': 'none', \
                              'stroke-width': str(self.unittouu('1px')) })

        # Create main box
        vdivs = max(int(height/(2*thickness))-1,1)
        lc.insert_box(g,
                      (width, depth, height),
                      (int(width/(2*thickness)),
                       int(depth/(2*thickness)),
                       vdivs),
                      thickness, False, False, style)

        # Insert remaining edges
        # inkex.debug(nodes)
        edges = lc.decompose(nodes)

        # Position border edges (*after* having translated)
        e = edges.pop(0);
        e.position((xmax-xmin-thickness,0),'w')
        e = edges.pop(0);
        e.position((-thickness,ymin-ymax+2*thickness),'e')
        e = edges.pop(0);
        e.position((xmax-xmin-2*thickness,ymin-ymax+thickness),'s')
        e = edges.pop(0);
        e.position((0,thickness),'n')

        # Handle remaining edges
        numedges = 0
        for e in edges:
            # inkex.debug("==========================")
            # inkex.debug(str(e) + "\n")
            # style = formatStyle({ 'stroke': "#%06x" % random.randint(0, 0xFFFFFF), \
            #                       'fill': 'none', \
            #                       'stroke-width': str(self.unittouu('3px')) })
            numedges += 1

            # Determine edge direction in the main plate
            dir = e.getdir()

            # Middle holes
            leng = e.getlen()
            for (f,df) in e.touch:
                if not(f.bnd):
                    leng += thickness/2

            num  = int((leng-2*thickness)/(2*thickness))

            if (dir == 's') or (dir == 'n'): # Vertical edge
                dims = (thickness,(leng-2*thickness)/(2*num+1))
                if (dir == 's'):
                    st = (e.p_from[0]-xmin-thickness,
                          e.p_from[1]-ymax-dims[1]/2+thickness)
                else:
                    st = (e.p_from[0]-xmin-thickness,
                          e.p_from[1]-ymax+2*thickness+dims[1]/2)
                if not((abs(e.p_from[1]-ymin) < 0.1) or
                       (abs(e.p_from[1]-ymax) < 0.1)): # Is the start point on the border ?
                    st = (st[0],st[1]-thickness/2)
                else:
                    st = (st[0],st[1])
            else: # Horizontal edge
                dims = ((leng-2*thickness)/(2*num+1),thickness)
                if (dir == 'e'):
                    st = (e.p_from[0]-xmin+dims[0]/2,
                          e.p_from[1]-ymax+thickness)
                else:
                    st = (e.p_from[0]-xmin-2*thickness-dims[0]/2,
                          e.p_from[1]-ymax+thickness)
                if not((abs(e.p_from[0]-xmin) < 0.1) or
                       (abs(e.p_from[0]-xmax) < 0.1)): # Is the start point on the border ?
                    if (dir == 'e'):
                        st = (st[0]-thickness/2,st[1])
                    else:
                        st = (st[0]+thickness/2,st[1])

            lc.insert_holes(g, st, dims, num+1, dir, style)

            # Do we need to split the joins of the edge ?
            tm_from = 0; tm_to = 0
            for (f,df) in e.touch:
                tm_from += len(filter ((lambda q: ((q[0]-e.p_from[0])**2+(q[1]-e.p_from[1]))**2 < 0.1), f.attch))
                tm_to   += len(filter ((lambda q: ((q[0]-e.p_to[0])**2+(q[1]-e.p_to[1]))**2 < 0.1), f.attch))

            vdivs = max(int((height-iheight)/(2*thickness))-1,1)
            points=lc.make_plate((height-thickness-iheight,leng),(True,False),
                              thickness,vdivs,num,
                              'm' if tm_to   <= 1 else ('x' if (e.getdir() == 'w') or (e.getdir() == 'n') else 'w'),False,
                              'm' if tm_from <= 1 else ('x' if (e.getdir() == 'w') or (e.getdir() == 'n') else 'w'),False,
                              '-',False,
                              'f',True)
            (dpx,dpy) = (xmax-xmin-2*thickness+numedges*(height-iheight)+iheight,0)
            points = lc.translate_points(points,dpx,dpy)
            lc.insert_path(g, points, style)
            e.position((xmax-xmin+(height-iheight)*(numedges+1)+iheight-2*thickness,
                        thickness), 'n')

            # Left parts
            for (f,df) in e.touch:
                # inkex.debug("Touch " + str(f) + " -- DIST= " + str(df) + "\n")

                vdir = lc.rotatedir(f.dir)
                if (vdir == 's') or (vdir == 'n'):
                    xdim = thickness
                    ydim = (height-iheight-thickness)/(2*vdivs+1.)
                    dyf  = -2*thickness-3*ydim/2 if vdir == 'n' else +3*ydim/2
                    df   = 1-df
                    stf  = (f.r_from[0]+df*(f.r_to[0]-f.r_from[0]),
                            f.r_from[1]+df*(f.r_to[1]-f.r_from[1])+thickness+dyf)
                    vdir = 's' if vdir == 'n' else 'n'
                else:
                    ydim = thickness
                    xdim = (height-iheight-thickness)/(2*vdivs+1.)
                    df   = 1-df
                    dxf  = 2*thickness+3*xdim/2 if vdir == 'e' else -3*xdim/2
                    stf  = (f.r_from[0]+df*(f.r_to[0]-f.r_from[0])-thickness+dxf,
                            f.r_from[1]+df*(f.r_to[1]-f.r_from[1]))

                lc.insert_holes(g, stf, (xdim,ydim), vdivs, vdir, style)
Esempio n. 28
0
    def calculate_bboxes(self, nodes):
        bboxes = [(id, node, computeBBox([node]))
                for id, node in nodes.items()]

        return bboxes
Esempio n. 29
0
 def center(self, source_node):
     xmin, xmax, ymin, ymax = computeBBox([source_node])
     point = [(xmax - ((xmax - xmin) / 2)), (ymax - ((ymax - ymin) / 2))]
     transform = get_node_transform(self.node)
     applyTransformToPoint(transform, point)
     return point
Esempio n. 30
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)
Esempio n. 31
0
 def effect(self):
     if self.options.mformat == '"presets"':
         self.setPreset()
     # get number of digits
     prec = int(self.options.precision)
     scale = self.unittouu('1px')    # convert to document units
     self.options.offset *= scale
     factor = 1.0
     doc = self.document.getroot()
     if doc.get('viewBox'):
         [viewx, viewy, vieww, viewh] = doc.get('viewBox').split(' ')
         factor = self.unittouu(doc.get('width'))/float(vieww)
         if self.unittouu(doc.get('height'))/float(viewh) < factor:
             factor = self.unittouu(doc.get('height'))/float(viewh)
         factor /= self.unittouu('1px')
         self.options.fontsize /= factor
     factor *= scale/self.unittouu('1'+self.options.unit)
     # loop over all selected paths
     for id, node in self.selected.iteritems():
         if node.tag == inkex.addNS('path','svg'):
             mat = simpletransform.composeParents(node, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
             p = cubicsuperpath.parsePath(node.get('d'))
             simpletransform.applyTransformToPath(mat, p)
             if self.options.mtype == "length":
                 slengths, stotal = csplength(p)
                 self.group = inkex.etree.SubElement(node.getparent(),inkex.addNS('text','svg'))
             elif self.options.mtype == "area":
                 stotal = abs(csparea(p)*factor*self.options.scale)
                 self.group = inkex.etree.SubElement(node.getparent(),inkex.addNS('text','svg'))
             else:
                 xc, yc = cspcofm(p)
                 self.group = inkex.etree.SubElement(node.getparent(),inkex.addNS('path','svg'))
                 self.group.set('id', 'MassCenter_' + node.get('id'))
                 self.addCross(self.group, xc, yc, scale)
                 continue
             # Format the length as string
             lenstr = locale.format("%(len)25."+str(prec)+"f",{'len':round(stotal*factor*self.options.scale,prec)}).strip()
             if self.options.mformat == '"textonpath"':
                 startOffset = self.options.startOffset
                 if startOffset == "custom":
                     startOffset = str(self.options.startOffsetCustom) + '%'
                 if self.options.mtype == "length":
                     self.addTextOnPath(self.group, 0, 0, lenstr+' '+self.options.unit, id, self.options.anchor, startOffset, self.options.offset)
                 else:
                     self.addTextOnPath(self.group, 0, 0, lenstr+' '+self.options.unit+'^2', id, self.options.anchor, startOffset, self.options.offset)
             elif self.options.mformat == '"fixedtext"':
                 if self.options.position == "mass":
                     tx, ty = cspcofm(p)
                     anchor = 'middle'
                 elif self.options.position == "center":
                     bbox = simpletransform.computeBBox([node])
                     tx = bbox[0] + (bbox[1] - bbox[0])/2.0
                     ty = bbox[2] + (bbox[3] - bbox[2])/2.0
                     anchor = 'middle'
                 else:  # default
                     tx = p[0][0][1][0]
                     ty = p[0][0][1][1]
                     anchor = 'start'
                 if self.options.mtype == "length":
                     self.addTextWithTspan(self.group, tx, ty, lenstr+' '+self.options.unit, id, anchor, -int(self.options.angle), self.options.offset + self.options.fontsize/2)
                 else:
                     self.addTextWithTspan(self.group, tx, ty, lenstr+' '+self.options.unit+'^2', id, anchor, -int(self.options.angle), -self.options.offset + self.options.fontsize/2)
             else:
                 # center of mass, no text
                 pass
    def effect(self):
        """
        Effect behaviour.
        """
        self.where = self.options.where
        self.base64Encode = self.options.encode
        self.viewResult = self.options.viewresult
        self.resizeDrawing = self.options.resize
        self.reposition = self.options.reposition
        self.scour = self.options.scour
        self.renderSass = True
        self.includeJS = self.options.includejs
        self.CSSSource = []

        self.getselected()

        self.svgDoc = self.document.xpath("//svg:svg", namespaces=inkex.NSS)[0]
        self.svgWidth = inkex.unittouu(self.svgDoc.get("width"))
        self.svgHeight = inkex.unittouu(self.svgDoc.get("height"))

        overideElementDim = False

        # Temporary solution where I grab all defs, regardless of if they are actually used or not
        # defs = self.document.xpath('//svg:svg/svg:defs',namespaces=inkex.NSS)[0]

        layers = self.document.xpath('//svg:svg/svg:g[@style!="display:none"]', namespaces=inkex.NSS)

        """
        if(len(defs) > 0):
            defs = inkex.etree.tostring(defs)
        else:
            defs = '<defs/>'
        """

        # If no elements where selected we default to exporting every visible layer in the drawing
        if self.selected.__len__() <= 0:
            self.selected = layers
            # As we are exporting whole layers we assume that the resulting SVG drawings has the
            # same dimensions as the source document and thus overide the elements bounding box.
            overideElementDim = True
        else:
            self.selected = self.selected.values()

        if self.selected.__len__() > 0:
            selected = []

            # Iterate through all selected elements
            for element in self.selected:

                elementLabel = str(element.get(inkex.addNS("label", "inkscape"), ""))
                elementId = element.get("id")

                if elementLabel != "":
                    element.set("label", elementLabel)
                    element.set("class", elementLabel)
                else:
                    pass

                tagName = self.getTagName(element)

                if tagName == "path":
                    # Paths can easily be moved by recalculating their d attributes
                    if self.reposition or self.resizeDrawing:
                        pathData = self.movePath(element, 0, 0, "tl")
                        if pathData:
                            element.set("d", pathData)

                elif tagName == "g":
                    # Groups however are best "transformed" into place using translate
                    # self.translateElement(element,0,0,False)
                    pass

                elementBox = list(simpletransform.computeBBox([element]))
                elementBox[1] = elementBox[1] - elementBox[0]
                elementBox[3] = elementBox[3] - elementBox[2]

                if overideElementDim == False:
                    elementWidth = elementBox[1]
                    elementHeight = elementBox[3]
                else:
                    elementWidth = self.svgWidth
                    elementHeight = self.svgHeight

                elementSource = inkex.etree.tostring(element)

                if elementSource != "":
                    # Wrap the node in an SVG doc
                    if self.resizeDrawing:
                        tplResult = string.replace(self.exportTemplate, "{{element.width}}", str(elementWidth))
                        tplResult = string.replace(tplResult, "{{element.height}}", str(elementHeight))

                    else:
                        tplResult = string.replace(self.exportTemplate, "{{element.width}}", str(self.svgWidth))
                        tplResult = string.replace(tplResult, "{{element.height}}", str(self.svgHeight))

                    # tplResult = string.replace(tplResult,'{{document.defs}}',defs)
                    tplResult = string.replace(tplResult, "{{element.source}}", elementSource)
                    if self.includeJS:
                        tplResult = string.replace(tplResult, "{{js}}", self.js)
                    else:
                        tplResult = string.replace(tplResult, "{{js}}", "")

                    if self.scour:
                        tplResult = self.scourDoc(tplResult)

                    # If the result of the operation is valid, add the SVG source to the selected array
                    if tplResult:
                        selected.append(
                            {"id": elementId, "label": elementLabel, "source": tplResult, "box": elementBox}
                        )

            for node in selected:
                # Cache these in local vars
                content = node["source"]
                id = node["id"]
                label = node["label"] or node["id"]

                if content != "":

                    if self.base64Encode:

                        if self.renderSass:
                            content = (
                                "$data-url-"
                                + label
                                + ':"data:image/svg+xml;name='
                                + label
                                + ";base64,"
                                + (base64.b64encode(content))
                                + '";'
                            )
                            # node['source'] = ('data:image/svg+xml;name='+label+';base64,'+(base64.b64encode(content)))
                            # content = self.renderSassStyle(node)
                        else:
                            pass
                            # content = ('data:image/svg+xml;name='+label+';base64,'+(base64.b64encode(content)))

                    if self.where != "":

                        # The easiest way to name rendered elements is by using their id since we can trust that this is always unique.
                        filename = os.path.join(self.where, (id + "-" + label + ".svg"))
                        success = self.saveToFile(content, filename)

                        if success:
                            if self.viewResult:
                                self.viewOutput(filename)
                        else:
                            inkex.debug('Unable to write to file "' + filename + '"')

                    else:
                        if self.viewResult:
                            if self.base64Encode:
                                inkex.debug(content)
                                inkex.debug("")
                                # self.viewOutput('data:image/svg+xml;base64,'+content)
                            else:
                                inkex.debug(content)
                                inkex.debug("")
                                # self.viewOutput('data:image/svg+xml,'+content)
                        else:
                            inkex.debug(content)

                else:
                    inkex.debug("No SVG source available for element " + id)
        else:
            inkex.debug("No SVG elements or layers to extract.")
Esempio n. 33
0
	def effect(self):

		#{{{ Check that elements have been selected

		if len(self.options.ids) == 0:
			inkex.errormsg(_("Please select objects!"))
			return

		#}}}

		#{{{ Drawing styles

		linestyle = {
			'stroke': '#000000',
			'stroke-width': str(self.unittouu('1px')),
			'fill': 'none'
		}

		facestyle = {
			'stroke': '#000000',
			'stroke-width':'0px',# str(self.unittouu('1px')),
			'fill': 'none'
		}

		#}}}

		#{{{ Handle the transformation of the current group
		parentGroup = self.getParentNode(self.selected[self.options.ids[0]])

		svg = self.document.getroot()
		children =svg.getchildren()
		fp=open("log.txt","w")
		img=None
		width_in_svg=1
		height_in_svg=1
		for child in children:
			if child.tag=="{http://www.w3.org/2000/svg}g":
				ccc=child.getchildren()
				for c in ccc:
					if c.tag=="{http://www.w3.org/2000/svg}image":
						href=c.attrib["{http://www.w3.org/1999/xlink}href"]
						fp.write(href)
						img = Image.open(href)
						width_in_svg=child.attrib['width']
						height_in_svg=child.attrib['height']
			elif child.tag=="{http://www.w3.org/2000/svg}image":
				href=child.attrib["{http://www.w3.org/1999/xlink}href"]
				width_in_svg=child.attrib['width']
				height_in_svg=child.attrib['height']
				if "file://" in href:
					href=href[7:]
				fp.write(href+"\n")
				img = Image.open(href).convert("RGB")
		width=-1
		height=-1
		if img!=None:
			imagesize = img.size
			width=img.size[0]
			height=img.size[1]
		fp.write("imageSize="+str(imagesize))



		trans = self.getGlobalTransform(parentGroup)
		invtrans = None
		if trans:
			invtrans = self.invertTransform(trans)

		#}}}

		#{{{ Recovery of the selected objects

		pts = []
		nodes = []
		seeds = []

		fp.write('num:'+str(len(self.options.ids))+'\n')
		for id in self.options.ids:
			node = self.selected[id]
			nodes.append(node)
			if(node.tag=="{http://www.w3.org/2000/svg}path"):#pathだった場合
				#パスの頂点座標を取得
				points = cubicsuperpath.parsePath(node.get('d'))
				fp.write(str(points)+"\n")
				for p in points[0]:
					pt=[p[1][0],p[1][1]]
					if trans:
						simpletransform.applyTransformToPoint(trans, pt)
					pts.append(Point(pt[0], pt[1]))
					seeds.append(Point(p[1][0], p[1][1]))
			else:#その他の図形の場合
				bbox = simpletransform.computeBBox([node])
				if bbox:
					cx = 0.5 * (bbox[0] + bbox[1])
					cy = 0.5 * (bbox[2] + bbox[3])
					pt = [cx, cy]
					if trans:
						simpletransform.applyTransformToPoint(trans, pt)
					pts.append(Point(pt[0], pt[1]))
					seeds.append(Point(cx, cy))
		pts.sort()
		seeds.sort()
		fp.write("*******sorted!***********"+str(len(seeds))+"\n")

		#}}}

		#{{{ Creation of groups to store the result
		# Delaunay
		groupDelaunay = inkex.etree.SubElement(parentGroup, inkex.addNS('g', 'svg'))
		groupDelaunay.set(inkex.addNS('label', 'inkscape'), 'Delaunay')

		#}}}

		scale_x=float(width_in_svg)/float(width)
		scale_y=float(height_in_svg)/float(height)
		fp.write('width='+str(width)+', height='+str(height)+'\n')
		fp.write('scale_x='+str(scale_x)+', scale_y='+str(scale_y)+'\n')

		#{{{ Voronoi diagram generation

		triangles = voronoi.computeDelaunayTriangulation(seeds)
		for triangle in triangles:
			p1 = seeds[triangle[0]]
			p2 = seeds[triangle[1]]
			p3 = seeds[triangle[2]]
			cmds = [['M', [p1.x, p1.y]],
					['L', [p2.x, p2.y]],
					['L', [p3.x, p3.y]],
					['Z', []]]
			path = inkex.etree.Element(inkex.addNS('path', 'svg'))
			path.set('d', simplepath.formatPath(cmds))
			middleX=(p1.x+p2.x+p3.x)/3.0/scale_x
			middleY=(p1.y+p2.y+p3.y)/3.0/scale_y
			fp.write("x:"+str(middleX)+" y:"+str(middleY)+"\n")
			if img!=None and imagesize[0]>middleX and imagesize[1]>middleY and middleX>=0 and middleY>=0:
				r,g,b = img.getpixel((middleX,middleY))
				facestyle["fill"]=simplestyle.formatColor3i(r,g,b)
			else:
				facestyle["fill"]="black"
			path.set('style', simplestyle.formatStyle(facestyle))
			groupDelaunay.append(path)
		fp.close()
Esempio n. 34
0
    def parsePath(self,node,parent):

        #self.parsing_context = 'path'

        style = node.get('style')
        style = self.parseStyleAttribute(style)

        transform = node.get('transform','')

        box =list(simpletransform.computeBBox([node]))

        box[1] = (box[1]-box[0])
        box[3] = (box[3]-box[2])

        origin_x = float(node.get(inkex.addNS('transform-center-x', 'inkscape'),0))
        origin_y = float(node.get(inkex.addNS('transform-center-y', 'inkscape'),0))
        origin_x = origin_x + ( box[1] / 2)
        origin_y = (origin_y * -1) + ( box[3] / 2)

        if(transform!=''):
            transform = simpletransform.parseTransform(node.get('transform',''))
            transform = self.matrixToList(transform)
            transform = self.normalizeMatrix(transform)

        path_array = simplepath.parsePath(node.get('d'))


        path = {
            'id':node.get('id'),
            'svg':'path',
            'label':str(node.get(inkex.addNS('label', 'inkscape'),'')),
            'box':box,
            'transform':transform,
            'origin':{
                'x':origin_x,
                'y':origin_y,
            },
            'path':path_array,
            #'d':node.get('d',''),
            'attr':{
                'fillColor':style.get('fill',''),
                'fillGradient':style.get('fillGradient',''),
                'fillOpacity':style.get('fillOpacity','1'),
                'opacity':style.get('opacity','1'),
                'strokeColor':style.get('stroke',''),
                'strokeGradient':style.get('strokeGradient',''),
                'strokeWidth':style.get('strokeWidth','0'),
                'strokeOpacity':style.get('strokeOpacity','1'),
                'filters':style.get('filter','')
            }

        }

        #inkex.debug('Path resides in group ' + self.parse_stack[len(self.parse_stack)-1]['id'])

        if(self.reposition):
            path['path'] = self.movePath(path,0,0,'tl')
        else:
            path['path'] = simplepath.formatPath(path_array)

        path['box'] = list(path['box']) if path['box'] != None else []
        parent.append(path)
Esempio n. 35
0
 def effect(self):
     if self.options.mformat == '"presets"':
         self.setPreset()
     # get number of digits
     prec = int(self.options.precision)
     scale = self.unittouu('1px')  # convert to document units
     self.options.offset *= scale
     factor = 1.0
     doc = self.document.getroot()
     if doc.get('viewBox'):
         [viewx, viewy, vieww, viewh] = doc.get('viewBox').split(' ')
         factor = self.unittouu(doc.get('width')) / float(vieww)
         if self.unittouu(doc.get('height')) / float(viewh) < factor:
             factor = self.unittouu(doc.get('height')) / float(viewh)
         factor /= self.unittouu('1px')
         self.options.fontsize /= factor
     factor *= scale / self.unittouu('1' + self.options.unit)
     # loop over all selected paths
     for id, node in self.selected.iteritems():
         if node.tag == inkex.addNS('path', 'svg'):
             mat = simpletransform.composeParents(
                 node, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
             p = cubicsuperpath.parsePath(node.get('d'))
             simpletransform.applyTransformToPath(mat, p)
             if self.options.mtype == "length":
                 slengths, stotal = csplength(p)
                 self.group = inkex.etree.SubElement(
                     node.getparent(), inkex.addNS('text', 'svg'))
             elif self.options.mtype == "area":
                 stotal = abs(csparea(p) * factor * self.options.scale)
                 self.group = inkex.etree.SubElement(
                     node.getparent(), inkex.addNS('text', 'svg'))
             else:
                 xc, yc = cspcofm(p)
                 self.group = inkex.etree.SubElement(
                     node.getparent(), inkex.addNS('path', 'svg'))
                 self.group.set('id', 'MassCenter_' + node.get('id'))
                 self.addCross(self.group, xc, yc, scale)
                 continue
             # Format the length as string
             lenstr = locale.format("%(len)25." + str(prec) + "f", {
                 'len':
                 round(stotal * factor * self.options.scale, prec)
             }).strip()
             if self.options.mformat == '"textonpath"':
                 startOffset = self.options.startOffset
                 if startOffset == "custom":
                     startOffset = str(self.options.startOffsetCustom) + '%'
                 if self.options.mtype == "length":
                     self.addTextOnPath(self.group, 0, 0,
                                        lenstr + ' ' + self.options.unit,
                                        id, self.options.anchor,
                                        startOffset, self.options.offset)
                 else:
                     self.addTextOnPath(
                         self.group, 0, 0,
                         lenstr + ' ' + self.options.unit + '^2', id,
                         self.options.anchor, startOffset,
                         self.options.offset)
             elif self.options.mformat == '"fixedtext"':
                 if self.options.position == "mass":
                     tx, ty = cspcofm(p)
                     anchor = 'middle'
                 elif self.options.position == "center":
                     bbox = simpletransform.computeBBox([node])
                     tx = bbox[0] + (bbox[1] - bbox[0]) / 2.0
                     ty = bbox[2] + (bbox[3] - bbox[2]) / 2.0
                     anchor = 'middle'
                 else:  # default
                     tx = p[0][0][1][0]
                     ty = p[0][0][1][1]
                     anchor = 'start'
                 if self.options.mtype == "length":
                     self.addTextWithTspan(
                         self.group, tx, ty,
                         lenstr + ' ' + self.options.unit, id, anchor,
                         -int(self.options.angle),
                         self.options.offset + self.options.fontsize / 2)
                 else:
                     self.addTextWithTspan(
                         self.group, tx, ty,
                         lenstr + ' ' + self.options.unit + '^2', id,
                         anchor, -int(self.options.angle),
                         -self.options.offset + self.options.fontsize / 2)
             else:
                 # center of mass, no text
                 pass
Esempio n. 36
0
 def effect(self):
     if len(self.options.ids) < 1:
         inkex.errormsg(_("This extension requires one selected path."))
         return
     
     self.prepareSelectionList()
     
     for skeleton in self.skeletons.itervalues():
         resPath = []
         pattern = inkex.etree.Element(inkex.addNS('path','svg'))
         
         self.options.strokeHexColor, self.strokeOpacity = getColorAndOpacity(self.options.strokeColor)
         
         # Copy style of skeleton with setting color and opacity
         s = skeleton.get('style')
         
         if s:
             pattern.set('style', setColorAndOpacity(s, self.options.strokeHexColor, self.strokeOpacity))
         
         skeletonPath = modifySkeletonPath(getSkeletonPath(skeleton.get('d'), self.options.offset))
         
         self.skelComp, self.lengths = self.linearizePath(skeletonPath, self.options.offset)
         
         length = sum(self.lengths)
         patternWidth = length / self.options.frequency
         selectedFunction = self.getFunction(self.options.contourFunction)
         
         pattern.set('d', simplepath.formatPath(drawfunction(self.options.nodes, patternWidth, selectedFunction)))
         
         # Add path into SVG structure
         skeleton.getparent().append(pattern)
         
         if self.options.remove:
             skeleton.getparent().remove(skeleton)
         
         # Compute bounding box
         bbox = simpletransform.computeBBox([pattern])
         
         width = bbox[1] - bbox[0]
         dx = width
         
         if dx < 0.01:
             exit(_("The total length of the pattern is too small."))
         
         patternPath = cubicsuperpath.parsePath(pattern.get('d'))
         curPath = deepcopy(patternPath)
         
         xoffset = self.skelComp[0][0] - bbox[0]
         yoffset = self.skelComp[0][1] - (bbox[2] + bbox[3]) / 2
         
         patternCopies = max(1, int(round(length / dx)))
         width = dx * patternCopies
         
         newPath = []
         
         # Repeat pattern to cover whole skeleton
         for subPath in curPath:
             for i in range(0, patternCopies, 1):
                 newPath.append(deepcopy(subPath))
                 offset(subPath, dx, 0)
         
         curPath = newPath
         
         # Offset pattern to the first node of the skeleton
         for subPath in curPath:
             offset(subPath, xoffset, yoffset)
         
         # Stretch pattern to whole skeleton
         for subPath in curPath:
             stretch(subPath, length / width, 1, self.skelComp[0])
         
         for subPath in curPath:
             for ctlpt in subPath:
                 self.applyDiffeo(ctlpt[1], (ctlpt[0], ctlpt[2]))
         
         # Check if there is a need to close path manually
         if self.skelCompIsClosed:
             firstPtX = round(curPath[0][0][1][0], 8)
             firstPtY = round(curPath[0][0][1][1], 8)
             finalPtX = round(curPath[-1][-1][1][0], 8)
             finalPtY = round(curPath[-1][-1][1][1], 8)
             
             if (firstPtX != finalPtX or firstPtY != finalPtY):
                 curPath[-1].append(curPath[0][0])
         
         resPath += curPath
         
         pattern.set('d', cubicsuperpath.formatPath(resPath))
Esempio n. 37
0
    def effect(self):
        # search for pattern layer
        triangle_layer = self.document.xpath('//svg:g[@id="triangle_layer"]',
                                             namespaces=inkex.NSS)
        if len(triangle_layer) == 0:
            # append pattern layer
            triangle_layer = self.createLayer("triangle_layer",
                                              "Triangle Boundary")
            self.document.getroot().append(triangle_layer)
            inkex.debug(
                "1. draw exactly one triangle in Triangle Boundary layer\n"
                "2. create a pattern composed of only paths\n"
                "3. select triangles that you want to apply pattern to\n"
                "4. enter pattern id (or default to use first pattern), then apply"
            )
        else:
            triangle_layer = triangle_layer[0]
            # find triangle in the triangle_layer
            trngl_lyr_children = triangle_layer.getchildren()
            if not len(trngl_lyr_children) == 1:
                inkex.debug(
                    "more or less than 1 element in Triangle Boundary layer: "
                    + str(len(trngl_lyr_children)))
                return
            else:
                bndry_trngle = triangle_layer.getchildren()[0]
                # seems like a path
                if isPath(bndry_trngle):
                    path_string = bndry_trngle.attrib[u'd']
                    svg_path = simplepath.parsePath(path_string)

                    # verified to be triangle
                    if pathIsTriangle(svg_path):
                        self.bndry_trngle_verts = getTriangleVerts(svg_path)
                        self.bndry_trngle_matrx = formMatrix(
                            self.bndry_trngle_verts)

                        # find pattern
                        self.defs = self.document.xpath(
                            '//svg:defs', namespaces=inkex.NSS)[0]
                        # get first pattern is default
                        if self.options.pattern_name == "default":
                            patterns = self.defs.xpath('./svg:pattern',
                                                       namespaces=inkex.NSS)
                        # find pattern with name
                        else:
                            patterns = self.defs.xpath(
                                './svg:pattern[@id="' +
                                self.options.pattern_name + '"]',
                                namespaces=inkex.NSS)

                        if len(patterns) > 0:
                            self.pattern = patterns[0]
                            # calculate the size of the pattern so that the pattern repeats exactly once in the bounding triangle
                            # get the union of all paths in pattern and boundary triangle
                            pattern_trngle_union = self.pattern.xpath(
                                './/svg:path', namespaces=inkex.NSS)
                            pattern_trngle_union.append(bndry_trngle)
                            # get bounding box of the union
                            bb_x_min, bb_x_max, bb_y_min, bb_y_max = simpletransform.computeBBox(
                                pattern_trngle_union)
                            # calculate size of union
                            pattern_width = bb_x_max - bb_x_min
                            pattern_height = bb_y_max - bb_y_min
                            # get scaling factor of pattern
                            pattern_trnsfrm = simpletransform.parseTransform(
                                self.pattern.attrib[u'patternTransform'])
                            scale_x = pattern_trnsfrm[0][0]
                            scale_y = pattern_trnsfrm[1][1]
                            # set size of pattern
                            self.pattern.attrib[u'width'] = str(pattern_width /
                                                                scale_x)
                            self.pattern.attrib[u'height'] = str(
                                pattern_height / scale_y)
                        else:
                            inkex.debug("cannot find pattern")
                            return
                else:
                    inkex.debug(
                        "the shape in triangle boundary layer is not a triangle"
                    )
                    return

        for id, node in self.selected.iteritems():
            if isPath(node):
                path_string = node.attrib[u'd']
                svg_path = simplepath.parsePath(path_string)
                if pathIsTriangle(svg_path):
                    trngle_verts = getTriangleVerts(svg_path)
                    trngle_matrx = formMatrix(trngle_verts)
                    # apply affine transform
                    pattern_trnsform = three.multiply(
                        trngle_matrx,
                        three.getInverse(self.bndry_trngle_matrx))
                    # compose with initial transform of pattern
                    initial_trnsform = simpletransform.parseTransform(
                        self.pattern.attrib[u'patternTransform'])
                    final_trnsform = simpletransform.composeTransform(
                        pattern_trnsform, initial_trnsform)
                    # if pattern for triangle exists, use it
                    pattern_name = "pattern_for_" + str(id)
                    existing_patterns = self.defs.xpath('./svg:pattern[@id="' +
                                                        pattern_name + '"]',
                                                        namespaces=inkex.NSS)
                    if len(existing_patterns) > 0:
                        pattern_transformed = existing_patterns[0]
                    else:
                        # create transformed pattern
                        pattern_transformed = etree.Element("{%s}pattern" %
                                                            inkex.NSS[u'svg'])
                    # fill in the attributes for pattern
                    pattern_transformed.attrib[u'id'] = "pattern_for_" + str(
                        id)
                    pattern_transformed.attrib[
                        "{%s}collect" % inkex.NSS[u'inkscape']] = "always"
                    pattern_transformed.attrib[
                        "{%s}href" %
                        inkex.NSS[u'xlink']] = '#' + self.pattern.attrib[u'id']
                    pattern_transformed.attrib[
                        u'patternTransform'] = simpletransform.formatTransform(
                            final_trnsform)
                    # append transformed pattern
                    self.defs.append(pattern_transformed)
                    # fill triangle with pattern
                    trngle_styles = simplestyle.parseStyle(
                        node.attrib[u'style'])
                    trngle_styles[u'fill'] = u'url(#' + str(
                        pattern_transformed.attrib[u'id']) + ')'
                    node.attrib[u'style'] = simplestyle.formatStyle(
                        trngle_styles)
                else:
                    inkex.debug("not triangle")
Esempio n. 38
0
  def effect(self):

    #{{{ Check that elements have been selected

    if len(self.options.ids) == 0:
      inkex.errormsg(_("Please select objects!"))
      return

    #}}}

    #{{{ Drawing styles

    linestyle = {
        'stroke'       : '#000000',
        'stroke-width' : str(self.unittouu('1px')),
        'fill'         : 'none'
        }

    facestyle = {
        'stroke'       : '#ff0000',
        'stroke-width' : str(self.unittouu('1px')),
        'fill'         : 'none'
        }

    #}}}

    #{{{ Handle the transformation of the current group
    parentGroup = self.getParentNode(self.selected[self.options.ids[0]])

    trans = self.getGlobalTransform(parentGroup)
    invtrans = None
    if trans:
      invtrans = simpletransform.invertTransform(trans)

    #}}}

    #{{{ Recovery of the selected objects

    pts = []
    nodes = []
    seeds = []


    for id in self.options.ids:
      node = self.selected[id]
      nodes.append(node)
      bbox = simpletransform.computeBBox([node])
      if bbox:
        cx = 0.5*(bbox[0]+bbox[1])
        cy = 0.5*(bbox[2]+bbox[3])
        pt = [cx,cy]
        if trans:
          simpletransform.applyTransformToPoint(trans,pt)
        pts.append(Point(pt[0],pt[1]))
        seeds.append(Point(cx,cy))

    #}}}

    #{{{ Creation of groups to store the result

    if self.options.diagramType != 'Delaunay':
      # Voronoi
      groupVoronoi = inkex.etree.SubElement(parentGroup,inkex.addNS('g','svg'))
      groupVoronoi.set(inkex.addNS('label', 'inkscape'), 'Voronoi')
      if invtrans:
        simpletransform.applyTransformToNode(invtrans,groupVoronoi)
    if self.options.diagramType != 'Voronoi':
      # Delaunay
      groupDelaunay = inkex.etree.SubElement(parentGroup,inkex.addNS('g','svg'))
      groupDelaunay.set(inkex.addNS('label', 'inkscape'), 'Delaunay')

    #}}}

    #{{{ Clipping box handling

    if self.options.diagramType != 'Delaunay':
      #Clipping bounding box creation
      gBbox = simpletransform.computeBBox(nodes)

      #Clipbox is the box to which the Voronoi diagram is restricted
      clipBox = ()
      if self.options.clipBox == 'Page':
        svg = self.document.getroot()
        w = self.unittouu(svg.get('width'))
        h = self.unittouu(svg.get('height'))
        clipBox = (0,w,0,h)
      else:
        clipBox = (2*gBbox[0]-gBbox[1],
                   2*gBbox[1]-gBbox[0],
                   2*gBbox[2]-gBbox[3],
                   2*gBbox[3]-gBbox[2])
      
      #Safebox adds points so that no Voronoi edge in clipBox is infinite
      safeBox = (2*clipBox[0]-clipBox[1],
                 2*clipBox[1]-clipBox[0],
                 2*clipBox[2]-clipBox[3],
                 2*clipBox[3]-clipBox[2])
      pts.append(Point(safeBox[0],safeBox[2]))
      pts.append(Point(safeBox[1],safeBox[2]))
      pts.append(Point(safeBox[1],safeBox[3]))
      pts.append(Point(safeBox[0],safeBox[3]))

      if self.options.showClipBox:
        #Add the clip box to the drawing
        rect = inkex.etree.SubElement(groupVoronoi,inkex.addNS('rect','svg'))
        rect.set('x',str(clipBox[0]))
        rect.set('y',str(clipBox[2]))
        rect.set('width',str(clipBox[1]-clipBox[0]))
        rect.set('height',str(clipBox[3]-clipBox[2]))
        rect.set('style',simplestyle.formatStyle(linestyle))

    #}}}

    #{{{ Voronoi diagram generation

    if self.options.diagramType != 'Delaunay':
      vertices,lines,edges = voronoi.computeVoronoiDiagram(pts)
      for edge in edges:
        line = edge[0]
        vindex1 = edge[1]
        vindex2 = edge[2]
        if (vindex1 <0) or (vindex2 <0):
          continue # infinite lines have no need to be handled in the clipped box
        else:
          segment = self.clipEdge(vertices,lines,edge,clipBox)
          #segment = [vertices[vindex1],vertices[vindex2]] # deactivate clipping
          if len(segment)>1:
            v1 = segment[0]
            v2 = segment[1]
            cmds = [['M',[v1[0],v1[1]]],['L',[v2[0],v2[1]]]]
            path = inkex.etree.Element(inkex.addNS('path','svg'))
            path.set('d',simplepath.formatPath(cmds))
            path.set('style',simplestyle.formatStyle(linestyle))
            groupVoronoi.append(path)

    if self.options.diagramType != 'Voronoi':
      triangles = voronoi.computeDelaunayTriangulation(seeds)
      for triangle in triangles:
        p1 = seeds[triangle[0]]
        p2 = seeds[triangle[1]]
        p3 = seeds[triangle[2]]
        cmds = [['M',[p1.x,p1.y]],
                ['L',[p2.x,p2.y]],
                ['L',[p3.x,p3.y]],
                ['Z',[]]]
        path = inkex.etree.Element(inkex.addNS('path','svg'))
        path.set('d',simplepath.formatPath(cmds))
        path.set('style',simplestyle.formatStyle(facestyle))
        groupDelaunay.append(path)
Esempio n. 39
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))
Esempio n. 40
0
    def calculate_bboxes(self, nodes):
        bboxes = [(id, node, computeBBox([node]))
                  for id, node in nodes.items()]

        return bboxes