コード例 #1
0
    def effect(self):
        xforms = []
        for i in range(self.NXFORM):
            if getattr(self.options, 'xform%d' % i):
                t = [
                    getattr(self.options, "%s%d" % (p, i))
                    for p in self.XFORM_PARAMS
                ]
                xforms.append(inkex.Transform(t))

        if not xforms:
            inkex.errormsg(_('There are no transforms to apply'))
            return False

        if not self.svg.selected:
            inkex.errormsg(_('There is no selection to duplicate'))
            return False

        nodes = self.svg.selected.values()
        grp = inkex.Group('IFS')
        layer = self.svg.get_current_layer().add(grp)

        for i in range(self.options.iter):
            n = []
            for node in nodes:
                for x in xforms:
                    d = node.copy()
                    d.transform = x * d.transform
                    n.append(d)
            g = inkex.Group('IFS iter %d' % i)
            g.add(*n)
            grp.add(g)
            nodes = n

        return True
コード例 #2
0
    def update_lettering(self, raise_error=False):
        del self.group[:]

        if self.settings.scale == 100:
            destination_group = self.group
        else:
            destination_group = inkex.Group(
                attrib={
                    # L10N The user has chosen to scale the text by some percentage
                    # (50%, 200%, etc).  If you need to use the percentage symbol,
                    # make sure to double it (%%).
                    INKSCAPE_LABEL: _("Text scale %s%%") % self.settings.scale
                })
            self.group.append(destination_group)

        font = self.fonts.get(self.font_chooser.GetValue(), self.default_font)
        try:
            font.render_text(self.settings.text,
                             destination_group,
                             back_and_forth=self.settings.back_and_forth,
                             trim=self.settings.trim)
        except FontError as e:
            if raise_error:
                inkex.errormsg(
                    "Error: Text cannot be applied to the document.\n%s" % e)
                return
            else:
                pass

        if self.settings.scale != 100:
            destination_group.attrib['transform'] = 'scale(%s)' % (
                self.settings.scale / 100.0)
コード例 #3
0
    def write_month_header(self, g, m):
        txt_atts = {'style': str(inkex.Style(self.style_month)),
                    'x': str(-self.day_w / 3),
                    'y': str(self.day_h / 5)}
        try:
            text = unicode(self.options.month_names[m - 1], self.options.input_encode)
            if self.options.primary_calendar == "hijri":
                text = unicode(self.options.hijri_month_names[m - 1], self.options.input_encode)
            g.add(TextElement(**txt_atts)).text = text
        except:
            raise ValueError('You must select a correct system encoding.')

        gw = g.add(inkex.Group())
        week_x = 0
        if self.options.start_day == 'sun':
            day_names = self.options.day_names[:]
        else:
            day_names = self.options.day_names[1:]
            day_names.append(self.options.day_names[0])

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

        for wday in day_names:
            txt_atts = {'style': str(inkex.Style(self.style_day_name)),
                        'x': str(self.day_w * week_x),
                        'y': str(self.day_h)}
            try:
                gw.add(TextElement(**txt_atts)).text = unicode(
                    wday, self.options.input_encode)
            except:
                raise ValueError('You must select a correct system encoding.')

            week_x += 1
コード例 #4
0
    def get_or_create_group(self):
        if self.svg.selected:
            groups = set()

            for node in self.svg.selected.values():
                if node.tag == SVG_GROUP_TAG and INKSTITCH_LETTERING in node.attrib:
                    groups.add(node)

                for group in node.iterancestors(SVG_GROUP_TAG):
                    if INKSTITCH_LETTERING in group.attrib:
                        groups.add(group)

            if len(groups) > 1:
                inkex.errormsg(_("Please select only one block of text."))
                sys.exit(1)
            elif len(groups) == 0:
                inkex.errormsg(
                    _("You've selected objects that were not created by the Lettering extension.  "
                      "Please clear your selection or select different objects before running Lettering again."
                      ))
                sys.exit(1)
            else:
                return list(groups)[0]
        else:
            group = inkex.Group(
                attrib={
                    INKSCAPE_LABEL:
                    _("Ink/Stitch Lettering"),
                    "transform":
                    get_correction_transform(self.get_current_layer(),
                                             child=True)
                })
            self.get_current_layer().append(group)
            return group
コード例 #5
0
 def draw_coluor_bars(self, cx, cy, rotate, name, parent, bbox):
     group = parent.add(inkex.Group(id=name))
     group.transform = inkex.Transform(translate=(cx, cy)) * inkex.Transform(rotate=rotate)
     loc = 0
     if bbox:
         loc = min(self.mark_size / 3, max(bbox.width, bbox.height) / 45)
     for bar in [{'c': '*', 'stroke': '#000', 'x': 0, 'y': -(loc + 1)},
                 {'c': 'r', 'stroke': '#0FF', 'x': 0, 'y': 0},
                 {'c': 'g', 'stroke': '#F0F', 'x': (loc * 11) + 1, 'y': -(loc + 1)},
                 {'c': 'b', 'stroke': '#FF0', 'x': (loc * 11) + 1, 'y': 0}
                 ]:
         i = 0
         while i <= 1:
             color = inkex.Color('white')
             if bar['c'] == 'r' or bar['c'] == '*':
                 color.red = 255 * i
             if bar['c'] == 'g' or bar['c'] == '*':
                 color.green = 255 * i
             if bar['c'] == 'b' or bar['c'] == '*':
                 color.blue = 255 * i
             r_att = {'fill': str(color),
                      'stroke': bar['stroke'],
                      'stroke-width': loc/8,
                      'x': str((loc * i * 10) + bar['x']), 'y': str(bar['y']),
                      'width': loc, 'height': loc}
             rect = Rectangle()
             for att, value in r_att.items():
                 rect.set(att, value)
             group.add(rect)
             i += 0.1
コード例 #6
0
ファイル: base.py プロジェクト: hasantahir/myinkspace
    def _expand_defs(root):
        from inkex import Transform, ShapeElement
        from copy import deepcopy
        for el in root:
            if isinstance(el, inkex.Use):
                # <group> element will replace <use> node
                group = inkex.Group()

                # add all objects from symbol node
                for obj in el.href:
                    group.append(deepcopy(obj))

                # translate group
                group.transform = Transform(translate=(float(el.attrib["x"]),
                                                       float(el.attrib["y"])))

                # replace use node with group node
                parent = el.getparent()
                parent.remove(el)
                parent.add(group)

                el = group  # required for recursive defs

            # expand children defs
            TexTextElement._expand_defs(el)
コード例 #7
0
    def csp_to_path(self, node, csp_list, transform=None):
        """Create new paths based on csp data, return group with paths."""
        # set up stroke width, group
        stroke_width = self.svg.unittouu('1px')
        stroke_color = '#000000'
        style = {
            'fill': 'none',
            'stroke': stroke_color,
            'stroke-width': str(stroke_width),
        }

        group = inkex.Group()
        # apply gradientTransform and node's preserved transform to group
        group.transform = transform * node.transform

        # convert each csp to path, append to group
        for csp in csp_list:
            elem = group.add(inkex.PathElement())
            elem.style = style
            elem.path = inkex.CubicSuperPath(csp)
            if self.options.mode == 'outline':
                elem.path.close()
            elif self.options.mode == 'faces':
                if len(csp) == 1 and len(csp[0]) == 5:
                    elem.path.close()
        return group
