slice a shape into two parts

edited November 2016 in Python scripting
I would like to create a macro which would to slice polygons or boxes vertically or horizontally
into two parts. Could you give some hints on how to implement the following?

In detail the functionality of a "slice-vertical" macro would be:
1 - select a set of polygons or boxes
2 - launch the sliceV script through a Shift+V keyboard shortcut
3 - click a point on the layoutview window
4 - an imaginary vertical line going through the point determined in step 3 cuts all the shapes selected in step 1 into two halves.

Similarly for slice-horizontal.

Thanks for help!

P.S. tried if using the erase mode and very narrow paths would work. Nothing happens when
the path width is smaller than dbu. Paths with width > dbu work as expected, but I would really want "infinitesimally narrow" paths, so that the cuts define the shapes nicely along the used grid points.


  • edited 11:53AM


    the request can probably be implemented, but the effort will be substantial. The basic approach for implementing a feature that provides mouse interaction is to employ the RBA::Plugin framework. A starting point is the documentation provided for the PluginFactory class and a basic introduction to this concept.

    I feel you ask for a emulation of Virtuoso's slice feature. Please consider not keeping the results to yourself but publish them if you think it's useful for others. This is the spirit of open source.

    Kind regards,


  • edited 11:53AM
    Hi Matthias
    and sorry for the delay in my comment :)

    I will probably try implementing this at some point in the future.

    Indeed I'm looking for an emulation feature - I've used Tanner's L-edit and slicing polygons
    has been an integral part of my drawing workflow. I'll share the result as soon as
    I have made something useful.

    Can I use python for using the PluginFactory class (couldn't find any example code on python using this class) or should I learn Ruby?

  • edited January 2017

    Hi Antti,

    one more suggestion: what about a feature like "separate into inner and outer parts"?

    There are already two operations which you can use in order to split a polygon: "Edit/Selection/Intersection" and "Edit/Selection/Subtraction". So imagine you want to keep the right half of a polygon, you could:

    1. draw a rectangle over the right half
    2. copy that rectangle and the original polygon into the clipboard
    3. subtract the rectangle from the original polygon (the rectangle will vanish)
    4. paste the rectangle and the original polygon again
    5. form the intersection with the original polygon

    Admittedly this is very tedious. But how about combining these instructions into a single operation, i.e "Edit/Selection/Separate Inside+Outside"? Then you do

    1. draw a rectangle over the right half
    2. select the original polygon and the rectangle
    3. choose "Edit/Selection/Separate Inside+Outside"

    the result would two polygons - the inside part and the outside part.

    What do you think? This feature is just a combination of existing functions - hence should be straightforward to implement.


  • edited 11:53AM
    Hi Matthias,
    thanks for your response.

    Yes, your suggestion sounds like an easier way to go, definitely something to start with first.

    Eventually, to get mouse interaction I understand that PluginFactory is needed.
    Regarding this, should PluginFactory work with python? If you have any example code of PluginFactory + python I'd appreciate a link...

  • edited 11:53AM

    An alternative way to split the polygon is to use diff mode and draw two identical rectangles over the right half.


  • edited 11:53AM

    @Harri: thanks for the suggestion and yes, that's one more option.

    I basically wanted to say, that within the framework of the current application it's possible to create a function that probably solves the problem stated. It's just not precisely like L-Edit. Instead of drawing a line you have a draw a mask shape. Within this approach, the solution is a few lines of script:

    # This script requires two selections
    # * the first selection is the "subject" 
    # * the second selection (Shift + click on object) is the "mask"
    # The script will take all polygons from the subject and 
    # separate it into parts inside and outside of the mask. 
    # TODO: 
    # * as a side effect, the polygons are merged currently
    #   (solution: pass them separately through the boolean operation)
    mw = RBA::Application::instance.main_window
    lv = mw.current_view || raise("No layout loaded")
    cv_index = nil
    layer = nil
    mask = RBA::Region::new
    subjects = RBA::Region::new
    shapes_to_delete = []
    lv.each_object_selected do |obj|
      if obj.shape.is_box? || obj.shape.is_polygon? || obj.shape.is_path?
        poly = obj.shape.polygon.transformed(obj.trans)
        if obj.seq == 0
          subjects += poly
          layer ||= obj.layer
          cv_index ||= obj.cv_index
          mask += poly
        shapes_to_delete << obj.shape
    layer || raise("No objects selected")
    mask.is_empty? && raise("No mask objects selection (second selection)")
      lv.transaction("Separate inside/outside of mask")
      inside  = subjects & mask
      outside = subjects - mask
      lv.cellview(cv_index).cell.shapes(layer).insert(inside + outside)
      shapes_to_delete.each do |s|

    This script can be bound to a menu: if you chose "edit_menu.selection_menu.intersection" it will be put in the "Edit/Selection" menu.



Sign In or Register to comment.