def effect(self):
        zoom = self.unittouu(str(self.options.zoom) + 'px')

        if self.options.randomize:
            imagelist = generate_random_string(self.options.text, zoom)
        else:
            tokens = tokenize(self.options.text)
            imagelist = randomize_input_string(tokens, zoom)

        image = layoutstring(imagelist, zoom)

        if image:
            s = {'stroke': 'none', 'fill': '#000000'}

            new = inkex.etree.Element(inkex.addNS('path', 'svg'))
            new.set('style', simplestyle.formatStyle(s))

            new.set('d', simplepath.formatPath(image))
            self.current_layer.append(new)

            # compensate preserved transforms of parent layer
            if self.current_layer.getparent() is not None:
                mat = simpletransform.composeParents(
                    self.current_layer, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
                simpletransform.applyTransformToNode(
                    simpletransform.invertTransform(mat), new)
Пример #2
0
    def to_patches(self, last_patch=None):
        patches = []

        source_node = get_clone_source(self.node)
        if source_node.tag not in EMBROIDERABLE_TAGS:
            return []

        clone = copy(source_node)

        # set id
        clone_id = 'clone__%s__%s' % (self.node.get('id',
                                                    ''), clone.get('id', ''))
        clone.set('id', clone_id)

        # apply transform
        transform = get_node_transform(self.node)
        applyTransformToNode(transform, clone)

        # apply style
        stroke_style = self.get_clone_style('stroke', self.node)
        if not stroke_style:
            stroke_style = self.get_clone_style('stroke', source_node)
        fill_style = self.node.get('fill')
        if not fill_style:
            fill_style = self.get_clone_style('fill', source_node, "#000000")
        fill_opacity = self.node.get('fill-opacity')
        if not fill_opacity:
            fill_opacity = self.get_clone_style('fill-opacity', source_node,
                                                "1")
        style = "fill:%s;fill-opacity:%s;" % (fill_style, fill_opacity)
        if stroke_style:
            style += "stroke:%s;" % stroke_style
        clone.set('style', style)

        # set fill angle. Use either
        # a. a custom set fill angle
        # b. calculated rotation for the cloned fill element to look exactly as it's source
        param = INKSTITCH_ATTRIBS['angle']
        if self.clone_fill_angle is not None:
            angle = self.clone_fill_angle
        else:
            # clone angle
            clone_mat = parseTransform(clone.get('transform', ''))
            clone_angle = degrees(atan(-clone_mat[1][0] / clone_mat[1][1]))
            # source node angle
            source_mat = parseTransform(source_node.get('transform', ''))
            source_angle = degrees(atan(-source_mat[1][0] / source_mat[1][1]))
            # source node fill angle
            source_fill_angle = source_node.get(param, 0)

            angle = clone_angle + float(source_fill_angle) - source_angle
        clone.set(param, str(angle))

        elements = self.clone_to_element(clone)

        for element in elements:
            patches.extend(element.to_patches(last_patch))

        return patches
Пример #3
0
 def copy_pattern(self, x, y):
     p = copy.deepcopy(self.ptrn)
     cx = float(self.ptrn.get('cx'))
     cy = float(self.ptrn.get('cy'))
     transformation = 'translate(' + str(x - cx) + ', ' + str(y - cy) + ')'
     transform = simpletransform.parseTransform(transformation)
     simpletransform.applyTransformToNode(transform, p)
     self.current_layer.append(p)
Пример #4
0
    def scaleRoot(self, svg):
        """Scale all top-level elements in SVG root."""

        # update viewport
        widthNumber = self.parse_length(svg.get('width'))[0]
        heightNumber = self.convert_length(*self.parse_length(svg.get('height')))[0]
        widthDoc = widthNumber * self.factor_a * self.unitExponent
        heightDoc = heightNumber * self.factor_a * self.unitExponent

        if svg.get('height'):
            svg.set('height', str(heightDoc))
        if svg.get('width'):
            svg.set('width', str(widthDoc))

        # update viewBox
        if svg.get('viewBox'):
            viewboxstring = re.sub(' +|, +|,',' ', svg.get('viewBox'))
            viewboxlist = [float(i) for i in viewboxstring.strip().split(' ', 4)]
            svg.set('viewBox','{} {} {} {}'.format(*[(val * self.factor_a) for val in viewboxlist]))

        # update guides, grids
        if self.options.switcher == "1":
            # FIXME: dpi96to90 only?
            self.scaleGuides(svg)
            self.scaleGrid(svg)

        for element in svg:  # iterate all top-level elements of SVGRoot

            # init variables
            tag = etree.QName(element).localname
            width_scale = self.factor_a
            height_scale = self.factor_a

            if tag in GRAPHICS_ELEMENTS or tag in CONTAINER_ELEMENTS:

                # test for specific elements to skip from scaling
                if is_3dbox(element):
                    if check_3dbox(svg, element, width_scale, height_scale):
                        continue
                if is_text_on_path(element):
                    if check_text_on_path(svg, element, width_scale, height_scale):
                        continue
                if is_use(element):
                    if check_use(svg, element, width_scale, height_scale):
                        continue

                # relative units ('%') in presentation attributes
                for attr in ['width', 'height']:
                    self.scale_attr_val(element, attr, ['%'], 1.0 / self.factor_a)
                for attr in ['x', 'y']:
                    self.scale_attr_val(element, attr, ['%'], 1.0 / self.factor_a)

                # set preserved transforms on top-level elements
                if width_scale != 1.0 and height_scale != 1.0:
                    mat = simpletransform.parseTransform(
                        'scale({},{})'.format(width_scale, height_scale))
                    simpletransform.applyTransformToNode(mat, element)
Пример #5
0
    def effect(self):

        if len(self.options.ids) < 2:
            inkex.debug("This extension requires that you select two paths.")
            return
        self.prepareSelectionList()

        #center at (0,0)
        bbox = pathmodifier.computeBBox([self.patternNode])
        mat = [[1, 0, -(bbox[0] + bbox[1]) / 2],
               [0, 1, -(bbox[2] + bbox[3]) / 2]]
        if self.options.vertical:
            bbox = [-bbox[3], -bbox[2], bbox[0], bbox[1]]
            mat = simpletransform.composeTransform([[0, -1, 0], [1, 0, 0]],
                                                   mat)
        mat[1][2] += self.options.noffset
        simpletransform.applyTransformToNode(mat, self.patternNode)

        width = bbox[1] - bbox[0]
        dx = width + self.options.space

        for skelnode in self.skeletons.itervalues():
            self.curSekeleton = cubicsuperpath.parsePath(skelnode.get('d'))
            for comp in self.curSekeleton:
                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)
                if self.options.stretch:
                    dx = width + self.options.space
                    n = int(
                        (length - self.options.toffset + self.options.space) /
                        dx)
                    if n > 0:
                        dx = (length - self.options.toffset) / n

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

                s = self.options.toffset
                while s <= length:
                    mat = self.localTransformAt(s, self.options.follow)

                    clone = copy.deepcopy(self.patternNode)
                    #!!!--> should it be given an id?
                    #seems to work without this!?!
                    myid = self.patternNode.tag.split('}')[-1]
                    clone.set("id", self.uniqueId(myid))
                    self.gNode.append(clone)

                    simpletransform.applyTransformToNode(mat, clone)

                    s += dx
        self.patternNode.getparent().remove(self.patternNode)
Пример #6
0
 def update_layer_xform(self, settings):
     scale = (
         TransformMatrix.translate(settings.origin) *
         TransformMatrix.scale(settings.scaleFactor) *
         TransformMatrix.translate(-settings.origin)
     )
     mat = (scale * TransformMatrix.translate(settings.translation)).toSVG()
     for layer in [settings.markingsLayer, settings.layer]:
         for node in self.layer_contents(layer):
             simpletransform.applyTransformToNode(mat, node)
Пример #7
0
 def safelyMoveTo(self, node, parent, doCopy = False):
   '''
   Move a node, preserving its position in absolute coordinates
   '''
   oldParentTr = SpeleoTransform.getTotalTransform(node.getparent())
   newParentTr = SpeleoTransform.getTotalTransform(parent)
   if doCopy: node = copy.deepcopy(node)
   simpletransform.applyTransformToNode(oldParentTr, node)
   simpletransform.applyTransformToNode(SpeleoTransform.invertTransform(newParentTr), node)
   parent.append(node)
   return node
Пример #8
0
    def effect(self):

        if len(self.options.ids)<2:
            inkex.debug("This extension requires that you select two paths.")
            return
        self.prepareSelectionList()

        #center at (0,0)
        bbox=pathmodifier.computeBBox([self.patternNode])
        mat=[[1,0,-(bbox[0]+bbox[1])/2],[0,1,-(bbox[2]+bbox[3])/2]]
        if self.options.vertical:
            bbox=[-bbox[3],-bbox[2],bbox[0],bbox[1]]
            mat=simpletransform.composeTransform([[0,-1,0],[1,0,0]],mat)
        mat[1][2] += self.options.noffset
        simpletransform.applyTransformToNode(mat,self.patternNode)
                
        width=bbox[1]-bbox[0]
        dx=width+self.options.space

        for skelnode in self.skeletons.itervalues(): 
            self.curSekeleton=cubicsuperpath.parsePath(skelnode.get('d'))
            for comp in self.curSekeleton:
                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)
                if self.options.stretch:
                    dx=width+self.options.space
                    n=int((length-self.options.toffset+self.options.space)/dx)
                    if n>0:
                        dx=(length-self.options.toffset)/n


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

                s=self.options.toffset
                while s<=length:
                    mat=self.localTransformAt(s,self.options.follow)

                    clone=copy.deepcopy(self.patternNode)
                    #!!!--> should it be given an id?
                    #seems to work without this!?!
                    myid = self.patternNode.tag.split('}')[-1]
                    clone.set("id", self.uniqueId(myid))
                    self.gNode.append(clone)
                    
                    simpletransform.applyTransformToNode(mat,clone)

                    s+=dx
        self.patternNode.getparent().remove(self.patternNode)