コード例 #8
0
    def effect(self):
        if len(self.svg.selected) == 0:
            inkex.errormsg("Please select some paths first.")
            exit()

        path_attribute = self.options.path_attribute
        is_text_attribute = path_attribute in ['id', 'label']
        for id, node in self.svg.selection.filter(inkex.PathElement).items():
            to_show = self.extract_path_attribute(path_attribute, node)

            node.path.transform(node.composed_transform()).to_superpath()
            bbox = node.bounding_box()
            tx, ty = bbox.center

            if self.options.group:
                group_element = node.getparent().add(inkex.Group())
                group_element.add(node)
                group_element.set('id', node.get('id') + "_group")
                text_element = group_element.add(inkex.TextElement())
            else:
                text_element = node.getparent().add(inkex.TextElement())

            tspan_element = text_element.add(inkex.Tspan())
            tspan_element.set('sodipodi:role', 'line')
            styles = {
                'text-align': 'center',
                'vertical-align': 'bottom',
                'text-anchor': 'middle',
                'font-size': str(self.options.fontsize) + 'px',
                'font-weight': self.options.fontweight,
                'font-style': 'normal',
                'font-family': self.options.font,
                'fill': str(self.options.color)
            }
            tspan_element.set('style', str(inkex.Style(styles)))
            tspan_element.set('dy', '0')

            if is_text_attribute:
                if self.options.capitals:
                    to_show = to_show.upper()

                if self.options.matchre != '':
                    matches = re.findall(self.options.matchre, to_show)
                    if len(matches) > 0:
                        to_show = matches[0]

                if self.options.replaced != '':
                    to_show = to_show.replace(self.options.replaced,
                                              self.options.replacewith)

            tspan_element.text = to_show
            tspan_element.set('id', node.get('id') + "_tspan")
            text_element.set('id', node.get('id') + "_text")
            text_element.set('x', str(tx))
            text_element.set('y', str(ty))
            text_element.set(
                'transform',
                'rotate(%s, %s, %s)' % (-int(self.options.angle), tx, ty))
コード例 #9
0
    def effect(self):
        delx = math.cos(math.radians(
            self.options.angle)) * self.options.magnitude
        dely = math.sin(math.radians(
            self.options.angle)) * self.options.magnitude
        for node in self.svg.selection.filter(inkex.PathElement):
            group = node.getparent().add(inkex.Group())
            facegroup = group.add(inkex.Group())
            group.append(node)

            if node.transform:
                group.transform = node.transform
                node.transform = None

            facegroup.style = node.style

            for cmd_proxy in node.path.to_absolute().proxy_iterator():
                self.process_segment(cmd_proxy, facegroup, delx, dely)
コード例 #10
0
def create_new_group(parent, insert_index):
    group = inkex.Group(
        attrib={
            INKSCAPE_LABEL: _("Auto-Satin"),
            "transform": get_correction_transform(parent, child=True)
        })
    parent.insert(insert_index, group)

    return group
コード例 #11
0
    def get_group(self, node):
        """
        make a clipped group, clip with clone of original, clipped group
        include original and group of paths.
        """
        defs = self.svg.defs
        clip = defs.add(ClipPath())
        new_node = clip.add(node.copy())
        clip_group = node.getparent().add(inkex.Group())
        group = clip_group.add(inkex.Group())
        clip_group.set('clip-path', clip.get_id(as_url=2))

        # make a blur filter reference by the style of each path
        filt = defs.add(Filter(x='-0.5', y='-0.5',\
            height=str(self.options.blurheight),\
            width=str(self.options.blurwidth)))

        filt.add_primitive('feGaussianBlur', stdDeviation=self.options.stddev)
        return group, inkex.Style(filter=filt.get_id(as_url=2))
コード例 #12
0
ファイル: path_number_nodes.py プロジェクト: wachin/inkscape
    def add_dot(self, node):
        """Add a dot label for this path element"""
        group = node.getparent().add(inkex.Group())
        dot_group = group.add(inkex.Group())
        num_group = group.add(inkex.Group())
        group.transform = node.transform

        style = inkex.Style({'stroke': 'none', 'fill': '#000'})

        for step, (x, y) in enumerate(node.path.end_points):
            circle = dot_group.add(Circle(cx=str(x), cy=str(y),\
                    r=str(self.svg.unittouu(self.options.dotsize) / 2)))
            circle.style = style
            num_group.append(
                self.add_text(
                    x + (self.svg.unittouu(self.options.dotsize) / 2),
                    y - (self.svg.unittouu(self.options.dotsize) / 2),
                    self.options.start + (self.options.step * step)))

        node.delete()
コード例 #13
0
    def create_troubleshoot_layer(self):
        svg = self.document.getroot()
        layer = svg.find(".//*[@id='__validation_layer__']")

        if layer is None:
            layer = inkex.Group(attrib={
                'id': '__validation_layer__',
                INKSCAPE_LABEL: _('Troubleshoot'),
                INKSCAPE_GROUPMODE: 'layer',
            })
            svg.append(layer)
        else:
            # Clear out everything from the last run
            del layer[:]

        add_layer_commands(layer, ["ignore_layer"])

        error_group = inkex.Group(attrib={
            "id": '__validation_errors__',
            INKSCAPE_LABEL: _("Errors"),
        })
        layer.append(error_group)

        warning_group = inkex.Group(attrib={
            "id": '__validation_warnings__',
            INKSCAPE_LABEL: _("Warnings"),
        })
        layer.append(warning_group)

        type_warning_group = inkex.Group(attrib={
            "id": '__validation_ignored__',
            INKSCAPE_LABEL: _("Type Warnings"),
        })
        layer.append(type_warning_group)

        self.troubleshoot_layer = layer
        self.error_group = error_group
        self.warning_group = warning_group
        self.type_warning_group = type_warning_group
コード例 #14
0
ファイル: paperfold.py プロジェクト: hasantahir/myinkspace
    def effect(self):
        mesh = om.read_trimesh(self.options.inputfile)
        fullUnfolded, unfoldedComponents = unfold(mesh)
        # Compute maxSize of the components
        # All components must be scaled to the same size as the largest component
        maxSize = 0
        for unfolding in unfoldedComponents:
            [xmin, ymin, boxSize] = findBoundingBox(unfolding[0])
            if boxSize > maxSize:
                maxSize = boxSize

        # Create a new container group to attach all paperfolds
        paperfoldMainGroup = self.document.getroot().add(
            inkex.Group(id=self.svg.get_unique_id(
                "paperfold-")))  #make a new group at root level
        for i in range(len(unfoldedComponents)):
            paperfoldPageGroup = writeSVG(self, unfoldedComponents[i], maxSize,
                                          self.options.printNumbers)
            #translate the groups next to each other to remove overlappings
            if i != 0:
                previous_bbox = paperfoldMainGroup[i - 1].bounding_box()
                this_bbox = paperfoldPageGroup.bounding_box()
                paperfoldPageGroup.set(
                    "transform", "translate(" +
                    str(previous_bbox.left + previous_bbox.width -
                        this_bbox.left) + ", 0.0)")
            paperfoldMainGroup.append(paperfoldPageGroup)

        #apply scale factor
        translation_matrix = [[self.options.scalefactor, 0.0, 0.0],
                              [0.0, self.options.scalefactor, 0.0]]
        paperfoldMainGroup.transform = Transform(
            translation_matrix) * paperfoldMainGroup.transform
        #paperfoldMainGroup.set('transform', 'scale(%f,%f)' % (self.options.scalefactor, self.options.scalefactor))

        #adjust canvas to the inserted unfolding
        if self.options.resizetoimport:
            bbox = paperfoldMainGroup.bounding_box()
            namedView = self.document.getroot().find(
                inkex.addNS('namedview', 'sodipodi'))
            doc_units = namedView.get(inkex.addNS('document-units',
                                                  'inkscape'))
            root = self.svg.getElement('//svg:svg')
            offset = self.svg.unittouu(
                str(self.options.extraborder) + self.options.extraborder_units)
            root.set(
                'viewBox', '%f %f %f %f' %
                (bbox.left - offset, bbox.top - offset,
                 bbox.width + 2 * offset, bbox.height + 2 * offset))
            root.set('width', str(bbox.width + 2 * offset) + doc_units)
            root.set('height', str(bbox.height + 2 * offset) + doc_units)
