Subtracting two polygons in C++

edited February 2014 in Ruby Scripting

I know you intentionally don't publish the C++ API, but I have a quick question.

I'm looking at Basic.ROUND_PATH Pcell code, and just need to make a minor modification - so instead of a rounded path it creates two co-linear paths, one wide and one narrow, then subtracts the wide path from the narrow path.

I believe it'd be far easier to do a minor modification of the existing C++ Pcell than to write the whole thing in Ruby from scratch.

So basically if this were Ruby I'd do the following:

    ep = RBA::EdgeProcessor::new
    wide_minus_narrow = ep.boolean_p2p(wide_wire, narrow_wire, RBA::EdgeProcessor::ModeANotB, false, false)
    wide_minus_narrow.each do |p|
      out_cell.shapes(out_layer).insert(p)
    end

Could you perhaps make an exception in this case with your non-API-publishing rule and let me know how I can find out what C++ commands to do that?

Thanks!

Comments

  • edited February 2014

    Never mind, I think I figured it out -- so you don't have to break your rules on publicizing C++ APIs :-). However I have another question.

    But first, my attempt at the code. Basically I found libBasicStrokedPolygon to be using an edge processor, so it was easy to copy that.

    So the only additions to the libBasicRoundPaths is the following..?

    /* Existing code */
    db::Polygon poly;
    poly.assign_hull (hull.begin (), hull.end (), db::cast_op<db::Point, db::DPoint> ());
    cell.shapes (layer_ids [p_layer]).insert (poly);
    
    /* New code */
    db::Polygon poly2;
    poly2 = poly;
    cell.shapes (layer_ids [p_layer]).insert (poly2);
    
    std::vector <db::Polygon> shapes;
    db::EdgeProcessor ep; 
    shapes.clear ();
    ep.boolean (poly, poly2, shapes, db::BooleanOp::ANotB, true /*resolve holes*/);
    

    Of course I added these two declarations to the start:

    #include "dbPolygonTools.h"
    #include "dbEdgeProcessor.h"
    

    Now just missing two small things:

    1) How to make poly2 have larger width than poly? So that the ep.boolean actually does something useful? Note that poly2 should be a rounded wire with width w2, converted to polygon. And poly should be a rounded wire with width w, converted to polygon. I just can't see where to set the width.

    2) This is a .cc file -- how to compile it to be included with an existing KLayout installation, if possible? Or do I have to build the whole KLayout from scratch with this extra file included?

    Thanks!

  • edited February 2014

    Hi,

    Here is a sketch (not tested):

    std::vector<db::Polygon> a;
    a.push_back (db::Polygon ());
    a.back ().assign_hull (hull.begin (), hull.end (), db::cast_op<db::Point, db::DPoint> ());
    
    db::EdgeProcessor ep;
    
    //  Produce small version (d = compensation per edge)
    std::vector<db::Polygon> b;
    ep.size (a, -d, -d, b);
    
    //  subtract (a = a-b)
    ep.boolean (a, b, a, db::EdgeProcessor::ANotB, true /*resolve holes*/);
    
    //  Produce the shapes
    for (std::vector<db::Polygon>::const_iterator p = a.begin (); p != a.end (); ++p) {
      cell.shapes (layer_ids [p_layer]).insert (*p);
    }
    

    If you change anything in a C++ program, you'll have to rebuild the whole application. You cannot just exchange a single file. If you add a new file, you'll have to include it in the Makefile so it's built too.

    Matthias

Sign In or Register to comment.