Пример #9
0
    def place(self, nodes):
        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 = 0

        line_nodes = []

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

        for id, node, bbox in nodes:
            x, _, y, _ = bbox

            node_width = x_gap + self.width(bbox)
            # reached end of line, reset, move higher, start new group
            if total_width + node_width > max_line_width:
                group = etree.SubElement(self.current_layer, addNS('g', 'svg'))
                total_width = 0
                total_height += self.height(
                    self.computeBBox(line_nodes)) + y_gap
                line_nodes = []

            group.append(node)

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

            if node.tag == addNS('path', 'svg'):
                x_delta = x_dest - x
                y_delta = y_dest - y

                path = parsePath(node.attrib['d'])
                translatePath(path, x_delta, y_delta)
                node.attrib['d'] = formatPath(path)
            elif node.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)

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

            total_width += node_width
            line_nodes.append(node)
Пример #10
0
    def place(self, nodes):
        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 = 0

        line_nodes = []

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

        for id, node, bbox in nodes:
            x, _, y, _ = bbox

            node_width = x_gap + self.width(bbox)
            # reached end of line, reset, move higher, start new group
            if total_width + node_width > max_line_width:
                group = etree.SubElement(self.current_layer, addNS('g','svg'))
                total_width = 0
                total_height += self.height(self.computeBBox(line_nodes)) + y_gap
                line_nodes = []

            group.append(node)

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

            if node.tag == addNS('path','svg'):
                x_delta = x_dest - x
                y_delta = y_dest - y

                path = parsePath(node.attrib['d'])
                translatePath(path, x_delta, y_delta)
                node.attrib['d'] = formatPath(path)
            elif node.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)

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

            total_width += node_width
            line_nodes.append(node)
    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)
Пример #12
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
Пример #13
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
Пример #14
0
def draw_SVG_text(x, y, text, parent, style, angle=0):
	attribs = {
		'style' : simplestyle.formatStyle(style),
		'x' : str(x),
		'y' : str(y)
		}

	# Generate text
	txt = inkex.etree.SubElement(parent, inkex.addNS('text'), attribs)
	txt.text = text
	# Rotate (if needed)
	# We need to rotate around the text center.
	# To achieve this we move it to the origin, rotate it and then translate it back
	rotmatrix = simpletransform.parseTransform('translate('+str(x)+','+str(y)+')'+
										' rotate('+str(angle)+')'+
										' translate('+str(-x)+','+str(-y)+')')
	simpletransform.applyTransformToNode(rotmatrix, txt)
	return txt
Пример #15
0
	def fromSVG(self,nodes):
		# takes in a list of lxml elements
		# returns a list of inkscape compound simplepaths (paths in paths etc...)
		# could possibly push up into Plot
		spl = []
		for node in nodes:
			tag = node.tag[node.tag.rfind("}")+1:]
			if tag == 'path':
				spl.extend(simplepath.parsePath(node.get("d")))
			elif tag == 'rect':
				# how do I convert rect to path??
				raise AssertionError("Cannot handle '%s' objects, covert to rect's to path first."%(tag))
			elif tag == 'g':
				if node.get("transform"):
					simpletransform.applyTransformToNode(node.get("transform"),node)
				spl.extend(self.fromSVG(list(node)))
			else:
				raise AssertionError("Cannot handle tag '%s'"%(tag))
		return spl
Пример #16
0
    def unpackLayers(self, node, transform, appliedTransforms):
        '''
    Unpack a group back into layers and apply a transform accordingly
    '''

        # Was that a layer before going through packLayers() ?
        cName = node.get("class")
        if cName <> None:
            if cName == "wasLayer":
                # It seems so!

                # Revert changes made by packLayers()
                node.set(inkex.addNS('groupmode', 'inkscape'), "layer")
                node.attrib.pop("class")

                # The group could have acquired its own transform...
                layerTransform = node.get("transform")

                # Save transform applied to this layer, in case it is used by <use>
                appliedTransforms[node.get("id")] = transform

                # Transforms on regular groups are nice, but we do not want to have a transform on a layer!
                if layerTransform <> None:
                    # Remove the transform
                    node.attrib.pop("transform")

                    # Compose it with what we have
                    transform = simpletransform.composeTransform(
                        transform,
                        simpletransform.parseTransform(layerTransform))

                # Transform all child nodes of this layer, unpacking sub-layers if there are any
                for child in node:
                    self.unpackLayers(child, transform, appliedTransforms)

                return

        # We can simply apply our transform and say goodbye!
        simpletransform.applyTransformToNode(transform, node)

        # Save transform applied to this object, in case it is used by <use>
        appliedTransforms[node.get("id")] = transform
    def effect(self):
        # 選択要素がなければ終了
        if len(self.selected) <= 0: return

        # 親ノード
        parentnode = self.current_layer

        # 選択要素を取得
        sel = self.selected
        # inkex.debug('>> ' + ' '.join(_(v) for v in sel))

        # 変形マトリクスの作成
        transformation = 'scale(-1, 1)'
        transform = simpletransform.parseTransform(transformation)

        # 複製と変形マトリクスの適用
        for id, node in sel.iteritems():
            childNode = deepcopy(node)
            parentnode.append(childNode)
            simpletransform.applyTransformToNode(transform, childNode)
Пример #18
0
def draw_SVG_text(x, y, text, parent, style, angle=0):
    attribs = {
        'style': simplestyle.formatStyle(style),
        'x': str(x),
        'y': str(y)
    }

    # Generate text
    txt = inkex.etree.SubElement(parent, inkex.addNS('text'), attribs)
    txt.text = text
    # Rotate (if needed)
    # We need to rotate around the text center.
    # To achieve this we move it to the origin, rotate it and then translate it back
    rotmatrix = simpletransform.parseTransform('translate(' + str(x) + ',' +
                                               str(y) + ')' + ' rotate(' +
                                               str(angle) + ')' +
                                               ' translate(' + str(-x) + ',' +
                                               str(-y) + ')')
    simpletransform.applyTransformToNode(rotmatrix, txt)
    return txt
    def effect(self):
        # 選択要素がなければ終了
        if len(self.selected) <= 0: return

        # 親ノード
        parentnode = self.current_layer

        # 選択要素を取得
        sel = self.selected
        # inkex.debug('>> ' + ' '.join(_(v) for v in sel))

        # 変形マトリクスの作成
        transformation = 'scale(-1, 1)'
        transform = simpletransform.parseTransform(transformation)

        # 複製と変形マトリクスの適用
        for id, node in sel.iteritems():
            childNode = deepcopy(node)
            parentnode.append(childNode)
            simpletransform.applyTransformToNode(transform, childNode)
Пример #20
0
    def fromSVG(self, nodes, color):
        # takes in a list of lxml elements
        # returns a list of inkscape compound simplepaths (paths in paths etc...)
        # could possibly push up into Plot
        spl = []
        for node in nodes:
            tag = node.tag[node.tag.rfind("}") + 1:]
            if tag == 'path':
                #				spl.extend(simplepath.parsePath(node.get("d")))
                #Cut by color
                style_str = node.get('style')
                if style_str:
                    style = simplestyle.parseStyle(style_str)

                    if 'fill' in style:
                        f = style['fill']
                        color = str(color)
                        color_hex = color[-7:]
                        if (f == str(color_hex)
                                or str(color_hex) == '#######'):
                            spl.extend(simplepath.parsePath(node.get("d")))


#/Cut by color

            elif tag == 'rect':
                # how do I convert rect to path??
                raise AssertionError(
                    "Cannot handle '%s' objects, covert to rect's to path first."
                    % (tag))
            elif tag == 'g':
                if node.get("transform"):
                    simpletransform.applyTransformToNode(
                        node.get("transform"), node)
                spl.extend(self.fromSVG(list(node)))
            else:
                raise AssertionError("Cannot handle tag '%s'" % (tag))
        if (len(spl) == 0):
            raise AssertionError("No paths!", "Last selected color: " + color)
            sys.exit(0)
        return spl
Пример #21
0
    def effect(self):
        pm = PathModifier()
        pm.document = self.document

        for nid, node in self.selected.iteritems():
            # set() removes duplicates
            angles = set(
                # and remove Nones
                [x for x in rotate_helper.optimal_rotations(node)
                    if x is not None])
            # Go backwards so we know if we need to duplicate the node for
            # multiple rotations. (We don't want to rotate the main node
            # before duplicating it.)
            for i, angle in reversed(list(enumerate(angles))):
                if i > 0:
                    # Rotate a duplicate of the node
                    rotate_node = pm.duplicateNodes({nid: node}).items()[0][1]
                else:
                    rotate_node = node
                simpletransform.applyTransformToNode(
                    rotate_helper.rotate_matrix(rotate_node, angle),
                    rotate_node)
Пример #22
0
 def fromSVG(self, nodes):
     # takes in a list of lxml elements
     # returns a list of inkscape compound simplepaths (paths in paths etc...)
     # could possibly push up into Plot
     spl = []
     for node in nodes:
         tag = node.tag[node.tag.rfind("}") + 1:]
         if tag == 'path':
             spl.extend(simplepath.parsePath(node.get("d")))
         elif tag == 'rect':
             # how do I convert rect to path??
             raise AssertionError(
                 "Cannot handle '%s' objects, covert to rect's to path first."
                 % (tag))
         elif tag == 'g':
             if node.get("transform"):
                 simpletransform.applyTransformToNode(
                     node.get("transform"), node)
             spl.extend(self.fromSVG(list(node)))
         else:
             raise AssertionError("Cannot handle tag '%s'" % (tag))
     return spl
