Inkscape.org
Creating New Extensions How to generate several objects from custom generate extension
  1. #1
    oscoder oscoder @oscoder
    *

    Hi, I'm learning to program on the python api.

    I'm making a generation extension. At this moment I make a duplicate of the selected shape, i make some stuff to the copy and then I return the new shape or path.

    def generate(self):
    selection = self.svg.selection.filter((inkex.ShapeElement, inkex.PathElement))
        c = None
        i = selection[0]
    #... c will contain my ouptut
     
    return c
     

    Would it be possible to return several shapes?

    VERSION of inkscape: Inkscape 1.3.2 (091e20e, 2023-11-25, custom)

  2. #2
    inklinea inklinea @inklinea⛰️

    I would say if you need to use the contents of the existing svg, then it's better to make an effect extension instead of a generate extension.

    Generate extension are not used that much, 

    A basic EffectExtension can do everything you want.

    The difference is that the Generate extension returns an svg fragment instead of the entire svg - which for most cases is more difficult to work with. (In my opinion)

    import inkex
    from inkex import Layer
    
    from random import randint
    
    def duplicate_and_change_style(self, selection_list, to_new_layer=False):
    
        duplicate_list = []
    
        for selected in selection_list:
            # Duplicated the selected item on canvas
            duplicate = selected.duplicate()
            # Lets change some styles
            random_rgb = f'rgb({randint(0, 255)}, {randint(0, 255)}, {randint(0, 255)})'
            duplicate.style['fill'] = random_rgb
            duplicate_list.append(duplicate)
    
        # Should we move the duplicates to a new layer ?
        if to_new_layer:
            new_layer = Layer()
            for element in duplicate_list:
                # elements can only be in one place at once
                # so append moves them
                new_layer.append(element)
            # Make the new layer a sublayer of current layer
            self.svg.get_current_layer().append(new_layer)
    
    class DuplicateShapesTest(inkex.EffectExtension):
    
        def add_arguments(self, pars):
            pass
        
        def effect(self):
    
            # Create a filtered selection list
            selection_list = self.svg.selected.filter((inkex.ShapeElement, inkex.PathElement))
    
            # Exit if the selection list does not contain anything
            if len(selection_list) < 1:
                inkex.errormsg('Please select at least one object')
                return
    
            # Print the selection list in msgbox
            for selection in selection_list:
                inkex.errormsg(f'{selection} {selection.get_id()}')
    
            # Run the duplicate function
            # Change to_new_layer to True or False however you want.
            duplicate_and_change_style(self, selection_list, to_new_layer=True)
    
    
    if __name__ == '__main__':
        DuplicateShapesTest().run()
    
  3. #3
    oscoder oscoder @oscoder

    Thank you ¡very much! @inklinea This was helpful indeed.

Inkscape Inkscape.org Inkscape Forum Creating New Extensions How to generate several objects from custom generate extension