Skip to content

Commit

Permalink
Merge branch 'master' of github.com:KLayout/klayout
Browse files Browse the repository at this point in the history
  • Loading branch information
Matthias Koefferlein committed Jul 30, 2024
2 parents b6af0ba + 8ab398d commit 1040e81
Show file tree
Hide file tree
Showing 74 changed files with 2,249 additions and 604 deletions.
8 changes: 4 additions & 4 deletions src/ant/ant/antPlugin.cc
Original file line number Diff line number Diff line change
Expand Up @@ -63,16 +63,16 @@ static std::vector<ant::Template> make_standard_templates ()
templates.push_back (ant::Template (tl::to_string (tr ("Measure edge")), "$X", "$Y", "$D", ant::Object::STY_ruler, ant::Object::OL_diag, true, lay::AC_Global, "_measure_edge"));
templates.back ().set_mode (ant::Template::RulerAutoMetricEdge);

templates.push_back (ant::Template (tl::to_string (tr ("Angle")), "", "", "$(sprintf('%.5g',G))°", ant::Object::STY_line, ant::Object::OL_angle, true, lay::AC_Global, "_angle"));
templates.push_back (ant::Template (tl::to_string (tr ("Angle")), "", "", "$(sprintf('%.5g',G))°", ant::Object::STY_line, ant::Object::OL_angle, true, lay::AC_Any, "_angle"));
templates.back ().set_mode (ant::Template::RulerThreeClicks);

templates.push_back (ant::Template (tl::to_string (tr ("Radius")), "", "", "R=$D", ant::Object::STY_arrow_end, ant::Object::OL_radius, true, lay::AC_Global, "_radius"));
templates.push_back (ant::Template (tl::to_string (tr ("Radius")), "", "", "R=$D", ant::Object::STY_arrow_end, ant::Object::OL_radius, true, lay::AC_Any, "_radius"));
templates.back ().set_mode (ant::Template::RulerThreeClicks);
templates.back ().set_main_position (ant::Object::POS_center);

templates.push_back (ant::Template (tl::to_string (tr ("Ellipse")), "W=$(abs(X))", "H=$(abs(Y))", "", ant::Object::STY_line, ant::Object::OL_ellipse, true, lay::AC_Global, std::string ()));
templates.push_back (ant::Template (tl::to_string (tr ("Ellipse")), "W=$(abs(X))", "H=$(abs(Y))", "", ant::Object::STY_line, ant::Object::OL_ellipse, true, lay::AC_Any, std::string ()));

templates.push_back (ant::Template (tl::to_string (tr ("Box")), "W=$(abs(X))", "H=$(abs(Y))", "", ant::Object::STY_line, ant::Object::OL_box, true, lay::AC_Global, std::string ()));
templates.push_back (ant::Template (tl::to_string (tr ("Box")), "W=$(abs(X))", "H=$(abs(Y))", "", ant::Object::STY_line, ant::Object::OL_box, true, lay::AC_Any, std::string ()));

return templates;
}
Expand Down
90 changes: 66 additions & 24 deletions src/db/db/built-in-macros/pcell_declaration_helper.lym
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,11 @@ module RBA
# of a PCell
class PCellDeclarationHelper &lt; PCellDeclaration

# makes PCellDeclaration's "layout" method available
if ! self.method_defined?(:_layout_base)
alias_method :_layout_base, :layout
end

# import the Type... constants from PCellParameterDeclaration
PCellParameterDeclaration.constants.each do |c|
if !const_defined?(c)
Expand All @@ -290,18 +295,58 @@ module RBA
@cell = nil
@layer_param_index = []
@layers = nil
@state_stack = []
end

# provide accessors for the current layout and cell (for prod)
attr_reader :layout, :cell, :shape, :layer
attr_reader :cell, :shape, :layer

def layout
@layout || _layout_base()
end

# provide fallback accessors in case of a name clash with a
# parameter
def _layer; @layer; end
def _layout; @layout; end
def _layout; @layout || _layout_base(); end
def _cell; @cell; end
def _shape; @shape; end

# Starts an operation - pushes the state on the state stack

def start
@state_stack &lt;&lt; [ @param_values, @param_states, @layers, @cell, @layout, @layer, @shape ]
self._reset_state
end

# Finishes an operation - pops the state from the state stack

def finish
if ! @state_stack.empty?
@param_values, @param_states, @layers, @cell, @layout, @layer, @shape = @state_stack.pop
else
self._reset_state
end
end

# Resets the state to default values

def _reset_state

@param_values = nil
@param_states = nil
@layers = nil
@layout = nil

# This should be here:
# @cell = nil
# @layer = nil
# @shape = nil
# but this would break backward compatibility of "display_text" (actually
# exploiting this bug) - fix this in the next major release.

