Inkscape.org
Creating New Extensions Cloning objects - only works on paths?
  1. #1
    nine1seven3oh nine1seven3oh @nine1seven3oh

    Hi, I'm trying to clone a selected object, but it only seems to work on single paths, not on groups, rectangles, text etc.

    Minimum working example:

    iddd = self.svg.selection[0].get('id')
    elem = inkex.Use(x="50mm",  y="50mm")
    elem.set('xlink:href', '#'+iddd)
    self.svg.append(elem)
    

    If I manually edit the SVG I can point the a xlink:href to anything, e.g. text123 and it works fine. The extension creates the Use, I can view the attribs, but it just won't add to the document if it is not a path.

    I found clones_in_perspective extension in the Mightyscape collection, which adds clones in a different way. I've stripped the code down to this, but it also does not work on anything that isn't a single path. But for some reason the extension itself works fine on text, shapes etc

    xpath = list(self.svg.selected.items())[0][0]
    sel = self.svg.selected[xpath]
    id = sel.get('id')
    parent = sel.getparent()
    j = parent.index(sel)
    att = {
                  "id" : self.svg.get_unique_id("clone" + iddd),
                  inkex.addNS('href','xlink') : "#" + iddd,
                  inkex.addNS('x','inkscape') : str(50),
                  inkex.addNS('y','inkscape') : str(50),
                  'transform' : ("matrix(%f,0,0,%f,%f,%f)" % (1, 1,1, 1)),
                  "width" :  "100%",
                  "height" : "100%",
            }
    parent.insert(j, etree.Element('use', att))       

    I'm not sure if this is a bug, or something I'm missing. Inkscape 1.3

  2. #2
    inklinea inklinea @inklinea⛰️

    It should be as simple as this:

     

    import inkex

    from inkex import Use

    def clone_element(self, element):

    new_clone = Use()
    new_clone.set('xlink:href', f'#{element.get_id()}')

    self.svg.get_current_layer().append(new_clone)


    class MakeClones(inkex.EffectExtension):

    def add_arguments(self, pars):
    pass

    def effect(self):

    selection_list = self.svg.selected

    if len(selection_list) < 1:
    return

    for item in selection_list:
    clone_element(self, item)

    if __name__ == '__main__':
    MakeClones().run()

  3. #3
    nine1seven3oh nine1seven3oh @nine1seven3oh

    Thanks for the reply, it helped me narrow down the issue. I was just making a stupid mistake in my code. I forgot to remove a inkex.abortextension that was being called if the selection wasn't a path further down....

  4. #4
    Nikki.Smith Nikki.Smith @Nikki.Smith
    inklinea

    def clone_element(self, element): new_clone = Use() new_clone.set('xlink:href', f'#{element.get_id()}')

    I think this can be simplified to:

    def clone_element(self, element):
        new_clone = Use()
        new_clone.href = element
    

    Old thread I know, but it comes up when searching for help with cloning objects.

Inkscape Inkscape.org Inkscape Forum Creating New Extensions Cloning objects - only works on paths?