Пример #23
0
	def effect(self):
		zoom = self.unittouu( str(self.options.zoom) + 'px')

		if self.options.randomize:
			imagelist = generate_random_string(self.options.text, zoom)
		else:
			tokens = tokenize(self.options.text)
			imagelist = randomize_input_string(tokens, zoom)

		image = layoutstring( imagelist, zoom )

		if image:
			s = { 'stroke': 'none', 'fill': '#000000' }

			new = inkex.etree.Element(inkex.addNS('path','svg'))
			new.set('style', simplestyle.formatStyle(s))

			new.set('d', simplepath.formatPath(image))
			self.current_layer.append(new)

			# compensate preserved transforms of parent layer
			if self.current_layer.getparent() is not None:
				mat = simpletransform.composeParents(self.current_layer, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
				simpletransform.applyTransformToNode(simpletransform.invertTransform(mat), new)
Пример #24
0
    def create_pattern(self, rxy, cxy, angle, parent):

        # radius vars
        (rx, ry) = rxy

        # center vars
        (cx, cy) = cxy

        # pattern style
        style = {
            'stroke': '#000000',
            'stroke-width': '0',
            'fill': '#000000',
            'fill-opacity': '1.0'
        }

        # pattern element attributes
        attribs = {
            'style': simplestyle.formatStyle(style),
            'rx': str(rx),
            'ry': str(ry),
            'cx': str(cx),
            'cy': str(cy)
        }

        # create an xml element for the pattern
        el = inkex.etree.SubElement(parent, inkex.addNS('ellipse', 'svg'),
                                    attribs)

        # rotate the pattern to mimic calligraphy pen
        transformation = 'rotate(' + str(angle) + ',' + str(cx) + ',' + str(
            cy) + ')'
        transform = simpletransform.parseTransform(transformation)
        simpletransform.applyTransformToNode(transform, el)

        return el
Пример #25
0
  def processTree(self, node):
    '''
    Recursively walk the SVG tree and randomize all rock/pebble symbols on the way
    '''
    
    # Is this a symbol reference?
    if node.tag == inkex.addNS('use', 'svg'):
      # Is this one of our rock/pebble symbols?
      m = re.match('#(gr|un|)?([ra])b([0-9]+)[a-z]', str(node.get(inkex.addNS("href", "xlink"))))
      if m:
        # Add translation, if present
        x = float(node.get("x"))
        y = float(node.get("y"))
        
        if x <> 0 or y <> 0:
          node.set("x", "0")
          node.set("y", "0")
          currentTr = node.get("transform")
          if currentTr == None: currentTr = ""
          node.set("transform", currentTr + (" translate(%.6f, %.6f) " % (x, y)))

        # Get current symbol transform
        tr = SpeleoTransform.getTotalTransform(node)
        
        # Move it back to 0,0 for rotation
        simpletransform.applyTransformToNode(SpeleoTransform.invertTransform(tr), node)

        # Select a new, random symbol ID (matching the symbol family)
        new_id = m.group(1) + m.group(2) + "b" + m.group(3) + random.choice("abcdefghij")
        
        # Make sure the new symbol type is with us
        if self.ensureSymbol(new_id):
          node.set(inkex.addNS("href", "xlink"), "#" + new_id)
          # If not, we just leave the type as it is.

        # Apply random rotation
        simpletransform.applyTransformToNode(simpletransform.parseTransform("rotate(" + str(random.randint(0, 359)) + ")"), node)
        
        # Return the symbol to where it was
        simpletransform.applyTransformToNode(tr, node)


    # For compatibility with old maps, using speleoUIS3
    if (node.tag == inkex.addNS('tspan', 'svg') or node.tag == inkex.addNS('text', 'svg')) and node.text:
      if len(node.text) == 1:
        if node.text in string.ascii_lowercase:
          node.text = random.choice(string.ascii_lowercase)
        elif node.text in string.ascii_uppercase:
          node.text = random.choice(string.ascii_uppercase)
        if (node.text in string.ascii_letters):
          node.set("rotate",  str(random.randint(0, 359)))

    # Recurse!
    for child in node:
      self.processTree(child);
Пример #26
0
    def effect(self):
        pts = []
        for node in self.selected.itervalues():
            if node.tag == inkex.addNS('path','svg'):
                guide = node
                pts = get_n_points_from_path(node, 2)

        if len(pts) == 2:
    
            (x0, y0), (x1, y1) = pts
            theta = atan2(y1-y0, x1-x0)*180./pi
            length = ((x1-x0)**2 + (y1-y0)**2)**0.5
            
            label = inkex.etree.SubElement(self.current_layer, 'g')
            labeltag = inkex.etree.SubElement(label, 'g')
            
            
            if theta <= -90.0 or theta > 90.0:
                text, tw, th = self.make_text(anchor='end')
                applyTransformToNode(parseTransform('rotate(180.0)'), text)
            else:
                text, tw, th = self.make_text(anchor='start')
            
            fs = float(self.options.font_size)
            kh = 1.05
            h = kh*fs
            pad = (h - fs)*0.5 + 0.04*tw
            w = tw + pad*2
            x = -pad + 0.07*fs
            y = -0.5*h

            box = self.make_box(x, y, w, h, r=0.25*min(w, h))

            labeltag.append(box)
            labeltag.append(text)

            transform = 'translate(%f, 0.0)'% (length,)
            applyTransformToNode(parseTransform(transform), labeltag)
            
            leader = self.make_double_line(length+x)
            label.append(leader)

            transform = 'translate(%f, %f) rotate(%f)'%(x0, y0, theta)
            applyTransformToNode(parseTransform(transform), label)
        
            guide.getparent().remove(guide)
Пример #27
0
    def effect(self):
        pts = []
        for node in self.selected.itervalues():
            if node.tag == inkex.addNS('path', 'svg'):
                guide = node
                pts = get_n_points_from_path(node, 2)

        if len(pts) == 2:

            (x0, y0), (x1, y1) = pts
            theta = atan2(y1 - y0, x1 - x0) * 180. / pi
            length = ((x1 - x0)**2 + (y1 - y0)**2)**0.5

            label = inkex.etree.SubElement(self.current_layer, 'g')
            labeltag = inkex.etree.SubElement(label, 'g')

            if theta <= -90.0 or theta > 90.0:
                text, tw, th = self.make_text(anchor='end')
                applyTransformToNode(parseTransform('rotate(180.0)'), text)
            else:
                text, tw, th = self.make_text(anchor='start')

            fs = float(self.options.font_size)
            kh = 1.05
            h = kh * fs
            pad = (h - fs) * 0.5 + 0.04 * tw
            w = tw + pad * 2
            x = -pad + 0.07 * fs
            y = -0.5 * h

            box = self.make_box(x, y, w, h, r=0.25 * min(w, h))

            labeltag.append(box)
            labeltag.append(text)

            transform = 'translate(%f, 0.0)' % (length, )
            applyTransformToNode(parseTransform(transform), labeltag)

            leader = self.make_double_line(length + x)
            label.append(leader)

            transform = 'translate(%f, %f) rotate(%f)' % (x0, y0, theta)
            applyTransformToNode(parseTransform(transform), label)

            guide.getparent().remove(guide)
Пример #28
0
    def effect(self):

        if len(self.options.ids) < 2:
            inkex.errormsg(_("This extension requires two selected paths."))
            return
        self.prepareSelectionList()

        #center at (0,0)
        bbox = pathmodifier.computeBBox([self.patternNode])
        mat = [[1, 0, -(bbox[0] + bbox[1]) / 2],
               [0, 1, -(bbox[2] + bbox[3]) / 2]]
        if self.options.vertical:
            bbox = [-bbox[3], -bbox[2], bbox[0], bbox[1]]
            mat = simpletransform.composeTransform([[0, -1, 0], [1, 0, 0]],
                                                   mat)
        mat[1][2] += self.options.noffset
        simpletransform.applyTransformToNode(mat, self.patternNode)

        width = bbox[1] - bbox[0]
        dx = width + self.options.space

        #check if group and expand it
        patternList = []
        if self.options.grouppick and (self.patternNode.tag == inkex.addNS(
                'g', 'svg') or self.patternNode.tag == 'g'):
            mat = simpletransform.parseTransform(
                self.patternNode.get("transform"))
            for child in self.patternNode:
                simpletransform.applyTransformToNode(mat, child)
                patternList.append(child)
        else:
            patternList.append(self.patternNode)
        #inkex.debug(patternList)

        counter = 0
        for skelnode in self.skeletons.itervalues():
            self.curSekeleton = cubicsuperpath.parsePath(skelnode.get('d'))
            for comp in self.curSekeleton:
                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)
                if self.options.stretch:
                    dx = width + self.options.space
                    n = int(
                        (length - self.options.toffset + self.options.space) /
                        dx)
                    if n > 0:
                        dx = (length - self.options.toffset) / n

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

                s = self.options.toffset
                while s <= length:
                    mat = self.localTransformAt(s, self.options.follow)
                    if self.options.pickmode == "rand":
                        clone = copy.deepcopy(patternList[random.randint(
                            0,
                            len(patternList) - 1)])

                    if self.options.pickmode == "seq":
                        clone = copy.deepcopy(patternList[counter])
                        counter = (counter + 1) % len(patternList)

                    #!!!--> should it be given an id?
                    #seems to work without this!?!
                    myid = patternList[random.randint(0,
                                                      len(patternList) -
                                                      1)].tag.split('}')[-1]
                    clone.set("id", self.uniqueId(myid))
                    self.gNode.append(clone)

                    simpletransform.applyTransformToNode(mat, clone)

                    s += dx
        self.patternNode.getparent().remove(self.patternNode)
