Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Snap-to-grid (post facto) function?

I've been having some issues with grid bumping up and
down (probably due to fat-fingering the bindkeys, unaware).
So I have cell instances and polygon interconnect that are
now placed at a variety of grids and it's a bit ugly.

I've looked for, but not found, any "snap to grid" utility
that I would use to get everything on the 1.0u grid again.
I only find mention of snapping as a piece of other functions'
activity in the forum. There is nothing about a snap function
for objects in the manual, only Rulers.

Wonder if someone has a macro script for this perhaps?
All I really want to do is strip decimal places (rounding to
closest, would be acceptable but not strictly necessary) in
object origin / vertices, but not by hand one object at a time.

Comments

  • Hi Jim,

    DRC has a snapping feature, but that will flatten your layer and turn all paths and boxes into polygons and remove texts.

    A dirty trick is to save your layout with 1 µm database unit and later with a finer DBU again. This will force snapping, but beware of manifold snap artefacts.

    Matthias

  • Hi Jim,

    A long time ago I made the example below when working my way into Ruby and scripting. The code is most likely not the "cleanest" but it works for me. Note that it is not recursive and the vectors of instance arrays are also put on grid (you might want to resolve instance arrays first).

    Cheers,

    Tomas

    module MyMacro

    Puts selected shapes (boxes, polygons and paths) and instances (origin and array parameters on a user-defined grid.

    This function is NOT recursive.

    include RBA

    app = Application.instance
    mw = app.main_window

    lv = mw.current_view
    cv = lv.active_cellview
    ly = cv.layout

    dbu = ly.dbu

    ok = Value.new(true)

    grid = QInputDialog.getDouble(mw, "getDouble()", "Value", 0.1, dbu, 10, 5, ok)

    if ok.value

    begin

    lv.transaction("Put selected objects on grid")

    if lv == nil
    raise "Shape Statistics: No view selected"
    end

    grid_dbu = grid/dbu

    instances_to_modify = []
    shapes_to_modify = []

    lv.each_object_selected do |sel|

    if sel.is_cell_inst?
    
     instances_to_modify.push(sel) 
    
    else 
    
     shapes_to_modify.push(sel)
    
    end
    

    end

    instances_to_modify.each do |instance|

    instance = instance.inst

    trans0 = instance.trans

    text = instance.trans.to_s
    text2 = text.gsub(",", "\s").split("\s")

    px = text2[1].to_i
    py = text2[2].to_i

    point1 = Point.new(-px,-py)
    trans1 = Trans.new(point1)

    px = ((px/grid_dbu).round.to_igrid_dbu).to_i
    py = ((py/grid_dbu).round.to_i
    grid_dbu).to_i

    point2 = Point.new(px,py)
    trans2 = Trans.new(point2)

    instance.trans=trans2trans1trans0

    a = instance.a
    b = instance.b

    ax = a.x
    ay = a.y
    bx = b.x
    by = b.y

    ax = ((ax/grid_dbu).round.to_igrid_dbu).to_i
    ay = ((ay/grid_dbu).round.to_i
    grid_dbu).to_i
    bx = ((bx/grid_dbu).round.to_igrid_dbu).to_i
    by = ((by/grid_dbu).round.to_i
    grid_dbu).to_i

    a = Point.new(ax,ay)
    b = Point.new(bx,by)

    instance.a=(a)
    instance.b=(b)

    end

    shapes_to_modify.each do |shape|

    if shape.shape.is_box?

    box = shape.shape
    
    p1 = box.box_p1
    p2 = box.box_p2
    p1x = p1.x
    p1y = p1.y
    p2x = p2.x
    p2y = p2.y
    
    p1x = ((p1x/grid_dbu).round.to_i*grid_dbu).to_i
    p1y = ((p1y/grid_dbu).round.to_i*grid_dbu).to_i
    p2x = ((p2x/grid_dbu).round.to_i*grid_dbu).to_i
    p2y = ((p2y/grid_dbu).round.to_i*grid_dbu).to_i
    
    p1 = Point.new(p1x,p1y)
    p2 = Point.new(p2x,p2y)
    box.box_p1=(p1)
    box.box_p2=(p2)
    

    elsif shape.shape.is_polygon?

    polygon = shape.shape
    
    hull = []
    
    polygon.each_point_hull do |point|
    
    px = point.x
    py = point.y
    
    px = ((px/grid_dbu).round.to_i*grid_dbu).to_i
    py = ((py/grid_dbu).round.to_i*grid_dbu).to_i
    
    point = Point.new(px,py)
    
    hull.push(point)
    
    end
    

    polygonnew = Polygon.new(hull)
    polygon.polygon=polygonnew

    elsif shape.shape.is_path?

    path = shape.shape
    
    points = []
    
    path.each_point do |point|
    
    px = point.x
    py = point.y
    
    px = ((px/grid_dbu).round.to_i*grid_dbu).to_i
    py = ((py/grid_dbu).round.to_i*grid_dbu).to_i
    
    point = Point.new(px,py)
    
    points.push(point)
    
    end
    

    width = path.path.width

    width = ((width/2/grid_dbu).round.to_i*grid_dbu).to_i * 2

    bgn_ext = path.path.bgn_ext

    end_ext = path.path.end_ext

    is_round = path.path.is_round?

    pathnew = Path.new(points, width, bgn_ext, end_ext, is_round)
    path.path=pathnew

    end

    end

    ensure
    lv.commit
    end

    end

    end

  • Hi Thomas,

    if you want to achieve readability, you can put a triple backtick line in front of and after your code. Then the code will be formatted as such (markdown). See http://en.wikipedia.org/wiki/Markdown for details.

    Kind regards,

    Matthias

  • Hi Matthias,

    Thanks for the tip, could not edit, so re-post below...

    <br />module MyMacro
    
    # Puts selected shapes (boxes, polygons and paths) and instances (origin and array parameters on a user-defined grid.
    # This function is NOT recursive.
    
      include RBA
    
    
      app = Application.instance
      mw = app.main_window
    
      lv = mw.current_view
      cv = lv.active_cellview
      ly = cv.layout
    
      dbu = ly.dbu
    
      ok = Value.new(true)
    
      grid = QInputDialog.getDouble(mw, "getDouble()", "Value", 0.1, dbu, 10, 5, ok)
    
    if ok.value
    
     begin
    
      lv.transaction("Put selected objects on grid")
    
      if lv == nil
        raise "Shape Statistics: No view selected"
      end
    
      grid_dbu = grid/dbu
    
      instances_to_modify = []
      shapes_to_modify = []
    
      lv.each_object_selected do |sel|
    
        if sel.is_cell_inst?
    
         instances_to_modify.push(sel) 
    
        else 
    
         shapes_to_modify.push(sel)
    
        end
    
      end
    
    instances_to_modify.each do |instance|
    
      instance = instance.inst
    
      trans0 = instance.trans
    
      text = instance.trans.to_s
      text2 = text.gsub(",", "\s").split("\s")
    
      px = text2[1].to_i
      py = text2[2].to_i
    
      point1 = Point.new(-px,-py)
      trans1 = Trans.new(point1)
    
      px = ((px/grid_dbu).round.to_i*grid_dbu).to_i
      py = ((py/grid_dbu).round.to_i*grid_dbu).to_i
    
      point2 = Point.new(px,py)
      trans2 = Trans.new(point2)
    
      instance.trans=trans2*trans1*trans0
    
      a = instance.a
      b = instance.b
    
      ax = a.x
      ay = a.y
      bx = b.x
      by = b.y  
    
      ax = ((ax/grid_dbu).round.to_i*grid_dbu).to_i
      ay = ((ay/grid_dbu).round.to_i*grid_dbu).to_i
      bx = ((bx/grid_dbu).round.to_i*grid_dbu).to_i
      by = ((by/grid_dbu).round.to_i*grid_dbu).to_i
    
      a = Point.new(ax,ay)
      b = Point.new(bx,by)
    
      instance.a=(a)
      instance.b=(b)
    
    end
    
    shapes_to_modify.each do |shape|
    
      if shape.shape.is_box?
    
        box = shape.shape
    
        p1 = box.box_p1
        p2 = box.box_p2
        p1x = p1.x
        p1y = p1.y
        p2x = p2.x
        p2y = p2.y
    
        p1x = ((p1x/grid_dbu).round.to_i*grid_dbu).to_i
        p1y = ((p1y/grid_dbu).round.to_i*grid_dbu).to_i
        p2x = ((p2x/grid_dbu).round.to_i*grid_dbu).to_i
        p2y = ((p2y/grid_dbu).round.to_i*grid_dbu).to_i
    
        p1 = Point.new(p1x,p1y)
        p2 = Point.new(p2x,p2y)
        box.box_p1=(p1)
        box.box_p2=(p2)
    
      elsif shape.shape.is_polygon?
    
        polygon = shape.shape
    
        hull = []
    
        polygon.each_point_hull do |point|
    
        px = point.x
        py = point.y
    
        px = ((px/grid_dbu).round.to_i*grid_dbu).to_i
        py = ((py/grid_dbu).round.to_i*grid_dbu).to_i
    
        point = Point.new(px,py)
    
        hull.push(point)
    
        end
    
      polygonnew = Polygon.new(hull)
      polygon.polygon=polygonnew
    
      elsif shape.shape.is_path?
    
        path = shape.shape
    
        points = []
    
        path.each_point do |point|
    
        px = point.x
        py = point.y
    
        px = ((px/grid_dbu).round.to_i*grid_dbu).to_i
        py = ((py/grid_dbu).round.to_i*grid_dbu).to_i
    
        point = Point.new(px,py)
    
        points.push(point)
    
        end
    
      width = path.path.width
    
      width = ((width/2/grid_dbu).round.to_i*grid_dbu).to_i * 2
    
      bgn_ext = path.path.bgn_ext
    
      end_ext = path.path.end_ext
    
      is_round = path.path.is_round?
    
      pathnew = Path.new(points, width, bgn_ext, end_ext, is_round)
      path.path=pathnew
    
      end
    
    end
    
    ensure
      lv.commit
    end
    
    end
    
    
    end
    
    
  • Very good ... that's better to read :-)

    I think something is wrong at the beginning (make sure the initial line is only three backticks). But that's just a small flaw.

Sign In or Register to comment.