コード例 #15
0
def add_group(document, node, command):
    parent = node.getparent()
    group = inkex.Group(
        attrib={
            "id":
            generate_unique_id(document, "command_group"),
            INKSCAPE_LABEL:
            _("Ink/Stitch Command") +
            ": %s" % get_command_description(command),
            "transform":
            get_correction_transform(node)
        })
    parent.insert(parent.index(node) + 1, group)
    return group
コード例 #16
0
ファイル: rendering.py プロジェクト: luzpaz/inkstitch
def render_stitch_plan(svg,
                       stitch_plan,
                       realistic=False,
                       visual_commands=True):
    layer = svg.find(".//*[@id='__inkstitch_stitch_plan__']")
    if layer is None:
        layer = inkex.Group(
            attrib={
                'id': '__inkstitch_stitch_plan__',
                INKSCAPE_LABEL: _('Stitch Plan'),
                INKSCAPE_GROUPMODE: 'layer'
            })
    else:
        # delete old stitch plan
        del layer[:]

        # make sure the layer is visible
        layer.set('style', 'display:inline')

    svg.append(layer)

    for i, color_block in enumerate(stitch_plan):
        group = inkex.Group(
            attrib={
                'id': '__color_block_%d__' % i,
                INKSCAPE_LABEL: "color block %d" % (i + 1)
            })
        layer.append(group)
        if realistic:
            color_block_to_realistic_stitches(color_block, svg, group)
        else:
            color_block_to_paths(color_block, svg, group, visual_commands)

    if realistic:
        filter_document = inkex.load_svg(realistic_filter)
        svg.defs.append(filter_document.getroot())
コード例 #17
0
    def effect(self):
        font_dir = self.options.font_dir
        file_format = self.options.file_format

        if not os.path.isdir(font_dir):
            errormsg(
                _("Font directory not found. Please specify an existing directory."
                  ))

        glyphs = list(Path(font_dir).rglob(file_format))
        if not glyphs:
            glyphs = list(Path(font_dir).rglob(file_format.lower()))

        document = self.document.getroot()
        for glyph in glyphs:
            letter = self.get_glyph_element(glyph)
            label = "GlyphLayer-%s" % letter.get(INKSCAPE_LABEL,
                                                 ' ').split('.')[0][-1]
            group = inkex.Group(
                attrib={
                    INKSCAPE_LABEL: label,
                    INKSCAPE_GROUPMODE: "layer",
                    "transform": get_correction_transform(document, child=True)
                })

            # remove color block groups if we import without commands
            # there will only be one object per color block anyway
            if not self.options.import_commands:
                for element in letter.iter(SVG_PATH_TAG):
                    group.insert(0, element)
            else:
                group.insert(0, letter)

            document.insert(0, group)
            group.set('style', 'display:none')

        # users may be confused if they get an empty document
        # make last letter visible again
        group.set('style', None)

        # In most cases trims are inserted with the imported letters.
        # Let's make sure the trim symbol exists in the defs section
        ensure_symbol(document, 'trim')

        self.insert_baseline(document)
コード例 #18
0
 def effect(self):
     self.validate_options()
     self.calculate_size_and_positions()
     parent = self.document.getroot()
     txt_atts = {'id': 'year_' + str(self.options.year)}
     self.year_g = parent.add(inkex.Group(**txt_atts))
     txt_atts = {'style': str(inkex.Style(self.style_year)),
                 'x': str(self.doc_w / 2),
                 'y': str(self.day_w * 1.5)}
     self.year_g.add(TextElement(**txt_atts)).text = str(self.options.year)
     try:
         if self.options.month == 0:
             for m in range(1, 13):
                 self.create_month(m)
         else:
             self.create_month(self.options.month)
     except ValueError as err:
         return inkex.errormsg(str(err))
コード例 #19
0
    def effect(self):
        dot_group = self.svg.add(inkex.Group())

        for node in self.svg.get_selected(
                inkex.PathElement
        ):  #works for InkScape (1:1.0+devel+202008292235+eff2292935) @ Linux and for Windows (but with deprecation)
            #for node in self.svg.selection.filter(inkex.PathElement).values(): #works for InkScape 1.1dev (9b1fc87, 2020-08-27)) @ Windows
            points = list(node.path.end_points)
            start = points[0]
            end = points[len(points) - 1]

            if start[0] == end[0] and start[1] == end[1]:
                self.drawCircle(dot_group, '#00FF00', start)
                self.drawCircle(
                    dot_group, '#FFFF00', points[1]
                )  #draw one point which gives direction of the path
            else:  #open contour with start and end point
                self.drawCircle(dot_group, '#FF0000', start)
                self.drawCircle(dot_group, '#0000FF', end)
コード例 #20
0
    def _render_line(self, line, position, glyph_set):
        """Render a line of text.

        An SVG XML node tree will be returned, with an svg:g at its root.  If
        the font metadata requests it, Auto-Satin will be applied.

        Parameters:
            line -- the line of text to render.
            position -- Current position.  Will be updated to point to the spot
                        immediately after the last character.
            glyph_set -- a FontVariant instance.

        Returns:
            An svg:g element containing the rendered text.
        """

        group = inkex.Group(attrib={INKSCAPE_LABEL: line})

        last_character = None
        for character in line:
            if self.letter_case == "upper":
                character = character.upper()
            elif self.letter_case == "lower":
                character = character.lower()

            glyph = glyph_set[character]

            if character == " " or (glyph is None
                                    and self.default_glyph == " "):
                position.x += self.word_spacing
                last_character = None
            else:
                if glyph is None:
                    glyph = glyph_set[self.default_glyph]

                if glyph is not None:
                    node = self._render_glyph(glyph, position, character,
                                              last_character)
                    group.append(node)

                last_character = character

        return group
コード例 #21
0
    def effect(self):
        if len(self.svg.selected) != 2:
            inkex.errormsg(
                "Please select exact two objects:\n1. object representing path,\n2. object representing dots."
            )
            return

        nodes = list(self.svg.selected.items())
        iddot = nodes[0][0]
        idpath = nodes[1][0]
        dot = self.svg.selected[iddot]
        path = self.svg.selected[idpath]
        self.svg.selected.popitem()
        self.svg.selected.popitem()
        bb = dot.bounding_box()
        parent = path.find('..')
        group = inkex.Group()
        parent.add(group)

        end_points = list(path.path.end_points)
        control_points = []
        for cp in path.path.control_points:
            is_endpoint = False
            for ep in end_points:
                if cp.x == ep.x and cp.y == ep.y:
                    is_endpoint = True
                    break
            if not is_endpoint:
                control_points.append(cp)

        pointlist = []
        if self.options.endpoints:
            pointlist += end_points
        if self.options.controlpoints:
            pointlist += control_points
        for point in pointlist:
            clone = inkex.Use()
            clone.set('xlink:href', '#' + iddot)
            clone.set('x', point.x - bb.center.x)
            clone.set('y', point.y - bb.center.y)
            group.add(clone)