Пример #29
0
    def effect(self):

        #used in cycles
        scale_len_inc = self.options.in_length
        scale_len_dec = self.options.in_length
        scale_width_inc = self.options.in_width
        scale_width_dec = self.options.in_width

        #horizontal distance is set by user
        horiz = self.options.hor_dist
        #vertical is just to keep details on the same lines
        vert = (-20 / 3) * 2

        if self.selected:
            for id, node in self.selected.iteritems():

                #saving original for decreasing cycle
                initial_node = node

                #increasing sizes from current
                for n in range(self.options.in_size,
                               self.options.out_max_size):

                    #calculating length factor
                    scale_len_next = scale_len_inc + 20 / 3
                    scale_factor_length = scale_len_next / scale_len_inc
                    scale_len_inc = scale_len_next

                    #calculating width factor
                    scale_width_next = scale_width_inc + 1
                    scale_factor_width = scale_width_next / scale_width_inc
                    scale_width_inc = scale_width_next

                    #initializing tranformations

                    #horizontal transformation
                    str_hor_translation = 'translate(' + str(
                        self.unittouu(str(horiz) + "mm")) + ', ' + str(
                            self.unittouu(str(vert) + "mm")) + ')'
                    horiz_translation = simpletransform.parseTransform(
                        str_hor_translation)

                    #length transformation
                    str_scaling_length = 'scale(' + str(
                        scale_factor_length) + ')'
                    scaling_length = simpletransform.parseTransform(
                        str_scaling_length)

                    #width transformation
                    str_scaling_width = 'scale(' + str(
                        scale_factor_width) + ')'
                    scaling_width = simpletransform.parseTransform(
                        str_scaling_width)

                    #copying previous size and then applying transformation
                    new_node = copy.deepcopy(node)

                    #changing length
                    simpletransform.applyTransformToNode(
                        scaling_length, new_node)

                    #changing width
                    simpletransform.applyTransformToNode(
                        scaling_width, new_node)

                    #moving horizontally
                    simpletransform.applyTransformToNode(
                        horiz_translation, new_node)

                    #inserting detail in current layer
                    self.current_layer.append(new_node)

                    node = new_node

                #decreasing sizes from current
                for n in range(self.options.out_min_size,
                               self.options.in_size):

                    scale_len_prev = scale_len_dec - 20 / 3
                    scale_factor_length = scale_len_prev / scale_len_dec
                    scale_len_dec = scale_len_prev

                    scale_width_prev = scale_width_dec - 1
                    scale_factor_width = scale_width_prev / scale_width_dec
                    scale_width_dec = scale_width_prev

                    str_hor_translation = 'translate(' + str(
                        self.unittouu(str((-1) * horiz) + "mm")) + ', ' + str(
                            self.unittouu(str((-1) * vert) + "mm")) + ')'
                    horiz_translation = simpletransform.parseTransform(
                        str_hor_translation)

                    str_scaling_length = 'scale(' + str(
                        scale_factor_length) + ')'
                    scaling_length = simpletransform.parseTransform(
                        str_scaling_length)

                    str_scaling_width = 'scale(' + str(
                        scale_factor_width) + ')'
                    scaling_width = simpletransform.parseTransform(
                        str_scaling_width)

                    new_node = copy.deepcopy(initial_node)

                    simpletransform.applyTransformToNode(
                        scaling_length, new_node)

                    simpletransform.applyTransformToNode(
                        scaling_width, new_node)

                    simpletransform.applyTransformToNode(
                        horiz_translation, new_node)

                    self.current_layer.append(new_node)

                    initial_node = new_node
Пример #30
0
    def effect(self):

        if len(self.options.ids)<2:
            inkex.errormsg(_("This extension requires two selected paths."))
            return
        self.prepareSelectionList()
        
        #center at (0,0)
        bbox=pathmodifier.computeBBox([self.patternNode])
        mat=[[1,0,-(bbox[0]+bbox[1])/2],[0,1,-(bbox[2]+bbox[3])/2]]
        if self.options.vertical:
            bbox=[-bbox[3],-bbox[2],bbox[0],bbox[1]]
            mat=simpletransform.composeTransform([[0,-1,0],[1,0,0]],mat)
        mat[1][2] += self.options.noffset
        simpletransform.applyTransformToNode(mat,self.patternNode)
                
        width=bbox[1]-bbox[0]
        dx=width+self.options.space

		#check if group and expand it
        patternList = []
        if self.options.grouppick and (self.patternNode.tag == inkex.addNS('g','svg') or self.patternNode.tag=='g') :
            mat=simpletransform.parseTransform(self.patternNode.get("transform"))
            for child in self.patternNode:
                simpletransform.applyTransformToNode(mat,child)
                patternList.append(child)
        else :
            patternList.append(self.patternNode)
        #inkex.debug(patternList)
                
        counter=0
        for skelnode in self.skeletons.itervalues(): 
            self.curSekeleton=cubicsuperpath.parsePath(skelnode.get('d'))
            for comp in self.curSekeleton:
                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)
                if self.options.stretch:
                    dx=width+self.options.space
                    n=int((length-self.options.toffset+self.options.space)/dx)
                    if n>0:
                        dx=(length-self.options.toffset)/n


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

                s=self.options.toffset
                while s<=length:
                    mat=self.localTransformAt(s,self.options.follow)
                    if self.options.pickmode=="rand":
                        clone=copy.deepcopy(patternList[random.randint(0, len(patternList)-1)])

                    if self.options.pickmode=="seq":
                        clone=copy.deepcopy(patternList[counter])
                        counter=(counter+1)%len(patternList)
                        
                    #!!!--> should it be given an id?
                    #seems to work without this!?!
                    myid = patternList[random.randint(0, len(patternList)-1)].tag.split('}')[-1]
                    clone.set("id", self.uniqueId(myid))
                    self.gNode.append(clone)
                    
                    simpletransform.applyTransformToNode(mat,clone)

                    s+=dx
        self.patternNode.getparent().remove(self.patternNode)
Пример #31
0
 def effect(self):
     for node in self.selected.values():
         min_width_angle = rotate_helper.optimal_rotations(node)[0]
         if min_width_angle is not None:
             simpletransform.applyTransformToNode(
                 rotate_helper.rotate_matrix(node, min_width_angle), node)
Пример #32
0
    def beVerbose(self, dictCone, unitFactor, parent):
        """ Verbose output of calculated values. 
            Can be used for debugging purposes or if calculated values needed.
        """
        # unpack
        base_dia = dictCone['diaBase']
        cut_dia = dictCone['diaCut']
        cone_height = dictCone['heightCone']
        shortradius = dictCone['shortRadius']
        longradius = dictCone['longRadius']
        angle = dictCone['angle']
        chord_base = dictCone['chordBase']
        chord_cut = dictCone['chordCut']
        ptA = dictCone['ptA']
        ptB = dictCone['ptB']
        ptC = dictCone['ptC']
        ptD = dictCone['ptD']

        # styles for markup
        stroke_width = max(
            0.1,
            self.getUnittouu(
                str(self.options.strokeWidth / 2) + self.options.units))
        line_style = {
            'stroke': self.color_marker_dim,
            'stroke-width': str(stroke_width),
            'fill': 'none'
        }
        arrow_style = self.dimline_style
        font_height = min(
            32,
            max(
                8,
                int(self.getUnittouu(
                    str(longradius / 40) + self.options.units))))
        text_style = {
            'font-size': str(font_height),
            'font-family': 'arial',
            'text-anchor': 'middle',
            'text-align': 'center',
            'fill': self.color_marker_dim
        }
        # verbose message for debug window
        msg = "Base diameter: " + str(base_dia) + "Cut diameter: " + str(cut_dia) + \
              "\nCone height: " + str(cone_height) + "\nShort radius: " + str(shortradius) + \
              "\nLong radius: " + str(longradius) + "\nAngle of circle sector: " + str(angle) + \
              " radians (= " + str(math.degrees(angle)) + " degrees)" + \
              "\nChord length of base arc: " + str(chord_base) + \
              "\nChord length of cut arc: " + str(chord_cut)
        #inkex.debug( msg)

        # Mark center
        marker_length = max(5, longradius * unitFactor / 100)
        line_attribs = {
            'style': simplestyle.formatStyle(line_style),
            inkex.addNS('label', 'inkscape'): 'center',
            'd': 'M -{0},-{0} L {0},{0}'.format(marker_length)
        }
        line = inkex.etree.SubElement(parent, inkex.addNS('path', 'svg'),
                                      line_attribs)
        line_attribs = {
            'style': simplestyle.formatStyle(line_style),
            inkex.addNS('label', 'inkscape'): 'center',
            'd': 'M -{0},{0} L {0},-{0}'.format(marker_length)
        }
        line = inkex.etree.SubElement(parent, inkex.addNS('path', 'svg'),
                                      line_attribs)
        # Draw tick marks
        line_attribs = {
            'style': simplestyle.formatStyle(line_style),
            'd': 'M 0,-3 L 0,-30'
        }
        line = inkex.etree.SubElement(parent, inkex.addNS('path', 'svg'),
                                      line_attribs)
        if cut_dia != 0:
            line_attribs = {
                'style': simplestyle.formatStyle(line_style),
                'd': 'M {0},-3 L {0},-30'.format(shortradius * unitFactor)
            }
            line = inkex.etree.SubElement(parent, inkex.addNS('path', 'svg'),
                                          line_attribs)
        line_attribs = {
            'style': simplestyle.formatStyle(line_style),
            'd': 'M {0},-3 L {0},-30'.format(longradius * unitFactor)
        }
        line = inkex.etree.SubElement(parent, inkex.addNS('path', 'svg'),
                                      line_attribs)
        # span line
        arrow_style['stroke'] = self.color_marker_dim
        self.drawDimension((0, -10), (shortradius * unitFactor, -10),
                           arrow_style, parent)
        self.drawDimension((shortradius * unitFactor, -10),
                           (longradius * unitFactor, -10), arrow_style, parent)
        # labels for short, long radii
        if cut_dia >= 0.001:
            text_atts = {
                'style': simplestyle.formatStyle(text_style),
                'x': str(shortradius * unitFactor / 2),
                'y': str(-15)
            }
            text = inkex.etree.SubElement(parent, 'text', text_atts)
            text.text = "%4.3f" % (shortradius)
        text_atts = {
            'style': simplestyle.formatStyle(text_style),
            'x': str(
                (shortradius + (longradius - shortradius) / 2) * unitFactor),
            'y': str(-15)
        }
        text = inkex.etree.SubElement(parent, 'text', text_atts)
        text.text = "%4.3f" % (longradius)
        # Draw angle
        lowside = math.degrees(angle) < 180
        value = math.degrees(angle) if lowside else 360 - math.degrees(angle)
        # radial limit lines
        line_attribs = {
            'style': simplestyle.formatStyle(line_style),
            'd': 'M 3,0 L %4.2f,0' % (ptA[0] * unitFactor * 0.8)
        }
        line = inkex.etree.SubElement(parent, inkex.addNS('path', 'svg'),
                                      line_attribs)
        line_attribs = {
            'style':
            simplestyle.formatStyle(line_style),
            'd':
            'M %4.2f,%4.2f L %4.2f,%4.2f' %
            (ptD[0] * unitFactor * 0.02, ptD[1] * unitFactor * 0.02,
             ptD[0] * unitFactor * 0.8, ptD[1] * unitFactor * 0.8)
        }
        line = inkex.etree.SubElement(parent, inkex.addNS('path', 'svg'),
                                      line_attribs)
        # arc
        arc_rad = ptA[0] * unitFactor * 0.50
        gap = self.getUnittouu(str(font_height * 2) + "pt")
        textpos = self.drawDimArc((0, 0), 0, value, arc_rad, arrow_style,
                                  parent, gap, lowside)
        # angle label
        textpos[1] += font_height / 4 if lowside else font_height / 2
        text_atts = {
            'style': simplestyle.formatStyle(text_style),
            'x': str(textpos[0]),
            'y': str(textpos[1])
        }
        text = inkex.etree.SubElement(parent, 'text', text_atts)
        text.text = "%4.2f deg" % (value)
        # chord lines
        dash_style = deepcopy(arrow_style)
        dash_style['stroke'] = self.color_marker_chords
        dash_style['stroke-dasharray'] = '4, 2, 1, 2'
        line = self.drawDimension((ptA[0] * unitFactor, ptA[1] * unitFactor),
                                  (ptD[0] * unitFactor, ptD[1] * unitFactor),
                                  dash_style, parent)
        line = self.drawDimension((ptB[0] * unitFactor, ptB[1] * unitFactor),
                                  (ptC[0] * unitFactor, ptC[1] * unitFactor),
                                  dash_style, parent)
        # chord labels
        centerx = ptB[0] * unitFactor + (ptC[0] - ptB[0]) * unitFactor / 2
        centery = ptB[1] * unitFactor + (ptC[1] - ptB[1]) * unitFactor / 2
        line_angle = calc_angle_between_points(ptC, ptB)
        ypos = centery + font_height + 2 if line_angle < 0 else centery - 2
        text_style['fill'] = self.color_marker_chords
        text_atts = {
            'style': simplestyle.formatStyle(text_style),
            'transform': 'rotate(%f)' % (line_angle)
        }
        text = inkex.etree.SubElement(parent, 'text', text_atts)
        scale_matrix = [[1, 0.0, centerx], [0.0, 1,
                                            ypos]]  # needs cos,sin corrections
        simpletransform.applyTransformToNode(scale_matrix, text)
        text.text = "%4.2f" % (chord_base)
        if cut_dia >= 0.001:
            centerx = ptA[0] * unitFactor + (ptD[0] - ptA[0]) * unitFactor / 2
            centery = ptA[1] * unitFactor + (ptD[1] - ptA[1]) * unitFactor / 2
            xpos = centerx - font_height * math.sin(
                math.radians(abs(line_angle)))
            ypos = centery - 2 if line_angle > 0 else centery + font_height + 2
            text = inkex.etree.SubElement(parent, 'text', text_atts)
            scale_matrix = [[1, 0.0, centerx], [0.0, 1, ypos]]
            simpletransform.applyTransformToNode(scale_matrix, text)
            text.text = "%4.2f" % (chord_cut)
        # frustum lines
        frustrum_repos = [[1, 0.0, 1],
                          [
                              0.0, 1,
                              math.sqrt(
                                  pow(shortradius * unitFactor, 2) -
                                  pow(cut_dia * unitFactor / 2, 2))
                          ]]
        text_style['fill'] = self.color_marker_base
        line_style['stroke'] = self.color_marker_base
        arrow_style['stroke'] = self.color_marker_base
        line_attribs = {
            'style':
            simplestyle.formatStyle(line_style),
            'd':
            'M %f,%f L %f,%f %f,%f %f,%f z' %
            (-cut_dia / 2 * unitFactor, 0, cut_dia / 2 * unitFactor, 0,
             base_dia / 2 * unitFactor, cone_height * unitFactor,
             -base_dia / 2 * unitFactor, cone_height * unitFactor)
        }
        line = inkex.etree.SubElement(parent, inkex.addNS('path', 'svg'),
                                      line_attribs)
        simpletransform.applyTransformToNode(frustrum_repos, line)
        # ticks
        line_attribs = {
            'style':
            simplestyle.formatStyle(line_style),
            'd':
            'M %f,%f L %f,%f' % (-(5 + cut_dia / 2 * unitFactor), 0,
                                 -(5 + base_dia / 2 * unitFactor), 0)
        }
        line = inkex.etree.SubElement(parent, inkex.addNS('path', 'svg'),
                                      line_attribs)
        simpletransform.applyTransformToNode(frustrum_repos, line)
        #
        line = self.drawDimension(
            (-base_dia / 2 * unitFactor, 0),
            (-base_dia / 2 * unitFactor, cone_height * unitFactor),
            arrow_style, parent)
        simpletransform.applyTransformToNode(frustrum_repos, line)
        # frustum text
        text_atts = {
            'style': simplestyle.formatStyle(text_style),
            'x': str(-(18 + base_dia / 2 * unitFactor)),
            'y': str(cone_height * unitFactor / 2)
        }
        text = inkex.etree.SubElement(parent, 'text', text_atts)
        text.text = "%4.3f" % (cone_height)
        simpletransform.applyTransformToNode(frustrum_repos, text)
        if cut_dia >= 0.001:
            text_atts = {
                'style': simplestyle.formatStyle(text_style),
                'x': '0',
                'y': str(font_height)
            }
            text = inkex.etree.SubElement(parent, 'text', text_atts)
            text.text = "%4.3f" % (cut_dia)
            simpletransform.applyTransformToNode(frustrum_repos, text)
        text_atts = {
            'style': simplestyle.formatStyle(text_style),
            'x': '0',
            'y': str(cone_height * unitFactor + font_height)
        }
        text = inkex.etree.SubElement(parent, 'text', text_atts)
        text.text = "%4.3f" % (base_dia)
        simpletransform.applyTransformToNode(frustrum_repos, text)