end

# A helper method to access the nth parameter

def _get_param(nth, name)
Expand Down Expand Up @@ -410,11 +455,13 @@ module RBA

# implementation of display_text
def display_text(parameters)
self.start
@param_values = parameters
text = ""
begin
text = display_text_impl
ensure
@param_values = nil
self.finish
end
text
end
Expand All @@ -431,94 +478,89 @@ module RBA

# coerce parameters (make consistent)
def coerce_parameters(layout, parameters)
self.start
@param_values = parameters
@layout = layout
ret = parameters
begin
coerce_parameters_impl
ensure
@layout = nil
ret = @param_values
@param_values = nil
self.finish
end
ret
end

# parameter change callback
def callback(layout, name, states)
@param_values = nil
self.start
@param_states = states
@layout = layout
begin
callback_impl(name)
ensure
@param_states = nil
@layout = nil
self.finish
end
end

# produce the layout
def produce(layout, layers, parameters, cell)
self.start
@layers = layers
@cell = cell
@param_values = parameters
@layout = layout
begin
produce_impl
ensure
@layers = nil
@cell = nil
@param_values = nil
@layout = nil
self.finish
end
end

# produce a helper for can_create_from_shape
def can_create_from_shape(layout, shape, layer)
self.start
ret = false
@layout = layout
@shape = shape
@layer = layer
begin
ret = can_create_from_shape_impl
ensure
@layout = nil
@shape = nil
@layer = nil
self.finish
end
ret
end

# produce a helper for parameters_from_shape
# produce a helper for transformation_from_shape
def transformation_from_shape(layout, shape, layer)
self.start
@layout = layout
@shape = shape
@layer = layer
t = nil
begin
t = transformation_from_shape_impl
ensure
@layout = nil
@shape = nil
@layer = nil
self.finish
end
t
end

# produce a helper for parameters_from_shape
# with this helper, the implementation can use the parameter setters
def parameters_from_shape(layout, shape, layer)
self.start
@param_values = @param_decls.map { |pd| pd.default }
@layout = layout
@shape = shape
@layer = layer
begin
parameters_from_shape_impl
ensure
@layout = nil
@shape = nil
@layer = nil
ret = @param_values
self.finish
end
@param_values
ret
end

# default implementation
Expand Down
6 changes: 5 additions & 1 deletion src/db/db/dbInstElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,11 @@ struct DB_PUBLIC InstElement
*/
db::ICplxTrans complex_trans () const
{
return inst_ptr.cell_inst ().complex_trans (*array_inst);
if (array_inst.at_end ()) {
return inst_ptr.cell_inst ().complex_trans ();
} else {
return inst_ptr.cell_inst ().complex_trans (*array_inst);
}
}