コード例 #22
0
ファイル: wireframe_sphere.py プロジェクト: wachin/inkscape
    def longitude_lines(self, number, tilt, radius, rotate):
        """Add lines of latitude as a group"""
        # GROUP FOR THE LINES OF LONGITUDE
        grp_long = inkex.Group()
        grp_long.set('inkscape:label', 'Lines of Longitude')

        # angle between neighbouring lines of longitude in degrees
        #delta_long = 360.0 / number

        for i in range(0, number // 2):
            # The longitude of this particular line in radians
            long_angle = rotate + (i * (360.0 / number)) * (pi / 180.0)
            if long_angle > pi:
                long_angle -= 2 * pi
            # the rise is scaled by the sine of the tilt
            # length     = sqrt(width*width+height*height)  #by pythagorean theorem
            # inverse    = sin(acos(length/so.RADIUS))
            inverse = abs(sin(long_angle)) * cos(tilt)

            rads = (radius * inverse + EPSILON, radius)

            # The rotation of the ellipse to get it to pass through the pole (degs)
            rotation = atan((radius * sin(long_angle) * sin(tilt)) /
                            (radius * cos(long_angle))) * (180.0 / pi)

            # remove the hidden side of the ellipses if required
            # this is always exactly half the ellipse, but we need to find out which half
            start_end = (0, 2 * pi
                         )  # Default start and end angles -> full ellipse
            if self.options.HIDE_BACK:
                if long_angle <= pi / 2:  # cut out the half ellispse that is hidden
                    start_end = (pi / 2, 3 * pi / 2)
                else:
                    start_end = (3 * pi / 2, pi / 2)

            # finally, draw the line of longitude
            # the centre is always at the centre of the sphere
            elem = grp_long.add(self.draw_ellipse(rads, (0, 0), start_end))
            # the rotation will be applied about the group centre (the centre of the sphere)
            elem.transform = inkex.Transform(rotate=(rotation, ))
        return grp_long
コード例 #23
0
    def effect(self):
        if not self.svg.selected:
            raise inkex.AbortExtension(
                _('You must to select some "Slicer rectangles" '
                  'or other "Layout groups".'))

        base_elements = self.get_slicer_layer().descendants()
        for key, node in self.svg.selected.id_dict().items():
            if node not in base_elements:
                raise inkex.AbortExtension(
                    _(f'The element "{key}" is not in the Web Slicer layer'))
            g_parent = node.getparent()

        group = g_parent.add(inkex.Group())
        desc = group.add(inkex.Desc())
        desc.text = self.get_conf_text_from_list([
            'html_id', 'html_class', 'width_unity', 'height_unity', 'bg_color'
        ])

        for node in self.svg.selected.values():
            group.insert(1, node)
コード例 #24
0
 def draw_reg_marks(self, cx, cy, rotate, name, parent):
     colours = ['#000000', '#00ffff', '#ff00ff', '#ffff00', '#000000']
     g = parent.add(inkex.Group(id=name))
     for i in range(len(colours)):
         style = {'fill': colours[i], 'fill-opacity': '1', 'stroke': 'none'}
         r = (self.mark_size / 2)
         step = r
         stroke = r / len(colours)
         regoffset = stroke * i
         regmark_attribs = {'style': str(inkex.Style(style)),
                            'd': 'm' +
                                 ' ' + str(-regoffset) + ',' + str(r) +
                                 ' ' + str(-stroke) + ',0' +
                                 ' ' + str(step) + ',' + str(-r) +
                                 ' ' + str(-step) + ',' + str(-r) +
                                 ' ' + str(stroke) + ',0' +
                                 ' ' + str(step) + ',' + str(r) +
                                 ' ' + str(-step) + ',' + str(r) +
                                 ' z',
                            'transform': 'translate(' + str(cx) + ',' + str(cy) +
                                         ') rotate(' + str(rotate) + ')'}
         g.add(inkex.PathElement(**regmark_attribs))
コード例 #25
0
ファイル: wireframe_sphere.py プロジェクト: wachin/inkscape
    def latitude_lines(self, number, tilt, radius):
        """Add lines of latitude as a group"""
        # GROUP FOR THE LINES OF LATITUDE
        grp_lat = inkex.Group()
        grp_lat.set('inkscape:label', 'Lines of Latitude')

        # Angle between the line of latitude (subtended at the centre)
        delta_lat = 180.0 / number

        for i in range(1, number):
            # The angle of this line of latitude (from a pole)
            lat_angle = ((delta_lat * i) * (pi / 180))

            # The width of the LoLat (no change due to projection)
            # The projected height of the line of latitude
            rads = (
                radius * sin(lat_angle),  # major
                (radius * sin(lat_angle) * sin(tilt)) + EPSILON,  # minor
            )

            # The x position is the sphere center, The projected y position of the LoLat
            pos = (0, radius * cos(lat_angle) * cos(tilt))

            if self.options.HIDE_BACK:
                if lat_angle > tilt:  # this LoLat is partially or fully visible
                    if lat_angle > pi - tilt:  # this LoLat is fully visible
                        grp_lat.add(self.draw_ellipse(rads, pos))
                    else:  # this LoLat is partially visible
                        proportion = -(acos(tan(lat_angle - pi / 2) \
                                       / tan(pi / 2 - tilt))) / pi + 1
                        # make the start and end angles (mirror image around pi/2)
                        start_end = (pi / 2 - proportion * pi,
                                     pi / 2 + proportion * pi)
                        grp_lat.add(self.draw_ellipse(rads, pos, start_end))

            else:  # just draw the full lines of latitude
                grp_lat.add(self.draw_ellipse(rads, pos))
        return grp_lat
コード例 #26
0
ファイル: linearcase.py プロジェクト: hasantahir/myinkspace
    def effect(self):
        centro_ancho_documento = self.svg.unittouu(self.document.getroot().get('width'))/2
        centro_alto_documento = self.svg.unittouu(self.document.getroot().get('height'))/2

        ancho_caja = self.svg.unittouu(str(self.options.width) + self.options.unit)
        alto_caja = self.svg.unittouu(str(self.options.height) + self.options.unit)
        largo_caja = self.svg.unittouu(str(self.options.depth) + self.options.unit)
        ancho_pestana_cola = self.svg.unittouu(str(self.options.glue_tab) + self.options.unit)
        alto_pestana_cierre = self.svg.unittouu(str(self.options.close_tab) + self.options.unit)
        alto_pestana = self.svg.unittouu(str(self.options.side_tabs) + self.options.unit)
		
        if self.options.unit=="mm":
            medida_pestana1=5
            medida_pestana2=1
            medida_pestana3=4
            medida_pestana4=3
			
        if self.options.unit=="cm":
            medida_pestana1=0.5
            medida_pestana2=0.1
            medida_pestana3=0.4
            medida_pestana4=0.3
			
        if self.options.unit=='in':
            medida_pestana1=0.196
            medida_pestana2=0.039
            medida_pestana3=0.157
            medida_pestana4=0.118

        medida1_pestanas_laterales=self.svg.unittouu(str(medida_pestana1) + self.options.unit)
        medida2_pestanas_laterales=self.svg.unittouu(str(medida_pestana2) + self.options.unit)
        medida3_pestanas_laterales=self.svg.unittouu(str(medida_pestana3) + self.options.unit)
        medida4_pestanas_laterales=self.svg.unittouu(str(medida_pestana4) + self.options.unit)

        id_caja = self.svg.get_unique_id('estuche-lineal')
        group = self.svg.get_current_layer().add(inkex.Group(id=id_caja))
        estilo_linea_cortes = {'stroke': '#FF0000', 'fill': 'none', 'stroke-width': str(self.svg.unittouu('1px'))}
        estilo_linea_hendidos = {'stroke': '#0000FF', 'fill': 'none', 'stroke-width': str(self.svg.unittouu('1px'))}
        estilo_linea_medioscortes = {'stroke': '#00FFFF', 'fill': 'none', 'stroke-width': str(self.svg.unittouu('1px'))}
    
        # line.path --> M = coordenadas absolutas
        # line.path --> l = dibuja una linea desde el punto actual a las coordenadas especificadas
        # line.path --> c = dibuja una curva beizer desde el punto actual a las coordenadas especificadas
        # line.path --> q = dibuja un arco desde el punto actual a las coordenadas especificadas usando un punto como referencia
        # line.path --> Z = cierra path

        #Perfil Exterior de la caja
        line = group.add(inkex.PathElement(id=id_caja + '-perfil-exterior'))
        line.path = [
			['M', [0, 0]],
			['l', [ancho_caja, 0]],
			['l', [0,0]],
			['l', [0, 0]],
			['l', [0, 0-medida1_pestanas_laterales]],
			['l', [medida2_pestanas_laterales, 0-medida2_pestanas_laterales]],
			['l', [medida3_pestanas_laterales, 0-(alto_pestana-medida2_pestanas_laterales-medida1_pestanas_laterales)]], 
			['l', [(largo_caja-medida2_pestanas_laterales-medida3_pestanas_laterales-medida4_pestanas_laterales), 0]],
			['l', [0,alto_pestana-medida4_pestanas_laterales]],
			['l', [medida4_pestanas_laterales, medida4_pestanas_laterales]],
			['l', [0, 0-largo_caja]],
			['l', [0, 0]],
			['q', [0,0-alto_pestana_cierre,alto_pestana_cierre, 0-alto_pestana_cierre]],
			['l', [ancho_caja-(alto_pestana_cierre*2), 0]],
			['q', [alto_pestana_cierre,0,alto_pestana_cierre,alto_pestana_cierre]],
			['l', [0, 0]],
			['l', [0, (largo_caja)]],
			['l', [medida4_pestanas_laterales, 0-medida4_pestanas_laterales]],
			['l', [0,0-(alto_pestana-medida4_pestanas_laterales)]],
			['l', [(largo_caja-medida2_pestanas_laterales-medida3_pestanas_laterales-medida4_pestanas_laterales), 0]],
			['l', [medida3_pestanas_laterales, (alto_pestana-medida2_pestanas_laterales-medida1_pestanas_laterales)]],
			['l', [medida2_pestanas_laterales, medida2_pestanas_laterales]],
			['l', [0, medida1_pestanas_laterales]],
			['l', [0,0]],
			['l', [0, alto_caja]],
			['l', [0-medida4_pestanas_laterales, medida4_pestanas_laterales]],
			['l', [0,(alto_pestana-medida4_pestanas_laterales)]],
			['l', [0-(largo_caja-medida2_pestanas_laterales-medida3_pestanas_laterales-medida4_pestanas_laterales), 0]],
			['l', [0-(medida3_pestanas_laterales), 0-(alto_pestana-medida2_pestanas_laterales-medida1_pestanas_laterales)]],
			['l', [0-(medida2_pestanas_laterales), 0-(medida2_pestanas_laterales)]],
			['l', [0, 0-medida1_pestanas_laterales]],
			['l', [0, 0]],
			['l', [0,0]],
			['l', [0-ancho_caja, 0]],
			['l', [0,0]],
			['l', [0, 0]],
			['l', [0, medida1_pestanas_laterales]],
			['l', [0-medida2_pestanas_laterales, medida2_pestanas_laterales]],
			['l', [0-medida3_pestanas_laterales, (alto_pestana-medida2_pestanas_laterales-medida1_pestanas_laterales)]],
			['l', [0-(largo_caja-medida2_pestanas_laterales-medida3_pestanas_laterales-medida4_pestanas_laterales), 0]],
			['l', [0,0-(alto_pestana-medida4_pestanas_laterales)]],
			['l', [0-medida4_pestanas_laterales, 0-medida4_pestanas_laterales]],
			['l', [0,0]],
			['l', [0, largo_caja]],
			['l', [0, 0]],
			['q', [0,alto_pestana_cierre,0-alto_pestana_cierre, alto_pestana_cierre]],#
			['l', [0-(ancho_caja-(alto_pestana_cierre*2)), 0]],
			['q', [0-alto_pestana_cierre,0,0-alto_pestana_cierre,0-alto_pestana_cierre]],
			['l', [0, 0]],
			['l', [0, 0-largo_caja]],
			['l', [0, 0-medida2_pestanas_laterales]],
			['l', [0-ancho_pestana_cola, 0-(ancho_pestana_cola/2)]],
			['l', [0, 0-(alto_caja-ancho_pestana_cola-(medida2_pestanas_laterales*2))]],
			['l', [ancho_pestana_cola, 0-(ancho_pestana_cola/2)]],
			['Z', []]
        ]
        line.style = estilo_linea_cortes
        
        #Hendidos
        line = group.add(inkex.PathElement(id=id_caja + '-perfil-hendidos-1'))
        line.path = [
			['M', [0,0]],
			['l', [0,alto_caja]]
		]
        line.style = estilo_linea_hendidos

        line = group.add(inkex.PathElement(id=id_caja + '-perfil-hendidos-2'))
        line.path = [
			['M', [ancho_caja,0]],
			['l', [0,alto_caja]]
		]
        line.style = estilo_linea_hendidos
        
        line = group.add(inkex.PathElement(id=id_caja + '-perfil-hendidos-3'))
        line.path = [
			['M', [ancho_caja+largo_caja,0]],
			['l', [0,alto_caja]]
		]
        line.style = estilo_linea_hendidos
        
        line = group.add(inkex.PathElement(id=id_caja + '-perfil-hendidos-4'))
        line.path = [
			['M', [ancho_caja+ancho_caja+largo_caja,0]],
			['l', [0,alto_caja]]
		]
        line.style = estilo_linea_hendidos
        
        line = group.add(inkex.PathElement(id=id_caja + '-perfil-hendidos-5'))
        line.path = [
			['M', [ancho_caja,0]],
			['l', [largo_caja,0]]
		]
        line.style = estilo_linea_hendidos
        
        line = group.add(inkex.PathElement(id=id_caja + '-perfil-hendidos-6'))
        line.path = [
			['M', [ancho_caja+largo_caja,0]],
			['l', [ancho_caja,0]]
		]
        line.style = estilo_linea_hendidos
        
        line = group.add(inkex.PathElement(id=id_caja + '-perfil-hendidos-7'))
        line.path = [
			['M', [(ancho_caja*2)+largo_caja,0]],
			['l', [largo_caja,0]]
		]
        line.style = estilo_linea_hendidos
 
        line = group.add(inkex.PathElement(id=id_caja + '-perfil-hendidos-8'))
        line.path = [
			['M', [0,alto_caja]],
			['l', [ancho_caja,0]]
		]
        line.style = estilo_linea_hendidos
        
        line = group.add(inkex.PathElement(id=id_caja + '-perfil-hendidos-9'))
        line.path = [
			['M', [ancho_caja,alto_caja]],
			['l', [largo_caja,0]]
		]
        line.style = estilo_linea_hendidos
        
        line = group.add(inkex.PathElement(id=id_caja + '-perfil-hendidos-10'))
        line.path = [
			['M', [(ancho_caja*2)+largo_caja,alto_caja]],
			['l', [largo_caja,0]]
		]
        line.style = estilo_linea_hendidos
        
        line = group.add(inkex.PathElement(id=id_caja + '-perfil-hendidos-11'))
        line.path = [
			['M', [ancho_caja+largo_caja,0-(largo_caja)]],
			['l', [ancho_caja,0]]
		]
        line.style = estilo_linea_hendidos
        
        line = group.add(inkex.PathElement(id=id_caja + '-perfil-hendidos-12'))
        line.path = [
			['M', [0,alto_caja+largo_caja]],
			['l', [ancho_caja,0]]
		]
        line.style = estilo_linea_hendidos
コード例 #27
0
ファイル: svgcalendar.py プロジェクト: wachin/inkscape
 def create_month(self, m):
     txt_atts = {
         'transform':
         'translate(' +
         str(self.year_margin +
             (self.month_w + self.month_margin) * self.month_x_pos) + ',' +
         str((self.day_h * 4) + (self.month_h * self.month_y_pos)) + ')',
         'id':
         'month_' + str(m) + '_' + str(self.options.year)
     }
     g = self.year_g.add(inkex.Group(**txt_atts))
     self.write_month_header(g, m)
     gdays = g.add(inkex.Group())
     cal = calendar.monthcalendar(self.options.year, m)
     if m == 1:
         if self.options.year > 1:
             before_month = \
                 self.in_line_month(calendar.monthcalendar(self.options.year - 1, 12))
     else:
         before_month = \
             self.in_line_month(calendar.monthcalendar(self.options.year, m - 1))
     if m == 12:
         next_month = \
             self.in_line_month(calendar.monthcalendar(self.options.year + 1, 1))
     else:
         next_month = \
             self.in_line_month(calendar.monthcalendar(self.options.year, m + 1))
     if len(cal) < 6:
         # add a line after the last week
         cal.append([0, 0, 0, 0, 0, 0, 0])
     if len(cal) < 6:
         # add a line before the first week (Feb 2009)
         cal.reverse()
         cal.append([0, 0, 0, 0, 0, 0, 0])
         cal.reverse()
     # How mutch before month days will be showed:
     bmd = cal[0].count(0) + cal[1].count(0)
     before = True
     week_y = 0
     for week in cal:
         if (self.weeknr != 0 and
             ((self.options.start_day == 'mon' and week[0] != 0) or
              (self.options.start_day == 'sun' and week[1] != 0))) or \
                 (self.weeknr == 0 and
                  ((self.options.start_day == 'mon' and week[3] > 0) or
                   (self.options.start_day == 'sun' and week[4] > 0))):
             self.weeknr += 1
         week_x = 0
         if self.options.show_weeknr:
             # Remove leap week (starting previous year) and empty weeks
             if self.weeknr != 0 and not (week[0] == 0 and week[6] == 0):
                 style = self.style_weeknr
                 txt_atts = {
                     'style': str(inkex.Style(style)),
                     'x': str(self.day_w * week_x),
                     'y': str(self.day_h * (week_y + 2))
                 }
                 gdays.add(TextElement(**txt_atts)).text = str(self.weeknr)
                 week_x += 1
             else:
                 week_x += 1
         for day in week:
             style = self.style_day
             if self.is_weekend(week_x - self.cols_before):
                 style = self.style_weekend
             if day == 0:
                 style = self.style_nmd
             txt_atts = {
                 'style': str(inkex.Style(style)),
                 'x': str(self.day_w * week_x),
                 'y': str(self.day_h * (week_y + 2))
             }
             text = None
             if day == 0 and not self.options.fill_edb:
                 pass  # draw nothing
             elif day == 0:
                 if before:
                     text = str(before_month[-bmd])
                     bmd -= 1
                 else:
                     text = str(next_month[bmd])
                     bmd += 1
             else:
                 text = str(day)
                 before = False
             if text:
                 gdays.add(TextElement(**txt_atts)).text = text
             week_x += 1
         week_y += 1
     self.month_x_pos += 1
     if self.month_x_pos >= self.months_per_line:
         self.month_x_pos = 0
         self.month_y_pos += 1
コード例 #28
0
        def createLinks(node):   
            nodeParent = node.getparent()

            pathIsClosed = False
            path = node.path.to_arrays() #to_arrays() is deprecated. How to make more modern?
            if path[-1][0] == 'Z' or path[0][1] == path[-1][1]:  #if first is last point the path is also closed. The "Z" command is not required
                pathIsClosed = True
            if self.options.path_types == 'open_paths' and pathIsClosed is True:
                return #skip this loop iteration
            elif self.options.path_types == 'closed_paths' and pathIsClosed is False:
                return #skip this loop iteration
            elif self.options.path_types == 'both':
                pass
                         
            # if keeping is enabled we make of copy of the current node and insert it while modifying the original ones. We could also delete the original and modify a copy...
            if self.options.keep_selected is True:
                parent = node.getparent()
                idx = parent.index(node)
                copynode = copy.copy(node)
                parent.insert(idx, copynode)

            # we measure the length of the path to calculate the required dash configuration
            csp = node.path.transform(node.composed_transform()).to_superpath()
            slengths, stotal = csplength(csp) #get segment lengths and total length of path in document's internal unit
           
            if self.options.length_filter is True:
                if stotal < self.svg.unittouu(str(self.options.length_filter_value) + self.options.length_filter_unit):
                    if self.options.show_info is True: self.msg("node " + node.get('id') + " is shorter than minimum allowed length of {:1.3f} {}. Path length is {:1.3f} {}".format(self.options.length_filter_value, self.options.length_filter_unit, stotal, self.options.creationunit))
                    return #skip this loop iteration

            if self.options.creationunit == "percent":
                length_link = (self.options.length_link / 100.0) * stotal
            else:
                length_link = self.svg.unittouu(str(self.options.length_link) + self.options.creationunit)

            dashes = [] #central dashes array
            
            if self.options.creationtype == "entered_values":
                dash_length = ((stotal - length_link * self.options.link_count) / self.options.link_count) - 2 * length_link * self.options.link_multiplicator
                dashes.append(dash_length)
                dashes.append(length_link)                  
                for i in range(0, self.options.link_multiplicator):
                    dashes.append(length_link) #stroke (=gap)
                    dashes.append(length_link) #gap
                    
                if self.options.switch_pattern is True:
                    dashes = dashes[::-1] #reverse the array
                    
                #validate dashes. May not be negative (dash or gap cannot be longer than the path itself). Otherwise Inkscape will freeze forever. Reason: rendering issue
                if any(dash <= 0.0 for dash in dashes) == True: 
                    if self.options.show_info is True: self.msg("node " + node.get('id') + ": Error! Dash array may not contain negative numbers: " + ' '.join(format(dash, "1.3f") for dash in dashes) + ". Path skipped. Maybe it's too short. Adjust your link count, multiplicator and length accordingly, or set to unit '%'")
                    return False if self.options.skip_errors is True else exit(1)
               
                if self.options.creationunit == "percent":
                    stroke_dashoffset = self.options.link_offset / 100.0
                else:         
                    stroke_dashoffset = self.svg.unittouu(str(self.options.link_offset) + self.options.creationunit)
                    
                if self.options.switch_pattern is True:
                    stroke_dashoffset = stroke_dashoffset + ((self.options.link_multiplicator * 2) + 1)  * length_link

            if self.options.creationtype == "use_existing":
                if self.options.no_convert is True:
                    if self.options.show_info is True: self.msg("node " + node.get('id') + ": Nothing to do. Please select another creation method or disable cosmetic style output paths.")
                    return False if self.options.skip_errors is True else exit(1)
                stroke_dashoffset = 0
                style = node.style
                if 'stroke-dashoffset' in style:
                    stroke_dashoffset = style['stroke-dashoffset']
                try:
                    floats = [float(dash) for dash in re.findall(r"[+]?\d*\.\d+|\d+", style['stroke-dasharray'])] #allow only positive values
                    if len(floats) > 0:
                        dashes = floats #overwrite previously calculated values with custom input
                    else:
                        raise ValueError
                except:
                    if self.options.show_info is True: self.msg("node " + node.get('id') + ": No dash style to continue with.")
                    return False if self.options.skip_errors is True else exit(1)
                           
            if self.options.creationtype == "custom_dashpattern":
                stroke_dashoffset = self.options.custom_dashoffset_value
                try:
                    floats = [float(dash) for dash in re.findall(r"[+]?\d*\.\d+|\d+", self.options.custom_dasharray_value)] #allow only positive values
                    if len(floats) > 0:
                        dashes = floats #overwrite previously calculated values with custom input
                    else:
                        raise ValueError
                except:
                    if self.options.show_info is True: self.msg("node " + node.get('id') + ": Error in custom dasharray string (might be empty or does not contain any numbers).")
                    return False if self.options.skip_errors is True else exit(1)

            #assign stroke dasharray from entered values, existing style or custom dashpattern
            stroke_dasharray = ' '.join(format(dash, "1.3f") for dash in dashes)

            # check if the node has a style attribute. If not we create a blank one with a black stroke and without fill
            style = None
            default_fill = 'none'
            default_stroke_width = '1px'
            default_stroke = '#000000'
            if node.attrib.has_key('style'):
                style = node.get('style')
                if style.endswith(';') is False:
                    style += ';'
                    
                # if has style attribute and dasharray and/or dashoffset are present we modify it accordingly
                declarations = style.split(';')  # parse the style content and check what we need to adjust
                for i, decl in enumerate(declarations):
                    parts = decl.split(':', 2)
                    if len(parts) == 2:
                        (prop, val) = parts
                        prop = prop.strip().lower()
                        #if prop == 'fill':
                        #    declarations[i] = prop + ':{}'.format(default_fill) 
                        #if prop == 'stroke':
                        #    declarations[i] = prop + ':{}'.format(default_stroke)
                        #if prop == 'stroke-width':
                        #    declarations[i] = prop + ':{}'.format(default_stroke_width)
                        if prop == 'stroke-dasharray': #comma separated list of one or more float values
                            declarations[i] = prop + ':{}'.format(stroke_dasharray)
                        if prop == 'stroke-dashoffset':
                            declarations[i] = prop + ':{}'.format(stroke_dashoffset)
                node.set('style', ';'.join(declarations)) #apply new style to node
                    
                #if has style attribute but the style attribute does not contain fill, stroke, stroke-width, stroke-dasharray or stroke-dashoffset yet
                style = node.style
                if re.search('fill:(.*?)(;|$)', str(style)) is None:
                    style += 'fill:{};'.format(default_fill)
                if re.search('(;|^)stroke:(.*?)(;|$)', str(style)) is None: #if "stroke" is None, add one. We need to distinguish because there's also attribute "-inkscape-stroke" that's why we check starting with ^ or ;
                    style += 'stroke:{};'.format(default_stroke)
                if not 'stroke-width' in style:
                    style += 'stroke-width:{};'.format(default_stroke_width)
                if not 'stroke-dasharray' in style:
                    style += 'stroke-dasharray:{};'.format(stroke_dasharray)
                if not 'stroke-dashoffset' in style:
                    style += 'stroke-dashoffset:{};'.format(stroke_dashoffset)
                node.set('style', style)
            else:
                style = 'fill:{};stroke:{};stroke-width:{};stroke-dasharray:{};stroke-dashoffset:{};'.format(default_fill, default_stroke, default_stroke_width, stroke_dasharray, stroke_dashoffset)
                node.set('style', style)

            # Print some info about values
            if self.options.show_info is True:
                self.msg("node " + node.get('id') + ":")
                if self.options.creationunit == "percent":
                    self.msg(" * total path length = {:1.3f} {}".format(stotal, self.svg.unit)) #show length, converted in selected unit
                    self.msg(" * (calculated) offset: {:1.3f} %".format(stroke_dashoffset))
                    if self.options.creationtype == "entered_values":
                        self.msg(" * (calculated) gap length: {:1.3f} %".format(length_link))
                else:
                    self.msg(" * total path length = {:1.3f} {} ({:1.3f} {})".format(self.svg.uutounit(stotal, self.options.creationunit), self.options.creationunit, stotal, self.svg.unit)) #show length, converted in selected unit
                    self.msg(" * (calculated) offset: {:1.3f} {}".format(self.svg.uutounit(stroke_dashoffset, self.options.creationunit), self.options.creationunit))
                    if self.options.creationtype == "entered_values":
                        self.msg(" * (calculated) gap length: {:1.3f} {}".format(length_link, self.options.creationunit))
                if self.options.creationtype == "entered_values":        
                    self.msg(" * total gaps = {}".format(self.options.link_count))
                self.msg(" * (calculated) dash/gap pattern: {} ({})".format(stroke_dasharray, self.svg.unit))
     
            # Conversion step (split cosmetic path into real segments)    
            if self.options.no_convert is False:
                style = node.style #get the style again, but this time as style class    
                    
                new = []
                for sub in node.path.to_superpath():
                    idash = 0
                    dash = dashes[0]
                    length = float(stroke_dashoffset)
                    while dash < length:
                        length = length - dash
                        idash = (idash + 1) % len(dashes)
                        dash = dashes[idash]
                    new.append([sub[0][:]])
                    i = 1
                    while i < len(sub):
                        dash = dash - length
                        length = bezier.cspseglength(new[-1][-1], sub[i])
                        while dash < length:
                            new[-1][-1], nxt, sub[i] = bezier.cspbezsplitatlength(new[-1][-1], sub[i], dash/length)
                            if idash % 2: # create a gap
                                new.append([nxt[:]])
                            else:  # splice the curve
                                new[-1].append(nxt[:])
                            length = length - dash
                            idash = (idash + 1) % len(dashes)
                            dash = dashes[idash]
                        if idash % 2:
                            new.append([sub[i]])
                        else:
                            new[-1].append(sub[i])
                        i += 1
                style.pop('stroke-dasharray')
                node.pop('sodipodi:type')
                csp = CubicSuperPath(new)
                node.path = CubicSuperPath(new)
                node.style = style
                
                # break apart the combined path to have multiple elements
                if self.options.breakapart is True:
                    breakOutputNodes = None
                    breakOutputNodes = self.breakContours(node, breakOutputNodes)
                    breakApartGroup = nodeParent.add(inkex.Group())
                    for breakOutputNode in breakOutputNodes:
                        breakApartGroup.append(breakOutputNode)
                        #self.msg(replacedNode.get('id'))
                        #self.svg.selection.set(replacedNode.get('id')) #update selection to split paths segments (does not work, so commented out)

                        #cleanup useless points
                        p = breakOutputNode.path
                        commandsCoords = p.to_arrays()
                        # "m 45.250809,91.692739" - this path contains onyl one command - a single point
                        if len(commandsCoords) == 1:
                            breakOutputNode.delete()
                        # "m 45.250809,91.692739 z"  - this path contains two commands, but only one coordinate. 
                        # It's a single point, the path is closed by a Z command
                        elif len(commandsCoords) == 2 and commandsCoords[0][1] == commandsCoords[1][1]:
                            breakOutputNode.delete()
                        # "m 45.250809,91.692739 l 45.250809,91.692739" - this path contains two commands, 
                        # but the first and second coordinate are the same. It will render als point
                        elif len(commandsCoords) == 2 and commandsCoords[-1][0] == 'Z':
                            breakOutputNode.delete()
                        # "m 45.250809,91.692739 l 45.250809,91.692739 z" - this path contains three commands, 
                        # but the first and second coordinate are the same. It will render als point, the path is closed by a Z command
                        elif len(commandsCoords) == 3 and commandsCoords[0][1] == commandsCoords[1][1] and commandsCoords[2][1] == 'Z':
                            breakOutputNode.delete()
コード例 #29
0
ファイル: primitive.py プロジェクト: hasantahir/myinkspace
    def effect(self):

        # internal overwrite for scale:
        self.options.scale = 1.0

        if (self.options.ids):
            for node in self.svg.selected.values():
                if node.tag == inkex.addNS('image', 'svg'):
                    self.path = self.checkImagePath(
                        node)  # This also ensures the file exists
                    if self.path is None:  # check if image is embedded or linked
                        image_string = node.get(
                            '{http://www.w3.org/1999/xlink}href')
                        # find comma position
                        i = 0
                        while i < 40:
                            if image_string[i] == ',':
                                break
                            i = i + 1
                        image = Image.open(
                            BytesIO(
                                base64.b64decode(
                                    image_string[i + 1:len(image_string)])))
                    else:
                        image = Image.open(self.path)

                    # Write the embedded or linked image to temporary directory
                    if os.name == "nt":
                        exportfile = "Primitive.png"
                    else:
                        exportfile = "/tmp/Primitive.png"

                    image.save(exportfile, "png")

                    ## Build up Primitive command according to your settings from extension GUI
                    if os.name == "nt":
                        command = "primitive"
                    else:
                        command = "./primitive"
                    command += " -m " + str(self.options.m)
                    command += " -rep " + str(self.options.rep)
                    command += " -r " + str(self.options.r)
                    command += " -s " + str(self.options.s)
                    command += " -a " + str(self.options.a)
                    if not self.options.bg_enabled:
                        command += " -bg " + self.rgbToHex(self.options.bg)
                    command += " -j " + str(self.options.j)
                    command += " -i " + exportfile
                    command += " -o " + exportfile + ".svg"
                    command += " -n " + str(self.options.n)

                    #inkex.utils.debug(command)

                    # Create the vector new SVG file
                    with os.popen(command, "r") as proc:
                        result = proc.read()
                        #inkex.utils.debug(result)

                    # proceed if new SVG file was successfully created
                    doc = None
                    if os.path.exists(exportfile + ".svg"):
                        # Delete the temporary png file again because we do not need it anymore
                        if os.path.exists(exportfile):
                            os.remove(exportfile)

                        # new parse the SVG file and insert it as new group into the current document tree
                        doc = etree.parse(exportfile + ".svg").getroot()
                        newGroup = self.document.getroot().add(inkex.Group())
                        newGroup.attrib['transform'] = "matrix(" + \
                            str(float(node.get('width')) / float(doc.get('width'))) + \
                            ", 0, 0 , " + \
                            str(float(node.get('height')) / float(doc.get('height'))) + \
                            "," + node.get('x') + \
                            "," + node.get('y') + ")"
                        newGroup.append(doc)

                        # Delete the temporary svg file
                        if os.path.exists(exportfile + ".svg"):
                            try:
                                os.remove(exportfile + ".svg")
                            except:
                                pass

                    else:
                        inkex.utils.debug(
                            "Error while creating output file! :-( The \"primitive\" executable seems to be missing, has no exec permissions or platform is imcompatible."
                        )
                        exit(1)
                    #remove the old image or not
                    if self.options.keeporiginal is not True:
                        node.delete()

                    # create clip path to remove the stuffy surroundings
                    if self.options.cliprect:
                        path = '//svg:defs'
                        defslist = self.document.getroot().xpath(
                            path, namespaces=inkex.NSS)
                        if len(defslist) > 0:
                            defs = defslist[0]
                        clipPathData = {
                            inkex.addNS('label', 'inkscape'):
                            'imagetracerClipPath',
                            'clipPathUnits': 'userSpaceOnUse',
                            'id': 'imagetracerClipPath'
                        }
                        clipPath = etree.SubElement(defs, 'clipPath',
                                                    clipPathData)
                        #inkex.utils.debug(image.width)
                        clipBox = {
                            'x': str(0),
                            'y': str(0),
                            'width': str(doc.get('width')),
                            'height': str(doc.get('height')),
                            'style':
                            'fill:#000000; stroke:none; fill-opacity:1;'
                        }
                        etree.SubElement(clipPath, 'rect', clipBox)
                        #etree.SubElement(newGroup, 'g', {inkex.addNS('label','inkscape'):'imagetracerjs', 'clip-path':"url(#imagetracerClipPath)"})
                        newGroup.getchildren()[0].set(
                            'clip-path', 'url(#imagetracerClipPath)')
        else:
            inkex.utils.debug(
                "No image found for tracing. Please select an image first.")
コード例 #30
0
    def generate(self):

        size = self.svg.unittouu(str(self.options.size) + 'px')
        head = self.svg.unittouu(str(self.options.head) + 'px')
        width = self.svg.unittouu(str(self.options.width) + 'pt')
        medium = self.svg.unittouu('10pt') # font sizes, ...
        large = self.svg.unittouu('12pt') # ... could be options

        tsector, survey_title = analyse3d(self.options.file, self.options.nsector)

        tmax = max(tsector)
        thoriz = 0.5 * sum(tsector) # each leg is counted twice
        ns = len(tsector)
        tmean = 2 * thoriz / ns

        # Inner group to contain all the rose diagram elements

        rose_diagram = inkex.Group() 

        elements = [''] * (2*ns) # list of lines and arc elements

        for i, v in enumerate(tsector):
            alo = 2 * m.pi * (i - 0.5) / ns
            ahi = 2 * m.pi * (i + 0.5) / ns
            rad = size * tsector[i] / tmax
            xx0 = rad * m.sin(alo)
            yy0 = - rad * m.cos(alo)
            xx1 = rad * m.sin(ahi)
            yy1 = - rad * m.cos(ahi)
            elements[2*i] = ('L' if i else 'M') + '%7.2f, %7.2f ' % (xx0, yy0)
            elements[2*i+1] = 'A %6.2f, %6.2f 0 0,1 %7.2f, %7.2f' % (rad, rad, xx1, yy1)

        # Add the lines and arc elements - 'z' closes the path

        zigzag = inkex.PathElement(d=' '.join(elements) + ' z')
        zigzag.style = {'stroke': 'black', 'fill': 'none' if self.options.bw else 'yellow', 'stroke-width': width}
        rose_diagram.add(zigzag)

        # Adjust the scale circle radius, rounding down if necessary
        
        scale_rad = fancy_round(tmean)
        if scale_rad > tmax:
            scale_rad = fancy_round(tmean, offset=0.0)

        # Add the scale circle 

        circle = inkex.Circle(r=str(size * scale_rad / tmax))
        circle.style = {'stroke': 'black' if self.options.bw else 'blue', 'fill': 'none', 'stroke-width': width}
        if self.options.bw:
            circle.style['stroke-dasharray'] = '{step} {step}'.format(step=4*width)
        rose_diagram.add(circle)

        # Add N-S, E-W, NW-SE, NE-SW lines; the N has a half-arrow

        style = {'stroke': 'black', 'fill': 'none', 'stroke-width': width}
        style = str(inkex.Style(style))

        length = 1.05 * size
        rose_diagram.add(inkex.PathElement(d=f'M0,{-length+2*head} L{-head},{-length+2*head} L0,-{length} L0,{length}', style=style))
        rose_diagram.add(inkex.PathElement(d=f'M-{length},0 L{length},0', style=style))

        length = m.sqrt(0.5) * 1.05 * size
        rose_diagram.add(inkex.PathElement(d=f'M-{length},-{length} L{length},{length}', style=style))
        rose_diagram.add(inkex.PathElement(d=f'M{length},-{length} L-{length},{length}', style=style))

        # Add a 'N' to the north arrow
        
        north = inkex.TextElement(x=str(head), y=str(-1.05*size+head))
        north.style = {'font-family': 'Verdana', 'font-size': large, 'fill': 'black', 'text-anchor': 'middle', 'text-align': 'center'}        
        north.text = 'N'
        rose_diagram.add(north)

        yield rose_diagram

        # Add annotation for cave length and circle radius

        annotation = inkex.TextElement(x=str(0), y=str(1.3*size))
        annotation.style = {'font-family': 'Verdana', 'font-size': medium, 'fill': 'black', 'text-anchor': 'middle', 'text-align': 'center'}        
        cave_length = f'{round(thoriz/1000, 1)} km' if thoriz > 10000 else f'{round(thoriz)} m'
        circle_radius = f'{scale_rad/1000} km' if scale_rad > 1000 else f'{scale_rad} m'
        annotation.text = f'length {cave_length}, circle radius is {circle_radius}'
        
        yield annotation

        # Add a title
        
        title = inkex.TextElement(x=str(0), y=str(-1.3*size))
        title.style = {'font-family': 'Verdana', 'font-size': large, 'fill': 'black', 'text-anchor': 'middle', 'text-align': 'center'}        
        title.text = self.options.title or survey_title

        yield title