Пример #33
0
    def beVerbose(self, dictCone, unitFactor, parent):
        """ Verbose output of calculated values. 
            Can be used for debugging purposes or if calculated values needed.
        """
        # unpack
        base_dia = dictCone['diaBase']
        cut_dia = dictCone['diaCut']
        cone_height = dictCone['heightCone']
        shortradius = dictCone['shortRadius']
        longradius = dictCone['longRadius']
        angle = dictCone['angle']
        chord_base = dictCone['chordBase']
        chord_cut = dictCone['chordCut']
        ptA = dictCone['ptA']
        ptB = dictCone['ptB']
        ptC = dictCone['ptC']
        ptD = dictCone['ptD']

        # styles for markup
        stroke_width = max(0.1, self.getUnittouu(str(self.options.strokeWidth/2) + self.options.units))
        line_style = { 'stroke': self.color_marker_dim, 'stroke-width': str(stroke_width), 'fill':'none' }
        arrow_style = self.dimline_style
        font_height = min(32, max( 8, int(self.getUnittouu(str(longradius/40) + self.options.units))))
        text_style = { 'font-size': str(font_height),
                       'font-family': 'arial',
                       'text-anchor': 'middle',
                       'text-align': 'center',
                       'fill': self.color_marker_dim }
        # verbose message for debug window
        msg = "Base diameter: " + str(base_dia) + "Cut diameter: " + str(cut_dia) + \
              "\nCone height: " + str(cone_height) + "\nShort radius: " + str(shortradius) + \
              "\nLong radius: " + str(longradius) + "\nAngle of circle sector: " + str(angle) + \
              " radians (= " + str(math.degrees(angle)) + " degrees)" + \
              "\nChord length of base arc: " + str(chord_base) + \
              "\nChord length of cut arc: " + str(chord_cut)
        #inkex.debug( msg)

        # Mark center
        marker_length = max(5, longradius* unitFactor/100)
        line_attribs = {'style' : simplestyle.formatStyle(line_style),
                        inkex.addNS('label','inkscape') : 'center',
                        'd' : 'M -{0},-{0} L {0},{0}'.format(marker_length)}
        line = inkex.etree.SubElement(parent, inkex.addNS('path','svg'), line_attribs)
        line_attribs = {'style' : simplestyle.formatStyle(line_style),
                        inkex.addNS('label','inkscape') : 'center',
                        'd' : 'M -{0},{0} L {0},-{0}'.format(marker_length)}
        line = inkex.etree.SubElement(parent, inkex.addNS('path','svg'), line_attribs)
        # Draw tick marks
        line_attribs = {'style' : simplestyle.formatStyle(line_style), 'd' : 'M 0,-3 L 0,-30'}
        line = inkex.etree.SubElement(parent, inkex.addNS('path','svg'), line_attribs)
        if cut_dia != 0:
            line_attribs = {'style' : simplestyle.formatStyle(line_style), 'd' : 'M {0},-3 L {0},-30'.format(shortradius * unitFactor)}
            line = inkex.etree.SubElement(parent, inkex.addNS('path','svg'), line_attribs)
        line_attribs = {'style' : simplestyle.formatStyle(line_style), 'd' : 'M {0},-3 L {0},-30'.format(longradius * unitFactor)}
        line = inkex.etree.SubElement(parent, inkex.addNS('path','svg'), line_attribs)
        # span line
        arrow_style['stroke'] = self.color_marker_dim
        self.drawDimension((0,-10), (shortradius * unitFactor, -10), arrow_style, parent)
        self.drawDimension((shortradius * unitFactor,-10), (longradius * unitFactor, -10), arrow_style, parent)
        # labels for short, long radii
        if cut_dia >= 0.001:
            text_atts = {'style':simplestyle.formatStyle(text_style),
                         'x': str(shortradius*unitFactor/2),
                         'y': str(-15) }
            text = inkex.etree.SubElement(parent, 'text', text_atts)
            text.text = "%4.3f" %(shortradius)
        text_atts = {'style':simplestyle.formatStyle(text_style),
                     'x': str((shortradius + (longradius-shortradius)/2)*unitFactor),
                     'y': str(-15) }
        text = inkex.etree.SubElement(parent, 'text', text_atts)
        text.text = "%4.3f" %(longradius)
        # Draw angle
        lowside = math.degrees(angle) < 180
        value = math.degrees(angle) if lowside else 360-math.degrees(angle)
        # radial limit lines
        line_attribs = {'style' : simplestyle.formatStyle(line_style), 'd' : 'M 3,0 L %4.2f,0' % (ptA[0]*unitFactor*0.8)}
        line = inkex.etree.SubElement(parent, inkex.addNS('path','svg'), line_attribs)
        line_attribs = {'style' : simplestyle.formatStyle(line_style), 'd' : 'M %4.2f,%4.2f L %4.2f,%4.2f' % (ptD[0]*unitFactor*0.02, ptD[1]*unitFactor*0.02,ptD[0]*unitFactor*0.8, ptD[1]*unitFactor*0.8)}
        line = inkex.etree.SubElement(parent, inkex.addNS('path','svg'), line_attribs)
        # arc
        arc_rad = ptA[0]*unitFactor*0.50
        gap = self.getUnittouu(str(font_height*2)+"pt")
        textpos = self.drawDimArc((0,0), 0, value, arc_rad, arrow_style, parent, gap, lowside)
        # angle label
        textpos[1] += font_height/4 if lowside else font_height/2
        text_atts = {'style':simplestyle.formatStyle(text_style),
                     'x': str(textpos[0]),
                     'y': str(textpos[1]) }
        text = inkex.etree.SubElement(parent, 'text', text_atts)
        text.text = "%4.2f deg" %(value)
        # chord lines
        dash_style = deepcopy(arrow_style)
        dash_style['stroke'] = self.color_marker_chords
        dash_style['stroke-dasharray'] = '4, 2, 1, 2'
        line = self.drawDimension((ptA[0]*unitFactor, ptA[1]*unitFactor), (ptD[0]*unitFactor, ptD[1]*unitFactor), dash_style, parent)
        line = self.drawDimension((ptB[0]*unitFactor, ptB[1]*unitFactor), (ptC[0]*unitFactor, ptC[1]*unitFactor), dash_style, parent)
        # chord labels
        centerx = ptB[0]*unitFactor + (ptC[0]-ptB[0])*unitFactor/2
        centery = ptB[1]*unitFactor + (ptC[1]-ptB[1])*unitFactor/2
        line_angle = calc_angle_between_points(ptC, ptB)
        ypos = centery+font_height+2 if line_angle<0 else centery-2
        text_style['fill'] = self.color_marker_chords
        text_atts = {'style':simplestyle.formatStyle(text_style),
                     'transform': 'rotate(%f)' % (line_angle) }
        text = inkex.etree.SubElement(parent, 'text', text_atts)
        scale_matrix = [[1, 0.0, centerx], [0.0, 1, ypos]] # needs cos,sin corrections
        simpletransform.applyTransformToNode(scale_matrix, text)
        text.text = "%4.2f" % (chord_base)
        if cut_dia >= 0.001:
            centerx = ptA[0]*unitFactor + (ptD[0]-ptA[0])*unitFactor/2
            centery = ptA[1]*unitFactor + (ptD[1]-ptA[1])*unitFactor/2
            xpos = centerx - font_height*math.sin(math.radians(abs(line_angle)))
            ypos = centery-2 if line_angle>0 else centery+font_height+2
            text = inkex.etree.SubElement(parent, 'text', text_atts)
            scale_matrix = [[1, 0.0, centerx], [0.0, 1, ypos]]
            simpletransform.applyTransformToNode(scale_matrix, text)
            text.text = "%4.2f" % (chord_cut)
        # frustum lines
        frustrum_repos = [[1, 0.0, 1], [0.0, 1, math.sqrt(pow(shortradius*unitFactor,2)-pow(cut_dia*unitFactor/2,2))]]
        text_style['fill'] = self.color_marker_base
        line_style['stroke'] = self.color_marker_base
        arrow_style['stroke'] = self.color_marker_base
        line_attribs = {'style': simplestyle.formatStyle(line_style),
                        'd': 'M %f,%f L %f,%f %f,%f %f,%f z' %(-cut_dia/2*unitFactor,0, cut_dia/2*unitFactor,0, base_dia/2*unitFactor,cone_height*unitFactor, -base_dia/2*unitFactor,cone_height*unitFactor)}
        line = inkex.etree.SubElement(parent, inkex.addNS('path','svg'), line_attribs)
        simpletransform.applyTransformToNode(frustrum_repos, line)
        # ticks
        line_attribs = {'style': simplestyle.formatStyle(line_style),
                        'd': 'M %f,%f L %f,%f' %(-(5+cut_dia/2*unitFactor),0, -(5+base_dia/2*unitFactor),0 )}
        line = inkex.etree.SubElement(parent, inkex.addNS('path','svg'), line_attribs)
        simpletransform.applyTransformToNode(frustrum_repos, line)
        #
        line = self.drawDimension((-base_dia/2*unitFactor,0), (-base_dia/2*unitFactor,cone_height*unitFactor), arrow_style, parent)
        simpletransform.applyTransformToNode(frustrum_repos, line)
        # frustum text
        text_atts = {'style':simplestyle.formatStyle(text_style),
                     'x': str(-(18+base_dia/2*unitFactor)),
                     'y': str(cone_height*unitFactor/2) }
        text = inkex.etree.SubElement(parent, 'text', text_atts)
        text.text = "%4.3f" %(cone_height)
        simpletransform.applyTransformToNode(frustrum_repos, text)
        if cut_dia >= 0.001:
            text_atts = {'style':simplestyle.formatStyle(text_style),
                         'x': '0',
                         'y': str(font_height) }
            text = inkex.etree.SubElement(parent, 'text', text_atts)
            text.text = "%4.3f" %(cut_dia)
            simpletransform.applyTransformToNode(frustrum_repos, text)
        text_atts = {'style':simplestyle.formatStyle(text_style),
                     'x': '0',
                     'y': str(cone_height*unitFactor+font_height) }
        text = inkex.etree.SubElement(parent, 'text', text_atts)
        text.text = "%4.3f" %(base_dia)
        simpletransform.applyTransformToNode(frustrum_repos, text)
