From 4a44329e381c53c711d544c9affaddc402635c82 Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Mon, 8 Nov 2021 23:18:01 +0100 Subject: [PATCH] Enabling 'enclosed' as a (sometimes) more efficient way of implementing an enclosing check. --- scripts/create_drc_samples.rb | 16 ++++ src/db/db/gsiDeclDbCompoundOperation.cc | 10 +++ src/db/db/gsiDeclDbEdges.cc | 4 +- src/db/db/gsiDeclDbRegion.cc | 3 +- .../drc/built-in-macros/_drc_complex_ops.rb | 2 +- .../built-in-macros/_drc_cop_integration.rb | 79 ++++++++++++++++++ src/drc/drc/built-in-macros/_drc_engine.rb | 1 + src/drc/drc/built-in-macros/_drc_layer.rb | 45 ++++++++-- src/lay/lay/doc/about/drc_ref_global.xml | 79 ++++++++++++++++++ src/lay/lay/doc/about/drc_ref_layer.xml | 43 +++++++++- src/lay/lay/doc/images/drc_encd1.png | Bin 0 -> 9333 bytes src/lay/lay/doc/images/drc_encd1u.png | Bin 0 -> 9446 bytes src/lay/lay/doc/images/drc_encd2.png | Bin 0 -> 9332 bytes src/lay/lay/doc/images/drc_encd2u.png | Bin 0 -> 9503 bytes src/lay/lay/layDRCLVSHelpResources.qrc | 4 + 15 files changed, 275 insertions(+), 11 deletions(-) create mode 100644 src/lay/lay/doc/images/drc_encd1.png create mode 100644 src/lay/lay/doc/images/drc_encd1u.png create mode 100644 src/lay/lay/doc/images/drc_encd2.png create mode 100644 src/lay/lay/doc/images/drc_encd2u.png diff --git a/scripts/create_drc_samples.rb b/scripts/create_drc_samples.rb index f7963be5d..2f0da729b 100644 --- a/scripts/create_drc_samples.rb +++ b/scripts/create_drc_samples.rb @@ -452,6 +452,22 @@ run_demo gen, "input1.drc(enclosing(input2) < 2.0.um)", "drc_enc1u.png" run_demo gen, "input1.drc(enclosing(input2,\n"+ " projection) < 2.0.um)", "drc_enc2u.png" +class Gen + def produce(s1, s2) + s1.insert(RBA::Box::new(3000, 0, 6000, 6000)) + s2.insert(RBA::Box::new(0, 1000, 6000, 7000)) + end +end + +gen = Gen::new + +run_demo gen, "input1.enclosed(input2, 2.0.um)", "drc_encd1.png" +run_demo gen, "input1.enclosed(input2, 2.0.um, projection)", "drc_encd2.png" + +run_demo gen, "input1.drc(enclosed(input2) < 2.0.um)", "drc_encd1u.png" +run_demo gen, "input1.drc(enclosed(input2,\n"+ + " projection) < 2.0.um)", "drc_encd2u.png" + class Gen def produce(s1, s2) diff --git a/src/db/db/gsiDeclDbCompoundOperation.cc b/src/db/db/gsiDeclDbCompoundOperation.cc index 9f2759c1a..9fbdf518f 100644 --- a/src/db/db/gsiDeclDbCompoundOperation.cc +++ b/src/db/db/gsiDeclDbCompoundOperation.cc @@ -460,6 +460,11 @@ static db::CompoundRegionOperationNode *new_enclosing_check (db::CompoundRegionO return new_check_node (other, db::OverlapRelation, true, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, opposite_filter, rect_filter, negative); } +static db::CompoundRegionOperationNode *new_enclosed_check (db::CompoundRegionOperationNode *other, db::Coord d, bool whole_edges, db::metrics_type metrics, const tl::Variant &ignore_angle, const tl::Variant &min_projection, const tl::Variant &max_projection, bool shielded, db::OppositeFilter opposite_filter, db::RectFilter rect_filter, bool negative) +{ + return new_check_node (other, db::InsideRelation, true, d, whole_edges, metrics, ignore_angle, min_projection, max_projection, shielded, opposite_filter, rect_filter, negative); +} + static db::CompoundRegionOperationNode *new_perimeter_filter (db::CompoundRegionOperationNode *input, bool inverse, db::coord_traits::perimeter_type pmin, db::coord_traits::perimeter_type pmax) { check_non_null (input, "input"); @@ -673,6 +678,11 @@ Class decl_CompoundRegionOperationNode ("db", " gsi::constructor ("new_enclosing_check", &new_enclosing_check, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian, "Euclidian"), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max."), gsi::arg ("shielded", true), gsi::arg ("opposite_filter", db::NoOppositeFilter, "NoOppositeFilter"), gsi::arg ("rect_filter", db::NoRectFilter, "NoRectFilter"), gsi::arg ("negative", false), "@brief Creates a node providing an inside (enclosure) check.\n" ) + + gsi::constructor ("new_enclosed_check", &new_enclosed_check, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian, "Euclidian"), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max."), gsi::arg ("shielded", true), gsi::arg ("opposite_filter", db::NoOppositeFilter, "NoOppositeFilter"), gsi::arg ("rect_filter", db::NoRectFilter, "NoRectFilter"), gsi::arg ("negative", false), + "@brief Creates a node providing an enclosed (secondary enclosing primary) check.\n" + "\n" + "This method has been added in version 0.27.5.\n" + ) + gsi::constructor ("new_perimeter_filter", &new_perimeter_filter, gsi::arg ("input"), gsi::arg ("inverse", false), gsi::arg ("pmin", 0), gsi::arg ("pmax", std::numeric_limits::perimeter_type>::max (), "max"), "@brief Creates a node filtering the input by perimeter.\n" "This node renders the input if the perimeter is between pmin and pmax (exclusively). If 'inverse' is set to true, the " diff --git a/src/db/db/gsiDeclDbEdges.cc b/src/db/db/gsiDeclDbEdges.cc index 84a0c9f6d..e302557cf 100644 --- a/src/db/db/gsiDeclDbEdges.cc +++ b/src/db/db/gsiDeclDbEdges.cc @@ -1160,7 +1160,7 @@ Class decl_Edges (decl_dbShapeCollection, "db", "Edges", "The projected length must be larger or equal to \"min_projection\" and less than \"max_projection\". " "If you don't want to specify one threshold, pass nil to the respective value.\n" ) + - method_ext ("inside_check", &inside2, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian, "Euclidian"), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max"), + method_ext ("inside_check|enclosed_check", &inside2, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian, "Euclidian"), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max"), "@brief Performs an inside check with options\n" "@param d The minimum distance for which the edges are checked\n" "@param other The other edge collection against which to check\n" @@ -1186,6 +1186,8 @@ Class decl_Edges (decl_dbShapeCollection, "db", "Edges", "It is sufficient if the projection of one edge on the other matches the specified condition. " "The projected length must be larger or equal to \"min_projection\" and less than \"max_projection\". " "If you don't want to specify one threshold, pass nil to the respective value.\n" + "\n" + "The 'enclosed_check' alias was introduced in version 0.27.5.\n" ) + method_ext ("enclosing_check", &enclosing2, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::Euclidian, "Euclidian"), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max"), "@brief Performs an enclosing check with options\n" diff --git a/src/db/db/gsiDeclDbRegion.cc b/src/db/db/gsiDeclDbRegion.cc index f7e560d39..621235460 100644 --- a/src/db/db/gsiDeclDbRegion.cc +++ b/src/db/db/gsiDeclDbRegion.cc @@ -2591,7 +2591,7 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "\n" "The 'shielded', 'negative', 'not_opposite' and 'rect_sides' options have been introduced in version 0.27." ) + - method_ext ("inside_check", &inside2, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::metrics_type::Euclidian, "Euclidian"), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max"), gsi::arg ("shielded", true), gsi::arg ("opposite_filter", db::NoOppositeFilter, "NoOppositeFilter"), gsi::arg ("rect_filter", db::NoRectFilter, "NoRectFilter"), gsi::arg ("negative", false), + method_ext ("inside_check|enclosed_check", &inside2, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::metrics_type::Euclidian, "Euclidian"), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max"), gsi::arg ("shielded", true), gsi::arg ("opposite_filter", db::NoOppositeFilter, "NoOppositeFilter"), gsi::arg ("rect_filter", db::NoRectFilter, "NoRectFilter"), gsi::arg ("negative", false), "@brief Performs an inside check with options\n" "@param d The minimum distance for which the polygons are checked\n" "@param other The other region against which to check\n" @@ -2639,6 +2639,7 @@ Class decl_Region (decl_dbShapeCollection, "db", "Region", "\n" "The 'shielded', 'negative', 'not_opposite' and 'rect_sides' options have been introduced in version 0.27. " "The interpretation of the 'negative' flag has been restriced to first-layout only output in 0.27.1.\n" + "The 'enclosed_check' alias was introduced in version 0.27.5.\n" ) + method_ext ("overlap_check", &overlap2, gsi::arg ("other"), gsi::arg ("d"), gsi::arg ("whole_edges", false), gsi::arg ("metrics", db::metrics_type::Euclidian, "Euclidian"), gsi::arg ("ignore_angle", tl::Variant (), "default"), gsi::arg ("min_projection", tl::Variant (), "0"), gsi::arg ("max_projection", tl::Variant (), "max"), gsi::arg ("shielded", true), gsi::arg ("opposite_filter", db::NoOppositeFilter, "NoOppositeFilter"), gsi::arg ("rect_filter", db::NoRectFilter, "NoRectFilter"), gsi::arg ("negative", false), "@brief Performs an overlap check with options\n" diff --git a/src/drc/drc/built-in-macros/_drc_complex_ops.rb b/src/drc/drc/built-in-macros/_drc_complex_ops.rb index e0d2ea017..48b534a37 100644 --- a/src/drc/drc/built-in-macros/_drc_complex_ops.rb +++ b/src/drc/drc/built-in-macros/_drc_complex_ops.rb @@ -1888,7 +1888,7 @@ class DRCOpNodeCheck < DRCOpNodeWithCompare factory = { :width => :new_width_check, :space => :new_space_check, :notch => :new_notch_check, :separation => :new_separation_check, :isolated => :new_isolated_check, :overlap => :new_overlap_check, - :enclosing => :new_enclosing_check }[self.check] + :enclosing => :new_enclosing_check, :enclosed => :new_enclosed_check }[self.check] oargs = [] if self.other diff --git a/src/drc/drc/built-in-macros/_drc_cop_integration.rb b/src/drc/drc/built-in-macros/_drc_cop_integration.rb index 58b5518a4..e299350f7 100644 --- a/src/drc/drc/built-in-macros/_drc_cop_integration.rb +++ b/src/drc/drc/built-in-macros/_drc_cop_integration.rb @@ -1042,6 +1042,84 @@ CODE # actual edges from the first input (see \separation for an example). # + # %DRC% + # @name enclosed + # @brief Performs an enclosing check (other enclosing layer) + # @synopsis enclosed(other [, options ]) (in conditions) + # @synopsis enclosed(layer, other [, options ]) + # + # This check verifies if the polygons of the input layer are enclosed by shapes + # of the other input layer by a certain distance. + # It has manifold options. See \Layer#width for the basic options such + # as metrics, projection and angle constraints etc. This check also features + # opposite and rectangle filtering. See \Layer#separation for details about opposite and + # rectangle error filtering. + # + # This function is essentially the reverse of \enclosing. In case of + # "enclosed", the other layer must be bigger than the primary layer. + # + # @h3 Classic mode @/h3 + # + # This function can be used in classic mode with a layer argument. In this case it + # is equivalent to "layer.enclosed" (see \Layer#enclosed). + # + # @code + # # classic "enclosed" check for < 0.2 um + # in = layer(1, 0) + # other = layer(2, 0) + # errors = enclosed(in, other, 0.2.um) + # @/code + # + # @h3 Universal DRC @/h3 + # + # The version without a first layer is intended for use within \DRC# expressions + # together with the "universal DRC" method \Layer#drc. In this case, this function needs to be + # put into a condition to specify the check constraints. The other options + # of \Layer#enclosed (e.g. metrics, projection constraints, angle limits etc.) + # apply to this version too: + # + # @code + # # universal DRC "enclosed" check for < 0.2 um + # in = layer(1, 0) + # other = layer(2, 0) + # errors = in.drc(enclosed(other) < 0.2.um) + # @/code + # + # The conditions may involve an upper and lower limit. The following examples + # illustrate the use of this function with conditions: + # + # @code + # out = in.drc(enclosed(other) < 0.2.um) + # out = in.drc(enclosed(other) <= 0.2.um) + # out = in.drc(enclosed(other) > 0.2.um) + # out = in.drc(enclosed(other) >= 0.2.um) + # out = in.drc(enclosed(other) == 0.2.um) + # out = in.drc(enclosed(other) != 0.2.um) + # out = in.drc(0.1.um <= enclosed(other) < 0.2.um) + # @/code + # + # The result of the enclosed check are edges or edge pairs forming the markers. + # These markers indicate the presence of the specified condition. + # + # With a lower and upper limit, the results are edges marking the positions on the + # primary shape where the condition is met. + # With a lower limit alone, the results are edge pairs which are formed by two identical, but opposite edges attached to + # the primary shape. Without an upper limit only, the first edge of the marker is attached to the + # primary shape while the second edge is attached to the shape of the "other" layer. + # + # @table + # @tr + # @td @img(/images/drc_encd1u.png) @/td + # @td @img(/images/drc_encd2u.png) @/td + # @/tr + # @/table + # + # When "larger than" constraints are used, this function will produce the edges from the + # first layer only. The result will still be edge pairs for consistency, but each edge pair holds one edge from + # the original polygon plus a reverse copy of that edge in the second member. Use "first_edges" to extract the + # actual edges from the first input (see \separation for an example). + # + # %DRC% # @name separation # @brief Performs a separation check @@ -1367,6 +1445,7 @@ CODE %w( enclosing + enclosed isolated notch overlap diff --git a/src/drc/drc/built-in-macros/_drc_engine.rb b/src/drc/drc/built-in-macros/_drc_engine.rb index f5fc0e9cf..3600355ca 100644 --- a/src/drc/drc/built-in-macros/_drc_engine.rb +++ b/src/drc/drc/built-in-macros/_drc_engine.rb @@ -1751,6 +1751,7 @@ CODE %w( enc enclosing + enclosed overlap sep separation diff --git a/src/drc/drc/built-in-macros/_drc_layer.rb b/src/drc/drc/built-in-macros/_drc_layer.rb index 182886121..2cb31656a 100644 --- a/src/drc/drc/built-in-macros/_drc_layer.rb +++ b/src/drc/drc/built-in-macros/_drc_layer.rb @@ -3756,7 +3756,7 @@ CODE # %DRC% # @name enclosing - # @brief An enclosing check + # @brief An enclosing check (layer enclosing other_layer) # @synopsis layer.enclosing(other_layer, value [, options]) # @synopsis layer.enc(other_layer, value [, options]) # @@ -3764,8 +3764,8 @@ CODE # the \DRC framework. These variants have more options and are more intuitive to use. # See \global#enclosing for more details. # - # This method checks whether layer encloses (is bigger than) other_layer by the - # given dimension. Locations, where this is not the case will be reported in form + # This method checks whether layer encloses (is bigger than) other_layer by not less than the + # given distance value. Locations, where the distance is less will be reported in form # of edge pair error markers. # Locations, where both edges coincide will be reported as errors as well. Formally # such locations form an enclosure with a distance of 0. Locations, where other_layer @@ -3794,13 +3794,48 @@ CODE # @/tr # @/table - %w(width space overlap enclosing separation isolated notch).each do |f| + # %DRC% + # @name enclosed + # @brief An enclosing check (other_layer enclosing layer) + # @synopsis layer.enclosed(other_layer, value [, options]) + # + # @b Note: @/b "enclosed" is available as operators for the "universal DRC" function \drc within + # the \DRC framework. These variants have more options and are more intuitive to use. + # See \global#enclosed for more details. + # + # This method checks whether layer is enclosed by (is inside of) other_layer by not less than the + # given distance value. Locations, where the distance is less will be reported in form + # of edge pair error markers. + # Locations, where both edges coincide will be reported as errors as well. Formally + # such locations form an enclosure with a distance of 0. Locations, where other_layer + # is inside layer will not be reported as errors. Such regions can be detected + # by \inside or a boolean "not" operation. + # + # The options are the same as for \separation. + # + # This method is available for edge and polygon layers. + # + # As for the other DRC methods, merged semantics applies. + # + # Distance values can be given as floating-point values (in micron) or integer values (in + # database units). To explicitly specify the unit, use the unit denominators. + # + # The following images show the effect of two enclosed checks (red: input1, blue: input2): + # + # @table + # @tr + # @td @img(/images/drc_encd1.png) @/td + # @td @img(/images/drc_encd2.png) @/td + # @/tr + # @/table + + %w(width space overlap enclosing enclosed separation isolated notch).each do |f| eval <<"CODE" def #{f}(*args) @engine._context("#{f}") do - if :#{f} == :width || :#{f} == :space || :#{f} == :overlap || :#{f} == :enclosing || :#{f} == :separation + if :#{f} == :width || :#{f} == :space || :#{f} == :overlap || :#{f} == :enclosed || :#{f} == :enclosing || :#{f} == :separation requires_edges_or_region else requires_region diff --git a/src/lay/lay/doc/about/drc_ref_global.xml b/src/lay/lay/doc/about/drc_ref_global.xml index 96c622861..34d3d7f07 100644 --- a/src/lay/lay/doc/about/drc_ref_global.xml +++ b/src/lay/lay/doc/about/drc_ref_global.xml @@ -536,6 +536,85 @@ See Source#edges for a description