/**
Expand Down
15 changes: 9 additions & 6 deletions src/db/db/dbLayout.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2887,15 +2887,18 @@ Layout::get_context_info (cell_index_type cell_index, LayoutOrCellContextInfo &i
if (pcell_variant) {

const db::PCellDeclaration *pcell_decl = ly->pcell_declaration (pcell_variant->pcell_id ());

const std::vector<db::PCellParameterDeclaration> &pcp = pcell_decl->parameter_declarations ();
std::vector<db::PCellParameterDeclaration>::const_iterator pd = pcp.begin ();
for (std::vector<tl::Variant>::const_iterator p = pcell_variant->parameters ().begin (); p != pcell_variant->parameters ().end () && pd != pcp.end (); ++p, ++pd) {
info.pcell_parameters.insert (std::make_pair (pd->get_name (), *p));
if (pcell_decl) {
const std::vector<db::PCellParameterDeclaration> &pcp = pcell_decl->parameter_declarations ();
std::vector<db::PCellParameterDeclaration>::const_iterator pd = pcp.begin ();
for (std::vector<tl::Variant>::const_iterator p = pcell_variant->parameters ().begin (); p != pcell_variant->parameters ().end () && pd != pcp.end (); ++p, ++pd) {
info.pcell_parameters.insert (std::make_pair (pd->get_name (), *p));
}
}

const db::PCellHeader *header = ly->pcell_header (pcell_variant->pcell_id ());
info.pcell_name = header->get_name ();
if (header) {
info.pcell_name = header->get_name ();
}

} else if (ly != this) {
info.cell_name = ly->cell_name (cptr->cell_index ());
Expand Down
101 changes: 101 additions & 0 deletions src/db/db/dbLayoutUtils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -683,5 +683,106 @@ scale_and_snap (db::Layout &layout, db::Cell &cell, db::Coord g, db::Coord m, db
}
}


// ------------------------------------------------------------
// break_polygons implementation

static bool split_polygon (bool first, db::Polygon &poly, size_t max_vertex_count, double max_area_ratio, std::vector<db::Polygon> &parts)
{
if ((max_vertex_count > 0 && poly.vertices () > max_vertex_count) ||
(max_area_ratio > 0 && poly.area_ratio () > max_area_ratio)) {

std::vector<db::Polygon> sp;
db::split_polygon (poly, sp);
for (auto p = sp.begin (); p != sp.end (); ++p) {
split_polygon (false, *p, max_vertex_count, max_area_ratio, parts);
}

return true;

} else {

if (! first) {
parts.push_back (db::Polygon ());
parts.back ().swap (poly);
}

return false;

}
}

void
break_polygons (db::Shapes &shapes, size_t max_vertex_count, double max_area_ratio)
{
if (shapes.is_editable ()) {

std::vector<db::Polygon> new_polygons;
std::vector<db::Shape> to_delete;

for (auto s = shapes.begin (db::ShapeIterator::Polygons | db::ShapeIterator::Paths); ! s.at_end (); ++s) {
db::Polygon poly;
s->instantiate (poly);
if (split_polygon (true, poly, max_vertex_count, max_area_ratio, new_polygons)) {
to_delete.push_back (*s);
}
}

shapes.erase_shapes (to_delete);

for (auto p = new_polygons.begin (); p != new_polygons.end (); ++p) {
shapes.insert (*p);
}

} else {

// In non-editable mode we cannot do "erase", so we use a temporary, editable Shapes container
db::Shapes tmp (true);
tmp.insert (shapes);

shapes.clear ();
break_polygons (tmp, max_vertex_count, max_area_ratio);
shapes.insert (tmp);

tl_assert (!shapes.is_editable ());

}
}

void
break_polygons (db::Layout &layout, db::cell_index_type cell_index, unsigned int layer, size_t max_vertex_count, double max_area_ratio)
{
if (layout.is_valid_cell_index (cell_index) && layout.is_valid_layer (layer)) {
db::Cell &cell = layout.cell (cell_index);
break_polygons (cell.shapes (layer), max_vertex_count, max_area_ratio);
}
}

void
break_polygons (db::Layout &layout, unsigned int layer, size_t max_vertex_count, double max_area_ratio)
{
for (db::cell_index_type ci = 0; ci < layout.cells (); ++ci) {
if (layout.is_valid_cell_index (ci)) {
db::Cell &cell = layout.cell (ci);
break_polygons (cell.shapes (layer), max_vertex_count, max_area_ratio);
}
}
}

void
break_polygons (db::Layout &layout, size_t max_vertex_count, double max_area_ratio)
{
for (db::cell_index_type ci = 0; ci < layout.cells (); ++ci) {
if (layout.is_valid_cell_index (ci)) {
db::Cell &cell = layout.cell (ci);
for (unsigned int li = 0; li < layout.layers (); ++li) {
if (layout.is_valid_layer (li)) {
break_polygons (cell.shapes (li), max_vertex_count, max_area_ratio);
}
}
}
}
}

}

27 changes: 27 additions & 0 deletions src/db/db/dbLayoutUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,33 @@ class DB_PUBLIC ContextCache
*/
DB_PUBLIC void scale_and_snap (db::Layout &layout, db::Cell &cell, db::Coord g, db::Coord m, db::Coord d);

/**
* @brief Breaks polygons according to max_vertex_count and max_area_ratio
*
* This method will investigate all polygons on the given layer and cell and split them in case they
* have more than the specified vertices and an bounding-box area to polygon area ratio larget
* than the specified max_area_ratio. This serves optimization for algorithms needing a good
* bounding box approximation.
*
* Setting max_vertex_count or max_area_ratio to 0 disables the respective check.
*/
DB_PUBLIC void break_polygons (db::Layout &layout, db::cell_index_type cell_index, unsigned int layer, size_t max_vertex_count, double max_area_ratio);

/**
* @brief Like "break_polygons" before, but applies it to all cells.
*/
DB_PUBLIC void break_polygons (db::Layout &layout, unsigned int layer, size_t max_vertex_count, double max_area_ratio);

/**
* @brief Like "break_polygons" before, but applies it to all cells and all layers.
*/
DB_PUBLIC void break_polygons (db::Layout &layout, size_t max_vertex_count, double max_area_ratio);

/**
* @brief Like "break_polygons" before, but applies it to the given Shapes container.
*/
DB_PUBLIC void break_polygons (db::Shapes &shapes, size_t max_vertex_count, double max_area_ratio);

} // namespace db

#endif
Expand Down
Loading

0 comments on commit 1040e81

Please sign in to comment.