Пример #34
0
    def effect(self):
        if len(self.options.ids) != 2:
            inkex.errormsg(_("This extension requires two selected objects. The first selected object must be the straight line with two nodes."))
            exit()

        # drawing that will be scaled is selected second, must be a single object
        scalepath = self.selected[self.options.ids[0]]
        drawing = self.selected[self.options.ids[1]]

        if scalepath.tag != inkex.addNS('path','svg'):
            inkex.errormsg(_("The first selected object is not a path.\nPlease select a straight line with two nodes instead."))
            exit()

        # apply its transforms to the scaling path, so we get the correct coordinates to calculate path length
        simpletransform.fuseTransform(scalepath)
        
        path = cubicsuperpath.parsePath(scalepath.get('d'))
        if len(path) < 1 or len(path[0]) < 2:
            inkex.errormsg(_("This extension requires that the first selected path be two nodes long."))
            exit()

        # calculate path length
        p1_x = path[0][0][1][0]
        p1_y = path[0][0][1][1]
        p2_x = path[0][1][1][0]
        p2_y = path[0][1][1][1]

        p_length = self.getUnittouu(str(distance((p1_x, p1_y),(p2_x, p2_y))) + self.getDocumentUnit())
        
        # Find Drawing Scale
        if self.options.choosescale == 'metric':
            drawing_scale = int(self.options.metric)
        elif self.options.choosescale == 'imperial':
            drawing_scale = int(self.options.imperial)
        elif self.options.choosescale == 'custom':
            drawing_scale = int(self.options.custom_scale)
        
        # calculate scaling center
        center = self.calc_scale_center(p1_x, p1_y, p2_x, p2_y)

        # calculate scaling factor
        target_length = self.getUnittouu(str(self.options.length) + self.options.unit)
        factor = (target_length / p_length) / drawing_scale
        # inkex.debug("%s, %s  %s" % (target_length, p_length, factor))
        
        # Add scale ruler
        if self.options.showscale == "true":
            dist = int(self.options.unitlength)
            
            ruler_length = self.getUnittouu(str(dist) + self.options.unit) / drawing_scale
            ruler_pos = (p1_x + (p2_x - p1_x)/2, (p1_y + (p2_y - p1_y)/2) - self.getUnittouu('4 mm'))
            
            # TODO: add into current layer instead
            self.create_ruler(self.document.getroot(), ruler_length, ruler_pos, dist, drawing_scale)

        # Get drawing and current transformations
        for obj in (scalepath, drawing):
            # Scale both objects about the center, first translate back to origin
            scale_matrix = [[1, 0.0, -center[0]], [0.0, 1, -center[1]]]
            simpletransform.applyTransformToNode(scale_matrix, obj)
            # Then scale
            scale_matrix = [[factor, 0.0, 0.0], [0.0, factor, 0.0]]
            simpletransform.applyTransformToNode(scale_matrix, obj)
            # Then translate back to original scale center location
            scale_matrix = [[1, 0.0, center[0]], [0.0, 1, center[1]]]
            simpletransform.applyTransformToNode(scale_matrix, obj)