"enc" is the short form for enclosing.

+

"enclosed" - Performs an enclosing check (other enclosing layer)

+ +

Usage:

+
    +
  • enclosed(other [, options ]) (in conditions)
  • +
  • enclosed(layer, other [, options ])
  • +
+

+This check verifies if the polygons of the input layer are enclosed by shapes +of the other input layer by a certain distance. +It has manifold options. See Layer#width for the basic options such +as metrics, projection and angle constraints etc. This check also features +opposite and rectangle filtering. See Layer#separation for details about opposite and +rectangle error filtering. +

+This function is essentially the reverse of enclosing. In case of +"enclosed", the other layer must be bigger than the primary layer. +

+

Classic mode

+

+This function can be used in classic mode with a layer argument. In this case it +is equivalent to "layer.enclosed" (see Layer#enclosed). +

+

+# classic "enclosed" check for < 0.2 um
+in = layer(1, 0)
+other = layer(2, 0)
+errors = enclosed(in, other, 0.2.um)
+
+

+

Universal DRC

+

+The version without a first layer is intended for use within DRC expressions +together with the "universal DRC" method Layer#drc. In this case, this function needs to be +put into a condition to specify the check constraints. The other options +of Layer#enclosed (e.g. metrics, projection constraints, angle limits etc.) +apply to this version too: +

+

+# universal DRC "enclosed" check for < 0.2 um
+in = layer(1, 0)
+other = layer(2, 0)
+errors = in.drc(enclosed(other) < 0.2.um)
+
+

+The conditions may involve an upper and lower limit. The following examples +illustrate the use of this function with conditions: +

+

+out = in.drc(enclosed(other) < 0.2.um)
+out = in.drc(enclosed(other) <= 0.2.um)
+out = in.drc(enclosed(other) > 0.2.um)
+out = in.drc(enclosed(other) >= 0.2.um)
+out = in.drc(enclosed(other) == 0.2.um)
+out = in.drc(enclosed(other) != 0.2.um)
+out = in.drc(0.1.um <= enclosed(other) < 0.2.um)
+
+

+The result of the enclosed check are edges or edge pairs forming the markers. +These markers indicate the presence of the specified condition. +

+With a lower and upper limit, the results are edges marking the positions on the +primary shape where the condition is met. +With a lower limit alone, the results are edge pairs which are formed by two identical, but opposite edges attached to +the primary shape. Without an upper limit only, the first edge of the marker is attached to the +primary shape while the second edge is attached to the shape of the "other" layer. +

+ + + + + +
+

+When "larger than" constraints are used, this function will produce the edges from the +first layer only. The result will still be edge pairs for consistency, but each edge pair holds one edge from +the original polygon plus a reverse copy of that edge in the second member. Use "first_edges" to extract the +actual edges from the first input (see separation for an example). +

"enclosing" - Performs an enclosing check

Usage:

diff --git a/src/lay/lay/doc/about/drc_ref_layer.xml b/src/lay/lay/doc/about/drc_ref_layer.xml index b86cc8e19..56dfbe4c8 100644 --- a/src/lay/lay/doc/about/drc_ref_layer.xml +++ b/src/lay/lay/doc/about/drc_ref_layer.xml @@ -778,7 +778,44 @@ individual ones unless raw mode is chosen.

See enclosing for a description of that method

-

"enclosing" - An enclosing check

+

"enclosed" - An enclosing check (other_layer enclosing layer)

+ +

Usage:

+
    +
  • layer.enclosed(other_layer, value [, options])
  • +
+

+Note: "enclosed" is available as operators for the "universal DRC" function drc within +the DRC framework. These variants have more options and are more intuitive to use. +See enclosed for more details. +

+This method checks whether layer is enclosed by (is inside of) other_layer by not less than the +given distance value. Locations, where the distance is less will be reported in form +of edge pair error markers. +Locations, where both edges coincide will be reported as errors as well. Formally +such locations form an enclosure with a distance of 0. Locations, where other_layer +is inside layer will not be reported as errors. Such regions can be detected +by inside or a boolean "not" operation. +

+The options are the same as for separation. +

+This method is available for edge and polygon layers. +

+As for the other DRC methods, merged semantics applies. +

+Distance values can be given as floating-point values (in micron) or integer values (in +database units). To explicitly specify the unit, use the unit denominators. +

+The following images show the effect of two enclosed checks (red: input1, blue: input2): +

+ + + + + +
+

+

"enclosing" - An enclosing check (layer enclosing other_layer)

Usage:

    @@ -790,8 +827,8 @@ See enclosing for a description of that method the DRC framework. These variants have more options and are more intuitive to use. See enclosing for more details.

    -This method checks whether layer encloses (is bigger than) other_layer by the -given dimension. Locations, where this is not the case will be reported in form +This method checks whether layer encloses (is bigger than) other_layer by not less than the +given distance value. Locations, where the distance is less will be reported in form of edge pair error markers. Locations, where both edges coincide will be reported as errors as well. Formally such locations form an enclosure with a distance of 0. Locations, where other_layer diff --git a/src/lay/lay/doc/images/drc_encd1.png b/src/lay/lay/doc/images/drc_encd1.png new file mode 100644 index 0000000000000000000000000000000000000000..4be32165a2f4cc8299ea5352de50f6746db13a8c GIT binary patch literal 9333 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�~%V4wW<$aTjj^Y9T0dFr*K$;4_E6$jtS60()n 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 literal 0 HcmV?d00001 diff --git a/src/lay/lay/doc/images/drc_encd2.png b/src/lay/lay/doc/images/drc_encd2.png new file mode 100644 index 0000000000000000000000000000000000000000..88e7ad63e41d317bd545161da5b457c9eee85af3 GIT binary patch literal 9332 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 literal 0 HcmV?d00001 diff --git a/src/lay/lay/doc/images/drc_encd2u.png b/src/lay/lay/doc/images/drc_encd2u.png new file mode 100644 index 0000000000000000000000000000000000000000..ec3615fca76c978e56e7e337dfed4f9f11d38031 GIT binary patch literal 9503 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/images/drc_enc2.png doc/images/drc_enc1u.png doc/images/drc_enc2u.png + doc/images/drc_encd1.png + doc/images/drc_encd2.png + doc/images/drc_encd1u.png + doc/images/drc_encd2u.png doc/images/drc_overlap1.png doc/images/drc_overlap2.png doc/images/drc_overlap1u.png