svghmi/geometry.ysl2
author Edouard Tisserant
Wed, 13 Jan 2021 10:28:09 +0100
branchsvghmi
changeset 3109 6c39d718e8cb
parent 2940 034b6ce4f885
child 3165 2db69e2c5673
permissions -rw-r--r--
Removed harmful assert in ProcessLogger.

ProcessLogger was having an assert in constructor when missing logger, leading to systematic exception when testing options accepted by compiler. This exception was silenced in ProjectController, and then MatIEC was always called without options.
// geometry.ysl2
//
// Geometry (bounding box intersection) definitions

// This retrieves geometry obtained through "inkscape -S"
// already parsed by python and presented as a list of
// <bbox x="0" y="0" w="42" h="42">
const "geometry", "ns:GetSVGGeometry()";

// Debug data
emit "debug:geometry" {
    | ID, x, y, w, h
    foreach "$geometry"
        |  «@Id» «@x» «@y» «@w» «@h»
}

// Rates 1D intersection of 2 segments A and B
// described respectively with a0,a1 and b0,b1
def "func:intersect_1d" {
    // it is assumed that a1 > a0 and b1 > b0
    param "a0";
    param "a1";
    param "b0";
    param "b1";

    const "d0", "$a0 >= $b0";
    const "d1", "$a1 >= $b1";
    choose {
        when "not($d0) and $d1"
            // b contained in a
            //   a0<b0 b1<a1
            // a +--------+
            // b    +--+
            result "3";
        when "$d0 and not($d1)"
            // a contained in b
            //   b0<a0 a1<b1
            // a    +--+
            // b +--------+
            result "2";
        when "$d0 and $d1 and $a0 < $b1"
            // a and b are overlapped 
            //   b0<a0<b1<a1
            // a    +-----+
            // b +-----+
            result "1";
        when "not($d0) and not($d1) and $b0 < $a1"
            // a and b are overlapped
            //   a0<b0<a1<b1
            // a +-----+
            // b    +-----+
            result "1";
            // since orientation doesn't matter,
            // rated same as previous symetrical overlapping
        otherwise
            result "0"; /* no intersection*/
    }
}


// Rates intersection A and B areas described with x,y,w and h 
// attributes passed as $a and $b parameters.
// 
// returns :
// 0 - no intersection
//            .-----.
//    .-----. |    b|
//    |     | |     |
//    |     | '-----'
//    |a    |
//    '-----'
//
// 1 - overlapping
//        .-----.
//    .---|--. b|
//    |   |  |  |
//    |   '-----'
//    |a     |
//    '------'
//
// 2 - overlapping
//        .-----.
//        |  a  |
//    .---|-----|---.
//    |   '-----'   |
//    | b           |
//    '-------------'
//
// 3 - overlapping
//        .-----.
//        |  b  |
//    .---|-----|---.
//    |   '-----'   |
//    | a           |
//    '-------------'
//
// 4 - a contained in b
//    .-------------.
//    |   .-----.   |
//    |   |  a  |   |
//    |b  '-----'   |
//    '-------------'
//
// 6 - overlapping
//        .----.
//        |   b|
//    .---|----|---.
//    |a  |    |   |
//    '---|----|---'
//        '----'
//
// 9 - b contained in a
//    .-------------.
//    |   .-----.   |
//    |   |  b  |   |
//    |a  '-----'   |
//    '-------------'
//
def "func:intersect" {
    param "a";
    param "b";

    const "x_intersect", "func:intersect_1d($a/@x, $a/@x+$a/@w, $b/@x, $b/@x+$b/@w)";

    choose{
        when "$x_intersect != 0"{
            const "y_intersect", "func:intersect_1d($a/@y, $a/@y+$a/@h, $b/@y, $b/@y+$b/@h)";
            result "$x_intersect * $y_intersect";
        }
        otherwise result "0";
    }
}

// return overlapping geometry for a given element
// all intersercting element are returned
// except groups, that must be contained to be counted in
def "func:overlapping_geometry" {
    param "elt";
    const "groups", "/svg:svg | //svg:g";
    const "g", "$geometry[@Id = $elt/@id]"; 
    const "candidates", "$geometry[@Id != $elt/@id]";
    result """$candidates[(@Id = $groups/@id and (func:intersect($g, .) = 9)) or 
                          (not(@Id = $groups/@id) and (func:intersect($g, .) > 0 ))]""";
}