Пример #35
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)
Пример #36
0
    def effect(self):

        docW = self.unittouu(self.document.getroot().get('width'))
        docH = self.unittouu(self.document.getroot().get('height'))

        boxW = self.unittouu( str(self.options.width)  + self.options.unit )
        boxH = self.unittouu( str(self.options.height) + self.options.unit )
        boxD = self.unittouu( str(self.options.depth)  + self.options.unit )
        tabProp = self.options.tabProportion
        tabH = boxD * tabProp

        box_id = self.uniqueId('box')
        self.box = g = inkex.etree.SubElement(self.current_layer, 'g', {'id':box_id})

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

        #self.createGuide( 0, docH, 0 );

        # Inner Close Tab
        line_path = [
                      [ 'M', [ boxW-(tabH*0.7),  0 ] ],
                      [ 'C', [ boxW-(tabH*0.25), 0, boxW, tabH*0.3, boxW, tabH*0.9 ] ],
                      [ 'L', [ boxW, tabH     ] ],
                      [ 'L', [ 0,    tabH     ] ],
                      [ 'L', [ 0,    tabH*0.9 ] ],
                      [ 'C', [ 0,    tabH*0.3, tabH*0.25, 0, tabH*0.7, 0 ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-inner-close-tab', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        lower_pos = boxD+tabH
        left_pos = 0

        #self.createGuide( 0, docH-tabH, 0 );

        # Upper Close Tab
        line_path = [
                      [ 'M', [ left_pos,        tabH      ] ],
                      [ 'L', [ left_pos + boxW, tabH      ] ],
                      [ 'L', [ left_pos + boxW, lower_pos ] ],
                      [ 'L', [ left_pos + 0,    lower_pos ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-upper-close-tab', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        left_pos += boxW

        # Upper Right Tab
        sideTabH = lower_pos - (boxW/2)
        if sideTabH < tabH: sideTabH = tabH
        line_path = [
                      [ 'M', [ left_pos,        sideTabH  ] ],
                      [ 'L', [ left_pos + (boxD*0.8), sideTabH  ] ],
                      [ 'L', [ left_pos + boxD, ((lower_pos*3)-sideTabH)/3 ] ],
                      [ 'L', [ left_pos + boxD, lower_pos ] ],
                      [ 'L', [ left_pos + 0,    lower_pos ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-upper-right-tab', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        left_pos += boxW + boxD

        # Upper Left Tab
        line_path = [
                      [ 'M', [ left_pos + boxD,       sideTabH  ] ],
                      [ 'L', [ left_pos + (boxD*0.2), sideTabH  ] ],
                      [ 'L', [ left_pos, ((lower_pos*3)-sideTabH)/3 ] ],
                      [ 'L', [ left_pos,              lower_pos ] ],
                      [ 'L', [ left_pos + boxD,       lower_pos ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-upper-left-tab', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        left_pos = 0

        #self.createGuide( 0, docH-tabH-boxD, 0 );

        # Right Tab
        line_path = [
                      [ 'M', [ left_pos,            lower_pos                   ] ],
                      [ 'L', [ left_pos - (boxD/2), lower_pos + (boxD/4)        ] ],
                      [ 'L', [ left_pos - (boxD/2), lower_pos + boxH - (boxD/4) ] ],
                      [ 'L', [ left_pos,            lower_pos + boxH            ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-left-tab', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        # Front
        line_path = [
                      [ 'M', [ left_pos,        lower_pos        ] ],
                      [ 'L', [ left_pos + boxW, lower_pos        ] ],
                      [ 'L', [ left_pos + boxW, lower_pos + boxH ] ],
                      [ 'L', [ left_pos,        lower_pos + boxH ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-front', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        left_pos += boxW

        # Right
        line_path = [
                      [ 'M', [ left_pos,        lower_pos        ] ],
                      [ 'L', [ left_pos + boxD, lower_pos        ] ],
                      [ 'L', [ left_pos + boxD, lower_pos + boxH ] ],
                      [ 'L', [ left_pos,        lower_pos + boxH ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-right', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        left_pos += boxD

        # Back
        line_path = [
                      [ 'M', [ left_pos,        lower_pos        ] ],
                      [ 'L', [ left_pos + boxW, lower_pos        ] ],
                      [ 'L', [ left_pos + boxW, lower_pos + boxH ] ],
                      [ 'L', [ left_pos,        lower_pos + boxH ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-back', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        left_pos += boxW

        # Left
        line_path = [
                      [ 'M', [ left_pos,        lower_pos        ] ],
                      [ 'L', [ left_pos + boxD, lower_pos        ] ],
                      [ 'L', [ left_pos + boxD, lower_pos + boxH ] ],
                      [ 'L', [ left_pos,        lower_pos + boxH ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-left', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        lower_pos += boxH
        left_pos = 0
        bTab = lower_pos + boxD
        if bTab > boxW / 2.5: bTab = boxW / 2.5

        # Bottom Front Tab
        line_path = [
                      [ 'M', [ left_pos,        lower_pos            ] ],
                      [ 'L', [ left_pos,        lower_pos + (boxD/2) ] ],
                      [ 'L', [ left_pos + boxW, lower_pos + (boxD/2) ] ],
                      [ 'L', [ left_pos + boxW, lower_pos            ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-bottom-front-tab', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        left_pos += boxW

        # Bottom Right Tab
        line_path = [
                      [ 'M', [ left_pos,        lower_pos        ] ],
                      [ 'L', [ left_pos,        lower_pos + bTab ] ],
                      [ 'L', [ left_pos + boxD, lower_pos + bTab ] ],
                      [ 'L', [ left_pos + boxD, lower_pos        ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-bottom-right-tab', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        left_pos += boxD

        # Bottom Back Tab
        line_path = [
                      [ 'M', [ left_pos,        lower_pos            ] ],
                      [ 'L', [ left_pos,        lower_pos + (boxD/2) ] ],
                      [ 'L', [ left_pos + boxW, lower_pos + (boxD/2) ] ],
                      [ 'L', [ left_pos + boxW, lower_pos            ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-bottom-back-tab', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        left_pos += boxW

        # Bottom Left Tab
        line_path = [
                      [ 'M', [ left_pos,        lower_pos        ] ],
                      [ 'L', [ left_pos,        lower_pos + bTab ] ],
                      [ 'L', [ left_pos + boxD, lower_pos + bTab ] ],
                      [ 'L', [ left_pos + boxD, lower_pos        ] ],
                      [ 'Z', [] ]
                    ]
        line_atts = { 'style':line_style, 'id':box_id+'-bottom-left-tab', 'd':formatPath(line_path) }
        inkex.etree.SubElement(g, inkex.addNS('path','svg'), line_atts )

        left_pos += boxD
        lower_pos += bTab

        g.set( 'transform', 'translate(%f,%f)' % ( (docW-left_pos)/2, (docH-lower_pos)/2 ) )

        # compensate preserved transforms of parent layer
        if self.current_layer.getparent() is not None:
            mat = simpletransform.composeParents(self.current_layer, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
            simpletransform.applyTransformToNode(simpletransform.invertTransform(mat), g)
Пример #37
0
    def drawGrid(self, x_center, y_center, doc_w, doc_h, pos_x=0, pos_y=0):

        if self.options.coords == "rotate":
            rot = " rotate(270)"
        else:
            rot = ""

        x_center -= pos_x
        y_center -= pos_y

        uufactor = self.getDocScale()

        uu_spacing = self.options.spacing / self.options.scale * 1000.0 * uufactor

        x_start = x_center - math.floor(x_center / uu_spacing) * uu_spacing
        y_start = y_center - math.floor(y_center / uu_spacing) * uu_spacing
        num_x = int(math.ceil(doc_w / uu_spacing))
        num_y = int(math.ceil(doc_h / uu_spacing))

        layer = self.currentLayer()

        g = inkex.etree.SubElement(layer, 'g')

        # Invert any sub-transforms of layer
        simpletransform.applyTransformToNode(
            SpeleoTransform.invertTransform(
                SpeleoTransform.getTotalTransform(g)), g)

        # Add translation
        simpletransform.applyTransformToNode(
            simpletransform.parseTransform("translate(%.6f, %.6f)" %
                                           (pos_x, pos_y)), g)

        if self.options.coords != "none":
            g.set(
                'style', 'stroke:#888;fill:#888;stroke-width:' +
                str(uufactor * 0.2) + 'px;font-size:' +
                str(self.options.fontsize * uufactor * 0.352778) +
                'px;text-anchor:end;text-align:end')

            cg = inkex.etree.SubElement(g, "g")
            g = inkex.etree.SubElement(g, "g")

            g.set('style', 'fill:none;')
            cg.set('style', 'stroke:none;stroke-width:0')
        else:
            g.set('style',
                  'stroke:#888;fill:none;stroke-width:' + str(uufactor * 0.2))

        # Vertical lines and coordinates
        for x in range(0, num_x):
            x = x_start + x * uu_spacing
            if x > doc_w: break

            if self.options.type == "line":
                l = inkex.etree.SubElement(g, 'path')
                l.set('d', 'M ' + str(x) + ",0 L " + str(x) + "," + str(doc_h))

            if self.options.coords != "none":
                l = inkex.etree.SubElement(cg, 'text')
                l.text = str(
                    int(
                        round((x - x_center) / uu_spacing *
                              self.options.spacing) +
                        self.options.origin_x)) + self.options.units
                l.set("style", "text-anchor:end;text-align:end")
                l.set("transform", ("translate(%.2f,%.2f)" + rot) %
                      (x - 1.4 * uufactor, 4.2 * uufactor))

        # Horizontal lines and coordinates
        for y in range(0, num_y):
            y = y_start + y * uu_spacing
            if y > doc_h: break

            if self.options.type == "line":
                l = inkex.etree.SubElement(g, 'path')
                l.set('d', 'M 0,' + str(y) + " L " + str(doc_w) + "," + str(y))

            if self.options.coords != "none":
                l = inkex.etree.SubElement(cg, 'text')
                l.text = str(
                    int(-round(
                        (y - y_center) / uu_spacing * self.options.spacing) +
                        self.options.origin_y)) + self.options.units
                l.set("style", "text-anchor:end;text-align:end")
                l.set(
                    "transform", "translate(%.2f,%.2f)" %
                    (12.7 * uufactor, y - 1.4 * uufactor))

        # Crosses, if requested
        if self.options.type == "cross":
            l = inkex.etree.SubElement(g, 'path')
            path_id = self.uniqueId("gridCross", True)
            l.set('d', "M -10,0 10,0 M 0,-10 0,10")
            l.set("transform", "translate(%.2f, %.2f)" % (x_center, y_center))
            l.set("id", path_id)

            for x in range(0, num_x):
                x_doc = x_start + x * uu_spacing - x_center
                if x_doc > doc_w: break

                for y in range(0, num_y):
                    if x == 0 and y == 0: continue

                    y_doc = y_start + y * uu_spacing - y_center
                    if y_doc > doc_h: break

                    l = inkex.etree.SubElement(g, 'use')
                    l.set(inkex.addNS('href', 'xlink'), '#' + str(path_id))
                    l.set("transform", "translate(%.2f,%.2f)" % (x_doc, y_doc))
 def moveNode(self, x, y, node, layer):
     transformation = 'translate(' + str(x) + ', ' + str(y) + ')'
     transform = simpletransform.parseTransform(transformation)
     simpletransform.applyTransformToNode(transform, node)
     layer.append(node)
Пример #39
0
    def effect(self):

        docW = self.unittouu(self.document.getroot().get('width'))
        docH = self.unittouu(self.document.getroot().get('height'))

        boxW = self.unittouu(str(self.options.width) + self.options.unit)
        boxH = self.unittouu(str(self.options.height) + self.options.unit)
        boxD = self.unittouu(str(self.options.depth) + self.options.unit)
        tabProp = self.options.tabProportion
        tabH = boxD * tabProp

        box_id = self.uniqueId('box')
        self.box = g = inkex.etree.SubElement(self.current_layer, 'g',
                                              {'id': box_id})

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

        #self.createGuide( 0, docH, 0 );

        # Inner Close Tab
        line_path = [['M', [boxW - (tabH * 0.7), 0]],
                     [
                         'C',
                         [
                             boxW - (tabH * 0.25), 0, boxW, tabH * 0.3, boxW,
                             tabH * 0.9
                         ]
                     ], ['L', [boxW, tabH]], ['L', [0, tabH]],
                     ['L', [0, tabH * 0.9]],
                     ['C', [0, tabH * 0.3, tabH * 0.25, 0, tabH * 0.7, 0]],
                     ['Z', []]]
        line_atts = {
            'style': line_style,
            'id': box_id + '-inner-close-tab',
            'd': formatPath(line_path)
        }
        inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts)

        lower_pos = boxD + tabH
        left_pos = 0

        #self.createGuide( 0, docH-tabH, 0 );

        # Upper Close Tab
        line_path = [['M', [left_pos, tabH]], ['L', [left_pos + boxW, tabH]],
                     ['L', [left_pos + boxW, lower_pos]],
                     ['L', [left_pos + 0, lower_pos]], ['Z', []]]
        line_atts = {
            'style': line_style,
            'id': box_id + '-upper-close-tab',
            'd': formatPath(line_path)
        }
        inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts)

        left_pos += boxW

        # Upper Right Tab
        sideTabH = lower_pos - (boxW / 2)
        if sideTabH < tabH: sideTabH = tabH
        line_path = [['M', [left_pos, sideTabH]],
                     ['L', [left_pos + (boxD * 0.8), sideTabH]],
                     [
                         'L',
                         [left_pos + boxD, ((lower_pos * 3) - sideTabH) / 3]
                     ], ['L', [left_pos + boxD, lower_pos]],
                     ['L', [left_pos + 0, lower_pos]], ['Z', []]]
        line_atts = {
            'style': line_style,
            'id': box_id + '-upper-right-tab',
            'd': formatPath(line_path)
        }
        inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts)

        left_pos += boxW + boxD

        # Upper Left Tab
        line_path = [['M', [left_pos + boxD, sideTabH]],
                     ['L', [left_pos + (boxD * 0.2), sideTabH]],
                     ['L', [left_pos, ((lower_pos * 3) - sideTabH) / 3]],
                     ['L', [left_pos, lower_pos]],
                     ['L', [left_pos + boxD, lower_pos]], ['Z', []]]
        line_atts = {
            'style': line_style,
            'id': box_id + '-upper-left-tab',
            'd': formatPath(line_path)
        }
        inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts)

        left_pos = 0

        #self.createGuide( 0, docH-tabH-boxD, 0 );

        # Right Tab
        line_path = [
            ['M', [left_pos, lower_pos]],
            ['L', [left_pos - (boxD / 2), lower_pos + (boxD / 4)]],
            ['L', [left_pos - (boxD / 2), lower_pos + boxH - (boxD / 4)]],
            ['L', [left_pos, lower_pos + boxH]], ['Z', []]
        ]
        line_atts = {
            'style': line_style,
            'id': box_id + '-left-tab',
            'd': formatPath(line_path)
        }
        inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts)

        # Front
        line_path = [['M', [left_pos, lower_pos]],
                     ['L', [left_pos + boxW, lower_pos]],
                     ['L', [left_pos + boxW, lower_pos + boxH]],
                     ['L', [left_pos, lower_pos + boxH]], ['Z', []]]
        line_atts = {
            'style': line_style,
            'id': box_id + '-front',
            'd': formatPath(line_path)
        }
        inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts)

        left_pos += boxW

        # Right
        line_path = [['M', [left_pos, lower_pos]],
                     ['L', [left_pos + boxD, lower_pos]],
                     ['L', [left_pos + boxD, lower_pos + boxH]],
                     ['L', [left_pos, lower_pos + boxH]], ['Z', []]]
        line_atts = {
            'style': line_style,
            'id': box_id + '-right',
            'd': formatPath(line_path)
        }
        inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts)

        left_pos += boxD

        # Back
        line_path = [['M', [left_pos, lower_pos]],
                     ['L', [left_pos + boxW, lower_pos]],
                     ['L', [left_pos + boxW, lower_pos + boxH]],
                     ['L', [left_pos, lower_pos + boxH]], ['Z', []]]
        line_atts = {
            'style': line_style,
            'id': box_id + '-back',
            'd': formatPath(line_path)
        }
        inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts)

        left_pos += boxW

        # Left
        line_path = [['M', [left_pos, lower_pos]],
                     ['L', [left_pos + boxD, lower_pos]],
                     ['L', [left_pos + boxD, lower_pos + boxH]],
                     ['L', [left_pos, lower_pos + boxH]], ['Z', []]]
        line_atts = {
            'style': line_style,
            'id': box_id + '-left',
            'd': formatPath(line_path)
        }
        inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts)

        lower_pos += boxH
        left_pos = 0
        bTab = lower_pos + boxD
        if bTab > boxW / 2.5: bTab = boxW / 2.5

        # Bottom Front Tab
        line_path = [['M', [left_pos, lower_pos]],
                     ['L', [left_pos, lower_pos + (boxD / 2)]],
                     ['L', [left_pos + boxW, lower_pos + (boxD / 2)]],
                     ['L', [left_pos + boxW, lower_pos]], ['Z', []]]
        line_atts = {
            'style': line_style,
            'id': box_id + '-bottom-front-tab',
            'd': formatPath(line_path)
        }
        inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts)

        left_pos += boxW

        # Bottom Right Tab
        line_path = [['M', [left_pos, lower_pos]],
                     ['L', [left_pos, lower_pos + bTab]],
                     ['L', [left_pos + boxD, lower_pos + bTab]],
                     ['L', [left_pos + boxD, lower_pos]], ['Z', []]]
        line_atts = {
            'style': line_style,
            'id': box_id + '-bottom-right-tab',
            'd': formatPath(line_path)
        }
        inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts)

        left_pos += boxD

        # Bottom Back Tab
        line_path = [['M', [left_pos, lower_pos]],
                     ['L', [left_pos, lower_pos + (boxD / 2)]],
                     ['L', [left_pos + boxW, lower_pos + (boxD / 2)]],
                     ['L', [left_pos + boxW, lower_pos]], ['Z', []]]
        line_atts = {
            'style': line_style,
            'id': box_id + '-bottom-back-tab',
            'd': formatPath(line_path)
        }
        inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts)

        left_pos += boxW

        # Bottom Left Tab
        line_path = [['M', [left_pos, lower_pos]],
                     ['L', [left_pos, lower_pos + bTab]],
                     ['L', [left_pos + boxD, lower_pos + bTab]],
                     ['L', [left_pos + boxD, lower_pos]], ['Z', []]]
        line_atts = {
            'style': line_style,
            'id': box_id + '-bottom-left-tab',
            'd': formatPath(line_path)
        }
        inkex.etree.SubElement(g, inkex.addNS('path', 'svg'), line_atts)

        left_pos += boxD
        lower_pos += bTab

        g.set(
            'transform', 'translate(%f,%f)' % ((docW - left_pos) / 2,
                                               (docH - lower_pos) / 2))

        # compensate preserved transforms of parent layer
        if self.current_layer.getparent() is not None:
            mat = simpletransform.composeParents(
                self.current_layer, [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]])
            simpletransform.applyTransformToNode(
                simpletransform.invertTransform(mat), g)
    def effect(self):
        if len(self.options.ids) != 2:
            inkex.errormsg(_("This extension requires two selected objects. The first selected object must be the straight line with two nodes."))
            exit()

        # drawing that will be scaled is selected second, must be a single object
        scalepath = self.selected[self.options.ids[0]]
        drawing = self.selected[self.options.ids[1]]

        if scalepath.tag != inkex.addNS('path','svg'):
            inkex.errormsg(_("The first selected object is not a path.\nPlease select a straight line with two nodes instead."))
            exit()

        # apply its transforms to the scaling path, so we get the correct coordinates to calculate path length
        simpletransform.fuseTransform(scalepath)
        
        path = cubicsuperpath.parsePath(scalepath.get('d'))
        if len(path) < 1 or len(path[0]) < 2:
            inkex.errormsg(_("This extension requires that the first selected path be two nodes long."))
            exit()

        # calculate path length
        p1_x = path[0][0][1][0]
        p1_y = path[0][0][1][1]
        p2_x = path[0][1][1][0]
        p2_y = path[0][1][1][1]

        p_length = self.getUnittouu(str(distance((p1_x, p1_y),(p2_x, p2_y))) + self.getDocumentUnit())
        
        # Find Drawing Scale
        if self.options.choosescale == 'metric':
            drawing_scale = int(self.options.metric)
        elif self.options.choosescale == 'imperial':
            drawing_scale = int(self.options.imperial)
        elif self.options.choosescale == 'custom':
            drawing_scale = self.options.custom_scale
        
        # calculate scaling center
        center = self.calc_scale_center(p1_x, p1_y, p2_x, p2_y)

        # calculate scaling factor
        target_length = self.getUnittouu(str(self.options.length) + self.options.unit)
        factor = (target_length / p_length) / drawing_scale
        # inkex.debug("%s, %s  %s" % (target_length, p_length, factor))
        
        # Add scale ruler
        if self.options.showscale == "true":
            dist = int(self.options.unitlength)
            
            ruler_length = self.getUnittouu(str(dist) + self.options.unit) / drawing_scale
            ruler_pos = (p1_x + (p2_x - p1_x)/2, (p1_y + (p2_y - p1_y)/2) - self.getUnittouu('4 mm'))
            
            # TODO: add into current layer instead
            self.create_ruler(self.document.getroot(), ruler_length, ruler_pos, dist, drawing_scale)

        # Get drawing and current transformations
        for obj in (scalepath, drawing):
            # Scale both objects about the center, first translate back to origin
            scale_matrix = [[1, 0.0, -center[0]], [0.0, 1, -center[1]]]
            simpletransform.applyTransformToNode(scale_matrix, obj)
            # Then scale
            scale_matrix = [[factor, 0.0, 0.0], [0.0, factor, 0.0]]
            simpletransform.applyTransformToNode(scale_matrix, obj)
            # Then translate back to original scale center location
            scale_matrix = [[1, 0.0, center[0]], [0.0, 1, center[1]]]
            simpletransform.applyTransformToNode(scale_matrix, obj)