mirror of https://github.com/KLayout/klayout.git
Fixed #75 (Python PCell issue when parameters are called 'layer')
This commit - Ignores exceptions when checking for PCells that accept shapes. Hence a single rogue one does not break the feature. - Prevents errors when parameters named "layer" are present by making the implementation safe against this case. - In addition, guiding shape parameters of type "Path", "Box" etc. (i.e. integer types) are supported too although they are not recommended for portability.
This commit is contained in:
parent
6a762db29b
commit
6d0fe85425
|
|
@ -226,16 +226,27 @@ class _PCellDeclarationHelperLayerDescriptor(object):
|
||||||
class _PCellDeclarationHelperParameterDescriptor(object):
|
class _PCellDeclarationHelperParameterDescriptor(object):
|
||||||
"""
|
"""
|
||||||
A descriptor object which translates the PCell parameters into class attributes
|
A descriptor object which translates the PCell parameters into class attributes
|
||||||
|
|
||||||
|
In some cases (i.e. can_convert_from_shape), these placeholders are not
|
||||||
|
connected to real parameters (obj._param_values is None). In this case,
|
||||||
|
the descriptor acts as a value holder (self.value)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, param_index):
|
def __init__(self, param_index):
|
||||||
self.param_index = param_index
|
self.param_index = param_index
|
||||||
|
self.value = None
|
||||||
|
|
||||||
def __get__(self, obj, type = None):
|
def __get__(self, obj, type = None):
|
||||||
|
if obj._param_values:
|
||||||
return obj._param_values[self.param_index]
|
return obj._param_values[self.param_index]
|
||||||
|
else:
|
||||||
|
return self.value
|
||||||
|
|
||||||
def __set__(self, obj, value):
|
def __set__(self, obj, value):
|
||||||
|
if obj._param_values:
|
||||||
obj._param_values[self.param_index] = value
|
obj._param_values[self.param_index] = value
|
||||||
|
else:
|
||||||
|
self.value = value
|
||||||
|
|
||||||
class _PCellDeclarationHelper(pya.PCellDeclaration):
|
class _PCellDeclarationHelper(pya.PCellDeclaration):
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -186,15 +186,28 @@ PCellVariant::update (ImportLayerMapping *layer_mapping)
|
||||||
|
|
||||||
shapes (layout ()->guiding_shape_layer ()).insert (db::BoxWithProperties(db::Box (m_parameters[i].to_user<db::DBox> () * (1.0 / layout ()->dbu ())), layout ()->properties_repository ().properties_id (props)));
|
shapes (layout ()->guiding_shape_layer ()).insert (db::BoxWithProperties(db::Box (m_parameters[i].to_user<db::DBox> () * (1.0 / layout ()->dbu ())), layout ()->properties_repository ().properties_id (props)));
|
||||||
|
|
||||||
|
} else if (m_parameters[i].is_user<db::Box> ()) {
|
||||||
|
|
||||||
|
shapes (layout ()->guiding_shape_layer ()).insert (db::BoxWithProperties(m_parameters[i].to_user<db::Box> (), layout ()->properties_repository ().properties_id (props)));
|
||||||
|
|
||||||
} else if (m_parameters[i].is_user<db::DEdge> ()) {
|
} else if (m_parameters[i].is_user<db::DEdge> ()) {
|
||||||
|
|
||||||
shapes (layout ()->guiding_shape_layer ()).insert (db::EdgeWithProperties(db::Edge (m_parameters[i].to_user<db::DEdge> () * (1.0 / layout ()->dbu ())), layout ()->properties_repository ().properties_id (props)));
|
shapes (layout ()->guiding_shape_layer ()).insert (db::EdgeWithProperties(db::Edge (m_parameters[i].to_user<db::DEdge> () * (1.0 / layout ()->dbu ())), layout ()->properties_repository ().properties_id (props)));
|
||||||
|
|
||||||
|
} else if (m_parameters[i].is_user<db::Edge> ()) {
|
||||||
|
|
||||||
|
shapes (layout ()->guiding_shape_layer ()).insert (db::EdgeWithProperties(m_parameters[i].to_user<db::Edge> (), layout ()->properties_repository ().properties_id (props)));
|
||||||
|
|
||||||
} else if (m_parameters[i].is_user<db::DPoint> ()) {
|
} else if (m_parameters[i].is_user<db::DPoint> ()) {
|
||||||
|
|
||||||
db::DPoint p = m_parameters[i].to_user<db::DPoint> ();
|
db::DPoint p = m_parameters[i].to_user<db::DPoint> ();
|
||||||
shapes (layout ()->guiding_shape_layer ()).insert (db::BoxWithProperties(db::Box (db::DBox (p, p) * (1.0 / layout ()->dbu ())), layout ()->properties_repository ().properties_id (props)));
|
shapes (layout ()->guiding_shape_layer ()).insert (db::BoxWithProperties(db::Box (db::DBox (p, p) * (1.0 / layout ()->dbu ())), layout ()->properties_repository ().properties_id (props)));
|
||||||
|
|
||||||
|
} else if (m_parameters[i].is_user<db::Point> ()) {
|
||||||
|
|
||||||
|
db::Point p = m_parameters[i].to_user<db::Point> ();
|
||||||
|
shapes (layout ()->guiding_shape_layer ()).insert (db::BoxWithProperties(db::Box (p, p), layout ()->properties_repository ().properties_id (props)));
|
||||||
|
|
||||||
} else if (m_parameters[i].is_user<db::DPolygon> ()) {
|
} else if (m_parameters[i].is_user<db::DPolygon> ()) {
|
||||||
|
|
||||||
db::complex_trans<db::DCoord, db::Coord> dbu_trans (1.0 / layout ()->dbu ());
|
db::complex_trans<db::DCoord, db::Coord> dbu_trans (1.0 / layout ()->dbu ());
|
||||||
|
|
@ -202,11 +215,21 @@ PCellVariant::update (ImportLayerMapping *layer_mapping)
|
||||||
// Hint: we don't compress the polygon since we don't want to loose information
|
// Hint: we don't compress the polygon since we don't want to loose information
|
||||||
shapes (layout ()->guiding_shape_layer ()).insert (db::PolygonWithProperties(poly, layout ()->properties_repository ().properties_id (props)));
|
shapes (layout ()->guiding_shape_layer ()).insert (db::PolygonWithProperties(poly, layout ()->properties_repository ().properties_id (props)));
|
||||||
|
|
||||||
|
} else if (m_parameters[i].is_user<db::Polygon> ()) {
|
||||||
|
|
||||||
|
db::Polygon poly = m_parameters[i].to_user<db::Polygon> ();
|
||||||
|
// Hint: we don't compress the polygon since we don't want to loose information
|
||||||
|
shapes (layout ()->guiding_shape_layer ()).insert (db::PolygonWithProperties(poly, layout ()->properties_repository ().properties_id (props)));
|
||||||
|
|
||||||
} else if (m_parameters[i].is_user<db::DPath> ()) {
|
} else if (m_parameters[i].is_user<db::DPath> ()) {
|
||||||
|
|
||||||
db::complex_trans<db::DCoord, db::Coord> dbu_trans (1.0 / layout ()->dbu ());
|
db::complex_trans<db::DCoord, db::Coord> dbu_trans (1.0 / layout ()->dbu ());
|
||||||
shapes (layout ()->guiding_shape_layer ()).insert (db::PathWithProperties(dbu_trans * m_parameters[i].to_user<db::DPath> (), layout ()->properties_repository ().properties_id (props)));
|
shapes (layout ()->guiding_shape_layer ()).insert (db::PathWithProperties(dbu_trans * m_parameters[i].to_user<db::DPath> (), layout ()->properties_repository ().properties_id (props)));
|
||||||
|
|
||||||
|
} else if (m_parameters[i].is_user<db::Path> ()) {
|
||||||
|
|
||||||
|
shapes (layout ()->guiding_shape_layer ()).insert (db::PathWithProperties(m_parameters[i].to_user<db::Path> (), layout ()->properties_repository ().properties_id (props)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1084,6 +1084,8 @@ MainService::cm_convert_to_pcell ()
|
||||||
db::Library *lib = db::LibraryManager::instance ().lib (l->second);
|
db::Library *lib = db::LibraryManager::instance ().lib (l->second);
|
||||||
for (db::Layout::pcell_iterator pc = lib->layout ().begin_pcells (); pc != lib->layout ().end_pcells (); ++pc) {
|
for (db::Layout::pcell_iterator pc = lib->layout ().begin_pcells (); pc != lib->layout ().end_pcells (); ++pc) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
const db::PCellDeclaration *pc_decl = lib->layout ().pcell_declaration (pc->second);
|
const db::PCellDeclaration *pc_decl = lib->layout ().pcell_declaration (pc->second);
|
||||||
size_t n = 1000; // 1000 tries max.
|
size_t n = 1000; // 1000 tries max.
|
||||||
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); n > 0 && pc_decl && es != edt_services.end (); ++es) {
|
for (std::vector<edt::Service *>::const_iterator es = edt_services.begin (); n > 0 && pc_decl && es != edt_services.end (); ++es) {
|
||||||
|
|
@ -1103,6 +1105,10 @@ MainService::cm_convert_to_pcell ()
|
||||||
items.push_back (tl::to_qstring (lib->get_name () + "." + pc_decl->name ()));
|
items.push_back (tl::to_qstring (lib->get_name () + "." + pc_decl->name ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} catch (...) {
|
||||||
|
// ignore errors in can_create_from_shape
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue