mirror of https://github.com/KLayout/klayout.git
WIP
This commit is contained in:
parent
5b3ce9ff30
commit
2a50c87969
|
|
@ -58,7 +58,6 @@ SOURCES = \
|
|||
dbLog.cc \
|
||||
dbManager.cc \
|
||||
dbMatrix.cc \
|
||||
dbMeasure.cc \
|
||||
dbMemStatistics.cc \
|
||||
dbMutableEdgePairs.cc \
|
||||
dbMutableEdges.cc \
|
||||
|
|
@ -140,6 +139,7 @@ SOURCES = \
|
|||
gsiDeclDbLog.cc \
|
||||
gsiDeclDbManager.cc \
|
||||
gsiDeclDbMatrix.cc \
|
||||
gsiDeclDbMeasureHelpers.cc \
|
||||
gsiDeclDbMetaInfo.cc \
|
||||
gsiDeclDbPath.cc \
|
||||
gsiDeclDbPoint.cc \
|
||||
|
|
@ -296,7 +296,6 @@ HEADERS = \
|
|||
dbLog.h \
|
||||
dbManager.h \
|
||||
dbMatrix.h \
|
||||
dbMeasure.h \
|
||||
dbMemStatistics.h \
|
||||
dbMetaInfo.h \
|
||||
dbMutableEdgePairs.h \
|
||||
|
|
|
|||
|
|
@ -453,18 +453,23 @@ public:
|
|||
|
||||
virtual void process (const db::object_with_properties<shape_type> &shape, std::vector<db::object_with_properties<result_type> > &res) const
|
||||
{
|
||||
res = do_process (shape);
|
||||
res = do_process_wp (shape);
|
||||
|
||||
auto res_no_prop = do_process (shape.base ());
|
||||
for (auto i = res_no_prop.begin (); i != res_no_prop.end (); ++i) {
|
||||
res.push_back (db::object_with_properties<result_type> (*i, shape.properties_id ()));
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<db::object_with_properties<result_type> > issue_do_process (const db::object_with_properties<shape_type> &) const
|
||||
std::vector<result_type> issue_do_process (const shape_type &) const
|
||||
{
|
||||
return std::vector<db::object_with_properties<result_type> > ();
|
||||
return std::vector<result_type> ();
|
||||
}
|
||||
|
||||
std::vector<db::object_with_properties<result_type> > do_process (const db::object_with_properties<shape_type> &shape) const
|
||||
std::vector<result_type> do_process (const shape_type &shape) const
|
||||
{
|
||||
if (f_process.can_issue ()) {
|
||||
return f_process.issue<shape_processor_impl, std::vector<db::object_with_properties<result_type> >, const db::object_with_properties<shape_type> &> (&shape_processor_impl::issue_do_process, shape);
|
||||
return f_process.issue<shape_processor_impl, std::vector<result_type>, const shape_type &> (&shape_processor_impl::issue_do_process, shape);
|
||||
} else {
|
||||
return issue_do_process (shape);
|
||||
}
|
||||
|
|
@ -472,6 +477,22 @@ public:
|
|||
|
||||
gsi::Callback f_process;
|
||||
|
||||
std::vector<db::object_with_properties<result_type> > issue_do_process_wp (const db::object_with_properties<shape_type> &) const
|
||||
{
|
||||
return std::vector<db::object_with_properties<result_type> > ();
|
||||
}
|
||||
|
||||
std::vector<db::object_with_properties<result_type> > do_process_wp (const db::object_with_properties<shape_type> &shape) const
|
||||
{
|
||||
if (f_process_wp.can_issue ()) {
|
||||
return f_process_wp.issue<shape_processor_impl, std::vector<db::object_with_properties<result_type> >, const db::object_with_properties<shape_type> &> (&shape_processor_impl::issue_do_process_wp, shape);
|
||||
} else {
|
||||
return issue_do_process_wp (shape);
|
||||
}
|
||||
}
|
||||
|
||||
gsi::Callback f_process_wp;
|
||||
|
||||
static gsi::Methods method_decls (bool with_merged_options)
|
||||
{
|
||||
gsi::Methods decls =
|
||||
|
|
@ -482,9 +503,15 @@ public:
|
|||
"The output list may be empty to entirely discard the input shape. It may also contain more than a single shape.\n"
|
||||
"In that case, the number of total shapes may grow during application of the processor.\n"
|
||||
"\n"
|
||||
"Since version 0.30.3, this method will always receive objects with properties and is also able to deliver them - "
|
||||
"hence modify the properties.\n"
|
||||
"'process_with_properties' is no longer supported."
|
||||
"Instead of implementing 'process', you can also implement \\process_with_properties. The latter function "
|
||||
"allows modifying the properties of an object."
|
||||
) +
|
||||
callback ("process_witp_properties", &shape_processor_impl::issue_do_process_wp, &shape_processor_impl::f_process_wp, gsi::arg ("shape"),
|
||||
"@brief Processes a shape with properties\n"
|
||||
"This method is called in addition to \\process. If reimplemented it allows producing objects "
|
||||
"with different properties than the input one.\n"
|
||||
"\n"
|
||||
"Modification of properties is supported since version 0.30.3.\n"
|
||||
);
|
||||
|
||||
return decls + shape_processor_base<ProcessorBase>::method_decls (with_merged_options);
|
||||
|
|
|
|||
|
|
@ -25,104 +25,234 @@
|
|||
namespace gsi
|
||||
{
|
||||
|
||||
/**
|
||||
* @brief Provides methods to handle measurement functions on various containers
|
||||
*/
|
||||
template <class Container, class ProcessorBase, class FilterBase>
|
||||
struct measure_methods
|
||||
class ShapeFunction
|
||||
: public tl::EvalFunction
|
||||
{
|
||||
/**
|
||||
* @brief Computes one or many properties from expressions
|
||||
*
|
||||
* This method will use the shapes from the "input" container and compute properties from them using the
|
||||
* given expression from "expressions". This map specifies the name of the target property, the value
|
||||
* specifies the expression to execute.
|
||||
*
|
||||
* The expressions can make use of the following variables and functions:
|
||||
* * "shape": the shape which is currently seen
|
||||
* * "<prop-name>": an existing property from the shape currently seen (or nil, if no such property is present).
|
||||
* This is a shortcut, only for properties with string names that are compatible with variable names
|
||||
* * "value(<name>)": the value of the property with the given name - if multiple properties with that
|
||||
* name are present, one value is returned
|
||||
* * "values(<name>)": a list of values for all properties with the given name
|
||||
*
|
||||
* Returns the new container with the computed properties attached.
|
||||
*/
|
||||
Container computed_properties (Container *input, const std::map<tl::Variant, std::string> &expressions, bool clear_properties);
|
||||
public:
|
||||
ShapeFunction (MeasureEval *eval)
|
||||
: mp_eval (eval)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Computes one or many properties from expressions
|
||||
*
|
||||
* Like "computed_properties", this method computes properties, but attaches them to the existing shapes.
|
||||
* As a side effect, the shapes may be merged if "merged_semantics" applies. If "clear_properties" is true,
|
||||
* any existing properties will be removed. If not, the new properties are added to the existing ones.
|
||||
*/
|
||||
void compute_properties_in_place (Container *container, const std::map<tl::Variant, std::string> &expressions, bool clear_properties);
|
||||
virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> * /*kwargs*/) const
|
||||
{
|
||||
if (args.size () != 0) {
|
||||
throw tl::EvalError (tl::to_string (tr ("'shape' function does not take arguments")), context);
|
||||
}
|
||||
out = mp_eval->shape_func ();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Selects all shapes for which the condition expression renders true (or the inverse)
|
||||
*
|
||||
* The condition expression can use the features as described for "computed_properties".
|
||||
* If inverse is false, all shapes are selected for which the condition renders true. If
|
||||
* inverse is true, all shapes are selected for which the condition renders false.
|
||||
*/
|
||||
Container selected_if (const Container *container, const std::string &condition_expression, bool inverse);
|
||||
|
||||
/**
|
||||
* @brief In-place version of "selected_if"
|
||||
*/
|
||||
void select_if (Container *container, const std::string &condition_expression, bool inverse);
|
||||
|
||||
/**
|
||||
* @brief Splits the container into one for which is the condition is true and one with the other shapes
|
||||
*/
|
||||
std::pair<Container, Container> split_if (const Container *container, const std::string &condition_expression);
|
||||
private:
|
||||
MeasureEval *mp_eval;
|
||||
};
|
||||
|
||||
template <class Container, class ProcessorBase, class FilterBase>
|
||||
Container
|
||||
measure_methods<Container, ProcessorBase, FilterBase>::computed_properties (Container *container, const std::map<tl::Variant, std::string> &expressions, bool clear_properties)
|
||||
class ValueFunction
|
||||
: public tl::EvalFunction
|
||||
{
|
||||
property_computation_processor<ProcessorBase, Container> proc (container, expressions, !clear_properties);
|
||||
return container->processed (proc);
|
||||
public:
|
||||
ValueFunction (MeasureEval *eval)
|
||||
: mp_eval (eval)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> * /*kwargs*/) const
|
||||
{
|
||||
if (args.size () != 1) {
|
||||
throw tl::EvalError (tl::to_string (tr ("'value' function takes one argument")), context);
|
||||
}
|
||||
out = mp_eval->value_func (args [0]);
|
||||
}
|
||||
|
||||
private:
|
||||
MeasureEval *mp_eval;
|
||||
};
|
||||
|
||||
class ValuesFunction
|
||||
: public tl::EvalFunction
|
||||
{
|
||||
public:
|
||||
ValuesFunction (MeasureEval *eval)
|
||||
: mp_eval (eval)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> * /*kwargs*/) const
|
||||
{
|
||||
if (args.size () != 1) {
|
||||
throw tl::EvalError (tl::to_string (tr ("'values' function takes one argument")), context);
|
||||
}
|
||||
out = mp_eval->values_func (args [0]);
|
||||
}
|
||||
|
||||
private:
|
||||
MeasureEval *mp_eval;
|
||||
};
|
||||
|
||||
class PropertyFunction
|
||||
: public tl::EvalFunction
|
||||
{
|
||||
public:
|
||||
PropertyFunction (MeasureEval *eval, const tl::Variant &name)
|
||||
: mp_eval (eval), m_name_id (db::property_names_id (name))
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> * /*kwargs*/) const
|
||||
{
|
||||
if (args.size () != 0) {
|
||||
throw tl::EvalError (tl::to_string (tr ("Property getter function does not take arguments")), context);
|
||||
}
|
||||
out = mp_eval->value_func (m_name_id);
|
||||
}
|
||||
|
||||
private:
|
||||
MeasureEval *mp_eval;
|
||||
db::property_names_id_type m_name_id;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// MeasureEval implementation
|
||||
|
||||
MeasureEval::MeasureEval ()
|
||||
: m_shape_type (None), m_prop_id (0)
|
||||
{
|
||||
mp_shape.any = 0;
|
||||
}
|
||||
|
||||
template <class Container, class ProcessorBase, class FilterBase>
|
||||
void
|
||||
measure_methods<Container, ProcessorBase, FilterBase>::compute_properties_in_place (Container *container, const std::map<tl::Variant, std::string> &expressions, bool clear_properties)
|
||||
MeasureEval::init ()
|
||||
{
|
||||
property_computation_processor<ProcessorBase, Container> proc (container, expressions, !clear_properties);
|
||||
container->process (proc);
|
||||
define_function ("shape", new ShapeFunction (this));
|
||||
define_function ("value", new ValueFunction (this));
|
||||
define_function ("values", new ValuesFunction (this));
|
||||
}
|
||||
|
||||
template <class Container, class ProcessorBase, class FilterBase>
|
||||
Container
|
||||
measure_methods<Container, ProcessorBase, FilterBase>::selected_if (const Container *container, const std::string &condition_expression, bool inverse)
|
||||
{
|
||||
expression_filter<FilterBase, Container> filter (condition_expression, inverse);
|
||||
return container->filtered (filter);
|
||||
}
|
||||
|
||||
template <class Container, class ProcessorBase, class FilterBase>
|
||||
void
|
||||
measure_methods<Container, ProcessorBase, FilterBase>::select_if (Container *container, const std::string &condition_expression, bool inverse)
|
||||
MeasureEval::reset_shape () const
|
||||
{
|
||||
expression_filter<FilterBase, Container> filter (condition_expression, inverse);
|
||||
container->filter (filter);
|
||||
m_shape_type = None;
|
||||
mp_shape.any = 0;
|
||||
m_prop_id = 0;
|
||||
}
|
||||
|
||||
template <class Container, class ProcessorBase, class FilterBase>
|
||||
std::pair<Container, Container>
|
||||
measure_methods<Container, ProcessorBase, FilterBase>::split_if (const Container *container, const std::string &condition_expression)
|
||||
void
|
||||
MeasureEval::set_shape (const db::Polygon *poly) const
|
||||
{
|
||||
expression_filter<FilterBase, Container> filter (condition_expression, false);
|
||||
return container->split_filter (filter);
|
||||
m_shape_type = Polygon;
|
||||
mp_shape.poly = poly;
|
||||
}
|
||||
|
||||
// explicit instantiations
|
||||
template struct measure_methods<db::Region, db::shape_collection_processor<db::Polygon, db::Polygon>, db::AllMustMatchFilter>;
|
||||
template struct measure_methods<db::Edges, db::shape_collection_processor<db::Edge, db::Edge>, db::AllEdgesMustMatchFilter>;
|
||||
template struct measure_methods<db::EdgePairs, db::shape_collection_processor<db::EdgePair, db::EdgePair>, db::EdgePairFilterBase>;
|
||||
template struct measure_methods<db::Texts, db::shape_collection_processor<db::Text, db::Text>, db::TextFilterBase>;
|
||||
void
|
||||
MeasureEval::set_shape (const db::PolygonRef *poly) const
|
||||
{
|
||||
m_shape_type = PolygonRef;
|
||||
mp_shape.poly_ref = poly;
|
||||
}
|
||||
|
||||
void
|
||||
MeasureEval::set_shape (const db::Edge *edge) const
|
||||
{
|
||||
m_shape_type = Edge;
|
||||
mp_shape.edge = edge;
|
||||
}
|
||||
|
||||
void
|
||||
MeasureEval::set_shape (const db::EdgePair *edge_pair) const
|
||||
{
|
||||
m_shape_type = EdgePair;
|
||||
mp_shape.edge_pair = edge_pair;
|
||||
}
|
||||
|
||||
void
|
||||
MeasureEval::set_shape (const db::Text *text) const
|
||||
{
|
||||
m_shape_type = Text;
|
||||
mp_shape.text = text;
|
||||
}
|
||||
|
||||
void
|
||||
MeasureEval::set_prop_id (db::properties_id_type prop_id) const
|
||||
{
|
||||
m_prop_id = prop_id;
|
||||
}
|
||||
|
||||
void
|
||||
MeasureEval::resolve_name (const std::string &name, const tl::EvalFunction *&function, const tl::Variant *&value, tl::Variant *&var)
|
||||
{
|
||||
tl::Eval::resolve_name (name, function, value, var);
|
||||
|
||||
if (!function && !value && !var) {
|
||||
// connect the name with a function getting the property value
|
||||
tl::EvalFunction *f = new PropertyFunction (this, name);
|
||||
define_function (name, f);
|
||||
function = f;
|
||||
}
|
||||
}
|
||||
|
||||
tl::Variant
|
||||
MeasureEval::shape_func () const
|
||||
{
|
||||
switch (m_shape_type)
|
||||
{
|
||||
case None:
|
||||
default:
|
||||
return tl::Variant ();
|
||||
case Polygon:
|
||||
return tl::Variant (mp_shape.poly);
|
||||
case PolygonRef:
|
||||
return tl::Variant (mp_shape.poly_ref);
|
||||
case Edge:
|
||||
return tl::Variant (mp_shape.edge);
|
||||
case EdgePair:
|
||||
return tl::Variant (mp_shape.edge_pair);
|
||||
case Text:
|
||||
return tl::Variant (mp_shape.text);
|
||||
}
|
||||
}
|
||||
|
||||
tl::Variant
|
||||
MeasureEval::value_func (db::property_names_id_type name_id) const
|
||||
{
|
||||
const db::PropertiesSet &ps = db::properties (m_prop_id);
|
||||
for (auto i = ps.begin (); i != ps.end (); ++i) {
|
||||
if (i->first == name_id) {
|
||||
return db::property_value (i->second);
|
||||
}
|
||||
}
|
||||
|
||||
return tl::Variant ();
|
||||
}
|
||||
|
||||
tl::Variant
|
||||
MeasureEval::value_func (const tl::Variant &name) const
|
||||
{
|
||||
const db::PropertiesSet &ps = db::properties (m_prop_id);
|
||||
for (auto i = ps.begin (); i != ps.end (); ++i) {
|
||||
if (db::property_name (i->first) == name) {
|
||||
return db::property_value (i->second);
|
||||
}
|
||||
}
|
||||
|
||||
return tl::Variant ();
|
||||
}
|
||||
|
||||
tl::Variant
|
||||
MeasureEval::values_func (const tl::Variant &name) const
|
||||
{
|
||||
tl::Variant res = tl::Variant::empty_list ();
|
||||
|
||||
const db::PropertiesSet &ps = db::properties (m_prop_id);
|
||||
for (auto i = ps.begin (); i != ps.end (); ++i) {
|
||||
if (db::property_name (i->first) == name) {
|
||||
res.push (db::property_value (i->second));
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,167 +44,30 @@ namespace gsi
|
|||
*
|
||||
* This class provides the methods, functions and variables for the expressions.
|
||||
*/
|
||||
class MeasureEval
|
||||
class DB_PUBLIC MeasureEval
|
||||
: public tl::Eval
|
||||
{
|
||||
public:
|
||||
MeasureEval ()
|
||||
: m_shape_type (None), m_prop_id (0)
|
||||
{
|
||||
mp_shape.any = 0;
|
||||
}
|
||||
MeasureEval ();
|
||||
|
||||
void init ()
|
||||
{
|
||||
define_function ("shape", new ShapesFunction (this));
|
||||
define_function ("value", new ValueFunction (this));
|
||||
define_function ("values", new ValuesFunction (this));
|
||||
}
|
||||
void init ();
|
||||
|
||||
void reset_shape () const
|
||||
{
|
||||
m_shape_type = None;
|
||||
mp_shape.any = 0;
|
||||
m_prop_id = 0;
|
||||
}
|
||||
|
||||
void set_shape (const db::Polygon *poly) const
|
||||
{
|
||||
m_shape_type = Polygon;
|
||||
mp_shape.poly = poly;
|
||||
}
|
||||
|
||||
void set_shape (const db::PolygonRef *poly) const
|
||||
{
|
||||
m_shape_type = PolygonRef;
|
||||
mp_shape.poly_ref = poly;
|
||||
}
|
||||
|
||||
void set_shape (const db::Edge *edge) const
|
||||
{
|
||||
m_shape_type = Edge;
|
||||
mp_shape.edge = edge;
|
||||
}
|
||||
|
||||
void set_shape (const db::EdgePair *edge_pair) const
|
||||
{
|
||||
m_shape_type = EdgePair;
|
||||
mp_shape.edge_pair = edge_pair;
|
||||
}
|
||||
|
||||
void set_shape (const db::Text *text) const
|
||||
{
|
||||
m_shape_type = Text;
|
||||
mp_shape.text = text;
|
||||
}
|
||||
|
||||
void set_prop_id (db::properties_id_type prop_id) const
|
||||
{
|
||||
m_prop_id = prop_id;
|
||||
}
|
||||
void reset_shape () const;
|
||||
void set_shape (const db::Polygon *poly) const;
|
||||
void set_shape (const db::PolygonRef *poly) const;
|
||||
void set_shape (const db::Edge *edge) const;
|
||||
void set_shape (const db::EdgePair *edge_pair) const;
|
||||
void set_shape (const db::Text *text) const;
|
||||
void set_prop_id (db::properties_id_type prop_id) const;
|
||||
|
||||
protected:
|
||||
virtual void resolve_name (const std::string &name, const tl::EvalFunction *&function, const tl::Variant *&value, tl::Variant *&var)
|
||||
{
|
||||
tl::Eval::resolve_name (name, function, value, var);
|
||||
|
||||
if (!function && !value && !var) {
|
||||
// connect the name with a function getting the property value
|
||||
tl::EvalFunction *f = new PropertyFunction (this, name);
|
||||
define_function (name, f);
|
||||
function = f;
|
||||
}
|
||||
}
|
||||
virtual void resolve_name (const std::string &name, const tl::EvalFunction *&function, const tl::Variant *&value, tl::Variant *&var);
|
||||
|
||||
private:
|
||||
class ShapesFunction
|
||||
: public tl::EvalFunction
|
||||
{
|
||||
public:
|
||||
ShapesFunction (MeasureEval *eval)
|
||||
: mp_eval (eval)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> * /*kwargs*/) const
|
||||
{
|
||||
if (args.size () != 0) {
|
||||
throw tl::EvalError (tl::to_string (tr ("'shape' function does not take arguments")), context);
|
||||
}
|
||||
out = mp_eval->shape_func ();
|
||||
}
|
||||
|
||||
private:
|
||||
MeasureEval *mp_eval;
|
||||
};
|
||||
|
||||
class ValueFunction
|
||||
: public tl::EvalFunction
|
||||
{
|
||||
public:
|
||||
ValueFunction (MeasureEval *eval)
|
||||
: mp_eval (eval)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> * /*kwargs*/) const
|
||||
{
|
||||
if (args.size () != 1) {
|
||||
throw tl::EvalError (tl::to_string (tr ("'value' function takes one argument")), context);
|
||||
}
|
||||
out = mp_eval->value_func (args [0]);
|
||||
}
|
||||
|
||||
private:
|
||||
MeasureEval *mp_eval;
|
||||
};
|
||||
|
||||
class ValuesFunction
|
||||
: public tl::EvalFunction
|
||||
{
|
||||
public:
|
||||
ValuesFunction (MeasureEval *eval)
|
||||
: mp_eval (eval)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> * /*kwargs*/) const
|
||||
{
|
||||
if (args.size () != 1) {
|
||||
throw tl::EvalError (tl::to_string (tr ("'values' function takes one argument")), context);
|
||||
}
|
||||
out = mp_eval->values_func (args [0]);
|
||||
}
|
||||
|
||||
private:
|
||||
MeasureEval *mp_eval;
|
||||
};
|
||||
|
||||
class PropertyFunction
|
||||
: public tl::EvalFunction
|
||||
{
|
||||
public:
|
||||
PropertyFunction (MeasureEval *eval, const tl::Variant &name)
|
||||
: mp_eval (eval), m_name (name)
|
||||
{
|
||||
// .. nothing yet ..
|
||||
}
|
||||
|
||||
virtual void execute (const tl::ExpressionParserContext &context, tl::Variant &out, const std::vector<tl::Variant> &args, const std::map<std::string, tl::Variant> * /*kwargs*/) const
|
||||
{
|
||||
if (args.size () != 0) {
|
||||
throw tl::EvalError (tl::to_string (tr ("Property getter function does not take arguments")), context);
|
||||
}
|
||||
out = mp_eval->value_func (m_name);
|
||||
}
|
||||
|
||||
private:
|
||||
MeasureEval *mp_eval;
|
||||
tl::Variant m_name;
|
||||
};
|
||||
friend class ShapeFunction;
|
||||
friend class ValueFunction;
|
||||
friend class ValuesFunction;
|
||||
friend class PropertyFunction;
|
||||
|
||||
union ShapeRef
|
||||
{
|
||||
|
|
@ -230,51 +93,10 @@ private:
|
|||
mutable ShapeRef mp_shape;
|
||||
mutable db::properties_id_type m_prop_id;
|
||||
|
||||
tl::Variant shape_func () const
|
||||
{
|
||||
switch (m_shape_type)
|
||||
{
|
||||
case None:
|
||||
default:
|
||||
return tl::Variant ();
|
||||
case Polygon:
|
||||
return tl::Variant (mp_shape.poly);
|
||||
case PolygonRef:
|
||||
return tl::Variant (mp_shape.poly_ref);
|
||||
case Edge:
|
||||
return tl::Variant (mp_shape.edge);
|
||||
case EdgePair:
|
||||
return tl::Variant (mp_shape.edge_pair);
|
||||
case Text:
|
||||
return tl::Variant (mp_shape.text);
|
||||
}
|
||||
}
|
||||
|
||||
tl::Variant value_func (const tl::Variant &name) const
|
||||
{
|
||||
const db::PropertiesSet &ps = db::properties (m_prop_id);
|
||||
for (auto i = ps.begin (); i != ps.end (); ++i) {
|
||||
if (db::property_name (i->first) == name) {
|
||||
return db::property_value (i->second);
|
||||
}
|
||||
}
|
||||
|
||||
return tl::Variant ();
|
||||
}
|
||||
|
||||
tl::Variant values_func (const tl::Variant &name) const
|
||||
{
|
||||
tl::Variant res = tl::Variant::empty_list ();
|
||||
|
||||
const db::PropertiesSet &ps = db::properties (m_prop_id);
|
||||
for (auto i = ps.begin (); i != ps.end (); ++i) {
|
||||
if (db::property_name (i->first) == name) {
|
||||
res.push (db::property_value (i->second));
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
tl::Variant shape_func () const;
|
||||
tl::Variant value_func (db::property_names_id_type name_id) const;
|
||||
tl::Variant value_func (const tl::Variant &name) const;
|
||||
tl::Variant values_func (const tl::Variant &name) const;
|
||||
};
|
||||
|
||||
inline db::RecursiveShapeIterator
|
||||
|
|
@ -341,7 +163,7 @@ public:
|
|||
typedef typename ProcessorBase::result_type result_type;
|
||||
|
||||
property_computation_processor (const Container *container, const std::map<tl::Variant, std::string> &expressions, bool copy_properties)
|
||||
: m_eval (), m_copy_properties (copy_properties)
|
||||
: m_eval (), m_copy_properties (copy_properties), m_expression_strings (expressions)
|
||||
{
|
||||
if (container) {
|
||||
this->set_result_is_merged (is_merged (container));
|
||||
|
|
@ -350,7 +172,7 @@ public:
|
|||
m_eval.init ();
|
||||
|
||||
// compile the expressions
|
||||
for (auto e = expressions.begin (); e != expressions.end (); ++e) {
|
||||
for (auto e = m_expression_strings.begin (); e != m_expression_strings.end (); ++e) {
|
||||
m_expressions.push_back (std::make_pair (db::property_names_id (e->first), tl::Expression ()));
|
||||
tl::Extractor ex (e->second.c_str ());
|
||||
m_eval.parse (m_expressions.back ().second, ex);
|
||||
|
|
@ -367,6 +189,9 @@ public:
|
|||
db::PropertiesSet ps;
|
||||
if (m_copy_properties) {
|
||||
ps = db::properties (shape.properties_id ());
|
||||
for (auto e = m_expressions.begin (); e != m_expressions.end (); ++e) {
|
||||
ps.erase (e->first);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto e = m_expressions.begin (); e != m_expressions.end (); ++e) {
|
||||
|
|
@ -380,6 +205,7 @@ public:
|
|||
MeasureEval m_eval;
|
||||
std::vector<std::pair<db::property_names_id_type, tl::Expression> > m_expressions;
|
||||
bool m_copy_properties;
|
||||
std::map<tl::Variant, std::string> m_expression_strings;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -397,12 +223,12 @@ public:
|
|||
typedef typename FilterBase::shape_type shape_type;
|
||||
|
||||
expression_filter (const std::string &expression, bool inverse)
|
||||
: m_eval (), m_inverse (inverse)
|
||||
: m_eval (), m_inverse (inverse), m_expression_string (expression)
|
||||
{
|
||||
m_eval.init ();
|
||||
|
||||
// compile the expression
|
||||
tl::Extractor ex (expression.c_str ());
|
||||
tl::Extractor ex (m_expression_string.c_str ());
|
||||
m_eval.parse (m_expression, ex);
|
||||
}
|
||||
|
||||
|
|
@ -429,6 +255,7 @@ public:
|
|||
MeasureEval m_eval;
|
||||
tl::Expression m_expression;
|
||||
bool m_inverse;
|
||||
std::string m_expression_string;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -227,7 +227,9 @@ Class<gsi::PolygonFilterImpl> decl_PolygonFilterImpl (decl_PolygonFilterBase, "d
|
|||
// ---------------------------------------------------------------------------------
|
||||
// PolygonProcessor binding
|
||||
|
||||
Class<shape_processor_impl<db::PolygonProcessorBase> > decl_PolygonOperator ("db", "PolygonOperator",
|
||||
Class<db::PolygonProcessorBase> decl_PolygonProcessorBase ("db", "PolygonProcessorBase", "@hide");
|
||||
|
||||
Class<shape_processor_impl<db::PolygonProcessorBase> > decl_PolygonOperator (decl_PolygonProcessorBase, "db", "PolygonOperator",
|
||||
shape_processor_impl<db::PolygonProcessorBase>::method_decls (true),
|
||||
"@brief A generic polygon operator\n"
|
||||
"\n"
|
||||
|
|
@ -279,7 +281,7 @@ new_pcp (const db::Region *container, const std::map<tl::Variant, std::string> &
|
|||
return new property_computation_processor<db::PolygonProcessorBase, db::Region> (container, expressions, copy_properties);
|
||||
}
|
||||
|
||||
Class<property_computation_processor<db::PolygonProcessorBase, db::Region> > decl_PolygonPropertiesExpressions ("db", "PolygonPropertiesExpressions",
|
||||
Class<property_computation_processor<db::PolygonProcessorBase, db::Region> > decl_PolygonPropertiesExpressions (decl_PolygonProcessorBase, "db", "PolygonPropertiesExpressions",
|
||||
property_computation_processor<db::PolygonProcessorBase, db::Region>::method_decls (true) +
|
||||
gsi::constructor ("new", &new_pcp, gsi::arg ("region"), gsi::arg ("expressions"), gsi::arg ("copy_properties", false),
|
||||
"@brief Creates a new properties expressions operator\n"
|
||||
|
|
@ -307,7 +309,9 @@ Class<property_computation_processor<db::PolygonProcessorBase, db::Region> > dec
|
|||
"This class has been introduced in version 0.30.3.\n"
|
||||
);
|
||||
|
||||
Class<shape_processor_impl<db::PolygonToEdgeProcessorBase> > decl_PolygonToEdgeProcessor ("db", "PolygonToEdgeOperator",
|
||||
Class<db::PolygonToEdgeProcessorBase> decl_PolygonToEdgeProcessorBase ("db", "PolygonToEdgeProcessorBase", "@hide");
|
||||
|
||||
Class<shape_processor_impl<db::PolygonToEdgeProcessorBase> > decl_PolygonToEdgeProcessor (decl_PolygonToEdgeProcessorBase, "db", "PolygonToEdgeOperator",
|
||||
shape_processor_impl<db::PolygonToEdgeProcessorBase>::method_decls (true),
|
||||
"@brief A generic polygon-to-edge operator\n"
|
||||
"\n"
|
||||
|
|
@ -331,7 +335,9 @@ Class<shape_processor_impl<db::PolygonToEdgeProcessorBase> > decl_PolygonToEdgeP
|
|||
"This class has been introduced in version 0.29.\n"
|
||||
);
|
||||
|
||||
Class<shape_processor_impl<db::PolygonToEdgePairProcessorBase> > decl_PolygonToEdgePairProcessor ("db", "PolygonToEdgePairOperator",
|
||||
Class<db::PolygonToEdgePairProcessorBase> decl_PolygonToEdgePairProcessorBase ("db", "PolygonToEdgePairProcessorBase", "@hide");
|
||||
|
||||
Class<shape_processor_impl<db::PolygonToEdgePairProcessorBase> > decl_PolygonToEdgePairProcessor (decl_PolygonToEdgePairProcessorBase, "db", "PolygonToEdgePairOperator",
|
||||
shape_processor_impl<db::PolygonToEdgePairProcessorBase>::method_decls (true),
|
||||
"@brief A generic polygon-to-edge-pair operator\n"
|
||||
"\n"
|
||||
|
|
@ -686,22 +692,22 @@ static std::vector<db::Region> split_filter (const db::Region *r, const PolygonF
|
|||
return as_2region_vector (r->split_filter (*f));
|
||||
}
|
||||
|
||||
static db::Region processed_pp (const db::Region *r, const shape_processor_impl<db::PolygonProcessorBase> *f)
|
||||
static db::Region processed_pp (const db::Region *r, const db::PolygonProcessorBase *f)
|
||||
{
|
||||
return r->processed (*f);
|
||||
}
|
||||
|
||||
static void process_pp (db::Region *r, const shape_processor_impl<db::PolygonProcessorBase> *f)
|
||||
static void process_pp (db::Region *r, const db::PolygonProcessorBase *f)
|
||||
{
|
||||
r->process (*f);
|
||||
}
|
||||
|
||||
static db::EdgePairs processed_pep (const db::Region *r, const shape_processor_impl<db::PolygonToEdgePairProcessorBase> *f)
|
||||
static db::EdgePairs processed_pep (const db::Region *r, const db::PolygonToEdgePairProcessorBase *f)
|
||||
{
|
||||
return r->processed (*f);
|
||||
}
|
||||
|
||||
static db::Edges processed_pe (const db::Region *r, const shape_processor_impl<db::PolygonToEdgeProcessorBase> *f)
|
||||
static db::Edges processed_pe (const db::Region *r, const db::PolygonToEdgeProcessorBase *f)
|
||||
{
|
||||
return r->processed (*f);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue