<?xml version="1.0" encoding="utf-8"?>
<!-- ArchiFrame material types and other settings for single block/plank/rafter etc -->
<archiframe>
  <settings>
    <misc>
      <!-- Manufacturer name is used inside the program to guide some tailorings -->
      <manufacturer name=""></manufacturer>

      <print layoutname="Elem drawing &lt;elemid&gt;"
             masterland="A4 Wall drawing" masterlandxsize="297" masterlandysize="210"
             masterport="A4 Wall drawing portrait" masterportxsize="210" masterportysize="297" frame="1">
        <!-- To leave margin for the stamp, units are mm -->
        <empty_custom name="Master_layout_name" left="10" top="10" right="87" bottom="10"></empty_custom>
      </print>

      <!-- FOLLOWING TO HAVE A3 LANDSCAPE ALWAYS WITHOUT FRAME -->
      <!--print layoutname="Elem drawing &lt;elemid&gt;" frame="0"
             masterland="A3 Wall drawing landscape" masterlandxsize="420" masterlandysize="297"
             masterport="A3 Wall drawing landscape" masterportxsize="420" masterportysize="297">
      </print-->

      <!-- FOLLOWING TO HAVE A3 -->
      <!--print layoutname="Elem drawing &lt;elemid&gt;"
             masterland="A3 Wall drawing" masterlandxsize="420" masterlandysize="297"
             masterport="A3 Wall drawing portrait" masterportxsize="297" masterportysize="420">
      </print-->

      <printframe dimtitle="Frame">
        <elemparam name="pen">1</elemparam>
        <objparam name="framepen">1</objparam>
      </printframe>

      <!-- Settings for dimension drawings, layer here is just a default for first time user. Selection is saved to user-specific settings. -->
      <projections layer="" maxwidth="80.0" margboxes="3.0" margleft="1.0" margtop="2.0" margright="1.0" margbot="1.0" margproj="0.7">
        <!-- Settings in <projbase> are set for every element created for dim drawings and element projections -->
        <projbase>
          <!--layer>Name, auto created</layer-->
          <!--elemparam name="pen">1</elemparam-->
        </projbase>

        <projplank>
          <elemparam name="linetype">1</elemparam>
          <objparam name="#useobjlinetype">0</objparam>
          <objparam name="iFillFrom3D">0</objparam>
          <objparam name="iFillPen"></objparam>
          <objparam name="iFill">0</objparam>
        </projplank>
        <dimsettings>
          <drill midout="1"></drill>
        </dimsettings>
        <!-- Projection side text bottom mid aligned -->
        <text_title yoff="0.10">
          <settings>
            <elemparam name="fontname">Arial</elemparam>
            <elemparam name="fontsize">1.2</elemparam>
            <elemparam name="fontstyle"> </elemparam>
            <elemparam name="pen">1</elemparam>
          </settings>
          <side1>
            <text>TOP</text>
          </side1>
          <side2>
            <text>FRONT</text>
          </side2>
          <side3>
            <text>BOTTOM</text>
          </side3>
          <side4>
            <text>BACK</text>
          </side4>
        </text_title>

        <!-- Main dimension line having total length -->
        <dim_main yoff="1.0">
          <!-- Settings for main dimension line -->
          <!-- linear or cumulative -->
          <elemparam name="dimensiontype" >linear</elemparam>
          <elemparam name="fontname">Arial</elemparam>
          <elemparam name="fontsize">1.5</elemparam>
          <!-- Style, use comma to separate: bold,italic,underline -->
          <elemparam name="fontstyle"></elemparam>
        </dim_main>
        <dim_mcmain yoff="0.5">
          <!-- Settings for main machinings dimension line -->
          <!-- linear or cumulative -->
          <elemparam name="dimensiontype" >linear</elemparam>
          <elemparam name="fontname">Arial</elemparam>
          <elemparam name="fontsize">1.5</elemparam>
          <elemparam name="fontstyle"></elemparam>
        </dim_mcmain>
        <dim_angled yoff="0.75">
          <!-- Settings for main dim line for angled endings -->
          <!-- linear or cumulative -->
          <elemparam name="dimensiontype" >linear</elemparam>
          <elemparam name="fontname">Arial</elemparam>
          <elemparam name="fontsize">1.5</elemparam>
          <elemparam name="fontstyle"></elemparam>
        </dim_angled>
        <dim_mcdet yoff="-0.5">
          <elemparam name="dimensiontype" >linear</elemparam>
          <elemparam name="fontname">Arial</elemparam>
          <elemparam name="fontsize">1.5</elemparam>
          <elemparam name="fontstyle"></elemparam>
        </dim_mcdet>
        <dim_mcdetangle yoff="-0.5">
          <elemparam name="fontname">Arial</elemparam>
          <elemparam name="fontsize">1.0</elemparam>
          <elemparam name="fontstyle"></elemparam>
          <elemparam name="radius">0.4</elemparam>
          <elemparam name="markersize">0.7</elemparam>
          <!--line>
            <elemparam name="pen">1</elemparam>
            <elemparam name="linetype">1</elemparam>
          </line-->
        </dim_mcdetangle>
        <text_mcdet yoff="-0.5" diapre="Ø ">
          <elemparam name="fontname">Arial</elemparam>
          <elemparam name="fontsize">1.5</elemparam>
          <elemparam name="fontstyle"></elemparam>
          <elemparam name="pen">1</elemparam>
        </text_mcdet>

        <text_summary height="1.4" minwidth="3.0">
          <settings>
            <elemparam name="fontname">Arial</elemparam>
            <elemparam name="fontsize">1.5</elemparam>
            <elemparam name="fontstyle"></elemparam>
            <elemparam name="pen">1</elemparam>
          </settings>
          <text lang="fin">Mat: [mat]\nQuality: [quality]\nName: [usage]\nSimilar: [count]\nIDs: [idlist]</text>
        </text_summary>
      </projections>

      <!-- List for available styles of dimension drawings (04/12/2020) -->
      <dimdrawings>
        <!--
        DIMDRAWING contains all data for one specific style definition.
        :param id:  This links the placed dimension drawings and these rules together
        :param name: Default name, use GetAttributeLang()
        :param name_xxx: Localized one 
        -->
        <dimdrawing id="dim10_all2single_morecol" name="All parts to single frame" name_fin="Kaikki osat yhteen kehykseen" name_pol="Wszystkie elementy w jednej ramie">

          <!--
          GENERAL contains the settings for a group of projections + titles + dimensions + textblocks.
          :param groupminwidth: gives minimum value in meter for the width of the whole group of layouts
          :param groupminheight: gives minimum value in meter for the height of the whole group of layouts
          :param groupmaxwidth: gives maximum values in meter for the width of the whole group of layouts
          :param groupmaxheight: gives maximum values in meter for the height of the whole group of layouts
          :param boxmargins: margins around each layout (left, right, top, bottom)
          -->
          <general groupminwidth="4.0" groupminheight="3.0" groupmaxwidth="80.0" groupmaxheight="50.0" boxmargins="0.9,0.9,0.9,0.9">
            <!-- it may contain default settings for all children, and this could be overwritten later -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.1</elemparam>
              <elemparam name="fontsizemodel">55</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="pen">1</elemparam>
            </settings>
          </general>

          <!--
          DIMENSIONLINESETTINGS contains the default settings for all dimension lines, and then individual parameters and settings for each dimension line, separately.
          -->
          <dimensionlinesettings>
            <!-- the following DRILL block with midout parameter is optional, you can overwrite the default setting (midout=1), if the value is 0, then the drillings with center point outside of the object will not have dim lines. -->
            <drill midout="0"></drill>
            <!-- the following REINFORCEMENT block with is optional, you can specify which direction of dimlines has to be shown (the default is to show both horizontal and vertical ones) -->
            <reinforcement horizontal="1" vertical="1"></reinforcement>
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be the base settings for dimension line definitions -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.5</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="markersize">2</elemparam>
              <elemparam name="pen">4</elemparam>
            </settings>
            <!--
                Each DIMLINE tag defines the parameters and setting of a certain type of dimension line.
                :param side: defines positioning, according to the projection (can be top, bottom, left, right, both)
                :param gap: defines distance from the last element on that side, in meter (you can position dimlines relative to each other)
                :param offset: defines distance from the projection, in meter (you can position dimlines in absolute positions, it will overwrite GAP parameter)
                :param showalways: 0 means that this dimline can be skipped (if it contains no new data), 1 means it must be shown
                Their SETTINGS block is optional. -->
            <dimline type="main_horizontal" side="top" gap="0.3" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
                <elemparam name="fontsize">1.7</elemparam>
              </settings>
            </dimline>
            <dimline type="main_vertical" side="left" gap="0.25">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_horizontal" side="top" gap="0.2" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_vertical" side="both" gap="0.3" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_detail" side="bottom" gap="0.2" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_detangle" side="bottom" gap="0.5" showalways="0">
              <settings>
                <elemparam name="radius">0.4</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_dettext" side="bottom" gap="0.2" showalways="0">
              <settings diapre="Ø ">
                <elemparam name="fontname">Arial</elemparam>
                <elemparam name="fontstyle"></elemparam>
                <elemparam name="pen">1</elemparam>
              </settings>
            </dimline>
          </dimensionlinesettings>

          <!--
          PROJECTION contains the settings for one specific element projection. All sides must have distinct definition, so many <projection> tag can appear in one style.
          :param id: unique identifier for using in the layout and for alignment anchor (optional)
          :param type: this tells which side is projected. Can be "top", "bottom", "front", "back", "beg", "end", "real_bottom", "real_back".
          :param margins: margins in a row (left, right, top, bottom)
          :param showalways: 0 means that this projection can be skipped (if it contains no new data in the dimlines), 1 means it must be shown (it also applies to all of its dimlines)
          -->
          <projection id="frontproj" type="front" margins="0.2,0.2,0.2,0.2" showalways="0">
            <!--
            TITLE contains the settings for the title of this projection (this tag is optional).
            :param value: the text to write out for this title
            :param side: on which side of the projection should it be placed
            :param align: -1 / 0 / 1 for left, center, right OR top, middle, bottom (depending on the side parameter)
            :param offset: offset from projection (if x or y axis, that depends on the side parameter)
            -->
            <title value="FRONT" side="bottom" align="0" offset="0.10">
              <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this title -->
              <settings>
                <elemparam name="pen">16</elemparam>
              </settings>
            </title>
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this projection (view of an element) -->
            <settings>
              <elemparam name="linetype">1</elemparam>
              <elemparam name="pen">14</elemparam>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="topproj" type="top" margins="0.1,0.1,0.1,0.1" showalways="0">
            <title value="TOP" side="top" align="0" offset="0.10">
              <settings>
                <elemparam name="pen">15</elemparam>
              </settings>
            </title>
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="begproj" type="beg" margins="0.1,0.1,0.1,0.1" showalways="0">
            <title value="BEGIN" side="left" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="endproj" type="end" margins="0.1,0.1,0.1,0.1" showalways="0">
            <title value="END" side="right" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="backproj" type="back" margins="0.1,0.1,0.1,0.1" showalways="0">
            <title value="BACK" side="left" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="bottomproj" type="bottom" margins="0.1,0.1,0.1,0.1" showalways="0">
            <title value="BOTTOM" side="bottom" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <!--
          TEXTBLOCK contains the settings and content for a block of text.
          :param id: unique identifier for using in the layout and for alignment anchor (optional)
          :param margins: margins in a row (left, right, top, bottom)
          :param minwidth: minimum width in meter (optional)
          :param maxwidth: maximum width in meter (optional)
          :param content: parametrized value to print out (word substitution is applied: [matname], [mat], [quality], [usage] will be replaced with object parameter value, and [count] will be replaced by the number of similar objects)
          :param content_LANG: similar to "content", but translated (use word substitution as in content)
          -->

          <textblock id="text1" margins="0.1,0.1,0.1,0.1" minwidth="2.0" maxwidth="10.0" content="Mat: [matname]\nQuality: [quality]\nUsage: [usage]\nPcs: [count]\nIDs: [idlist]" content_fin="Mat: [mat]\nLaatu: [quality]\nKäyttö: [usage]\nKpl: [count]\nIDt: [idlist]">
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this textblock -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.5</elemparam>
              <elemparam name="fontsizemodel">59</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="pen">6</elemparam>
            </settings>
          </textblock>

          <!--
          FRAME is optional for the dim drawings, the <frame> tag can be missing from the style definition. It contains the settings for the frame drawn around the projections, dimlines, texts, etc.
          :param foreach: 1=put all different IDs to separate frames (the old way), 0=put one frame around the whole group of plank drawings
          :param horizontalgap: if framed dimdrawings are beside each other, this distance will be between the frames
          :param verticalgap: if framed dimdrawings are on the top of each other, this distance will be between the frames
          :param title: name parameter in the frame object will be filled with this value (#id# will be replaced with ID of a single plank/board, #elemid# will be replaced with the ID of the whole element)
           -->
          <frame foreach="0" horizontalgap="0.2" verticalgap="0.1" title="Frame #elemid#">
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to the frame -->
            <settings>
              <objparam name="framepen">1</objparam>
            </settings>
          </frame>

          <!--
          TABLELAYOUT is optional for the dim drawings, all projections and texts will be drawn on the top of each other, if the <tablelayout> tag is missing from the style definition.
          It has only one parameter, "main", which contains an id of a cell. That cell will be in the central, all other elem will relate to the content of that cell.
          It contains some <row> tags.
          Each <row> tag contains some <cell> tag.
          All cells in one row will be drawn beside each other, while rows will be drawn on the top of each other.
          CELL tags have parameters to define the content and alignment within.
          :param content: can be empty string or an ID of a text or projection element
          :param aligntype: can be set to "full" or "main". Full means the whole content will be taken into calculation and the whole size of neighbouring cells will be matched with that. Main means the master part of the content (e.g. projected element drawing without titles and dimension lines) will be aligned to the master parts to the neighbouring cells.
          :param alignto: can be empty or an ID of a projection element. If aligntype is main, here you can set the matching cell, instead of the default neighbour.
          :param halign: horizontal alignment, can be -1 = left, 0 = center or 1 = right.
          :param valign: vertical alignment, can be -1 = top, 0 = middle or 1 = bottom.
          :param colspan: can be set to a positive integer. It gives the number of cells merged together in this row, to form this bigger single cell.
          :param rowspan: can be set to a positive integer. It gives the number of cells merged together, stepping downward, as in a column. The following rows should skip those cell definitions, which are already merged with rowspan.
          -->
          <tablelayout main="central">
            <row>
              <cell content="text1" colspan="3" halign="-1" valign="-1" aligntype="full" />
            </row>
            <row>
              <cell content="" />
              <cell content="topproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="begproj" halign="1" valign="-1" aligntype="main" alignto="central" />
              <cell id="central" content="frontproj" halign="0" valign="0" />
              <cell content="endproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="" />
              <cell content="bottomproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="" />
              <cell content="backproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
          </tablelayout>
        </dimdrawing>
        <dimdrawing id="dim10_all2single_onecol" name="All parts to single frame single column" name_fin="kaikki osat yhteen kehykseen ja yhteen sarakkeeseen" name_pol="Wszystkie elementy w jednej ramie i jednej kolumnie">

          <!--
          GENERAL contains the settings for a group of projections + titles + dimensions + textblocks.
          :param groupminwidth: gives minimum value in meter for the width of the whole group of layouts
          :param groupminheight: gives minimum value in meter for the height of the whole group of layouts
          :param groupmaxwidth: gives maximum values in meter for the width of the whole group of layouts
          :param groupmaxheight: gives maximum values in meter for the height of the whole group of layouts
          :param boxmargins: margins around each layout (left, right, top, bottom)
          -->
          <general groupminwidth="4.0" groupminheight="3.0" groupmaxwidth="5.0" groupmaxheight="80.0" boxmargins="0.9,0.9,0.9,0.9">
            <!-- it may contain default settings for all children, and this could be overwritten later -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.1</elemparam>
              <elemparam name="fontsizemodel">55</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="pen">1</elemparam>
            </settings>
          </general>

          <!--
          DIMENSIONLINESETTINGS contains the default settings for all dimension lines, and then individual parameters and settings for each dimension line, separately.
          -->
          <dimensionlinesettings>
            <!-- the following DRILL block with midout parameter is optional, you can overwrite the default setting (midout=1), if the value is 0, then the drillings with center point outside of the object will not have dim lines. -->
            <drill midout="0"></drill>
            <!-- the following REINFORCEMENT block with is optional, you can specify which direction of dimlines has to be shown (the default is to show both horizontal and vertical ones) -->
            <reinforcement horizontal="1" vertical="1"></reinforcement>
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be the base settings for dimension line definitions -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.5</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="markersize">2</elemparam>
              <elemparam name="pen">4</elemparam>
            </settings>
            <!--
                Each DIMLINE tag defines the parameters and setting of a certain type of dimension line.
                :param side: defines positioning, according to the projection (can be top, bottom, left, right, both)
                :param gap: defines distance from the last element on that side, in meter (you can position dimlines relative to each other)
                :param offset: defines distance from the projection, in meter (you can position dimlines in absolute positions, it will overwrite GAP parameter)
                :param showalways: 0 means that this dimline can be skipped (if it contains no new data), 1 means it must be shown
                Their SETTINGS block is optional. -->
            <dimline type="main_horizontal" side="top" gap="0.3" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
                <elemparam name="fontsize">1.7</elemparam>
              </settings>
            </dimline>
            <dimline type="main_vertical" side="left" gap="0.25">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_horizontal" side="top" gap="0.2" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_vertical" side="both" gap="0.3" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_detail" side="bottom" gap="0.2" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_detangle" side="bottom" gap="0.5" showalways="0">
              <settings>
                <elemparam name="radius">0.4</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_dettext" side="bottom" gap="0.2" showalways="0">
              <settings diapre="Ø ">
                <elemparam name="fontname">Arial</elemparam>
                <elemparam name="fontstyle"></elemparam>
                <elemparam name="pen">1</elemparam>
              </settings>
            </dimline>
          </dimensionlinesettings>

          <!--
          PROJECTION contains the settings for one specific element projection. All sides must have distinct definition, so many <projection> tag can appear in one style.
          :param id: unique identifier for using in the layout and for alignment anchor (optional)
          :param type: this tells which side is projected. Can be "top", "bottom", "front", "back", "beg", "end", "real_bottom", "real_back".
          :param margins: margins in a row (left, right, top, bottom)
          :param showalways: 0 means that this projection can be skipped (if it contains no new data in the dimlines), 1 means it must be shown (it also applies to all of its dimlines)
          -->
          <projection id="frontproj" type="front" margins="0.2,0.2,0.2,0.2" showalways="0">
            <!--
            TITLE contains the settings for the title of this projection (this tag is optional).
            :param value: the text to write out for this title
            :param side: on which side of the projection should it be placed
            :param align: -1 / 0 / 1 for left, center, right OR top, middle, bottom (depending on the side parameter)
            :param offset: offset from projection (if x or y axis, that depends on the side parameter)
            -->
            <title value="FRONT" side="bottom" align="0" offset="0.10">
              <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this title -->
              <settings>
                <elemparam name="pen">16</elemparam>
              </settings>
            </title>
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this projection (view of an element) -->
            <settings>
              <elemparam name="linetype">1</elemparam>
              <elemparam name="pen">14</elemparam>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="topproj" type="top" margins="0.1,0.1,0.1,0.1" showalways="0">
            <title value="TOP" side="top" align="0" offset="0.10">
              <settings>
                <elemparam name="pen">15</elemparam>
              </settings>
            </title>
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="begproj" type="beg" margins="0.1,0.1,0.1,0.1" showalways="0">
            <title value="BEGIN" side="left" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="endproj" type="end" margins="0.1,0.1,0.1,0.1" showalways="0">
            <title value="END" side="right" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="backproj" type="back" margins="0.1,0.1,0.1,0.1" showalways="0">
            <title value="BACK" side="left" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="bottomproj" type="bottom" margins="0.1,0.1,0.1,0.1" showalways="0">
            <title value="BOTTOM" side="bottom" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <!--
          TEXTBLOCK contains the settings and content for a block of text.
          :param id: unique identifier for using in the layout and for alignment anchor (optional)
          :param margins: margins in a row (left, right, top, bottom)
          :param minwidth: minimum width in meter (optional)
          :param maxwidth: maximum width in meter (optional)
          :param content: parametrized value to print out (word substitution is applied: [matname], [mat], [quality], [usage] will be replaced with object parameter value, and [count] will be replaced by the number of similar objects)
          :param content_LANG: similar to "content", but translated (use word substitution as in content)
          -->

          <textblock id="text1" margins="0.1,0.1,0.1,0.1" minwidth="2.0" maxwidth="10.0" content="Mat: [matname]\nQuality: [quality]\nUsage: [usage]\nPcs: [count]\nIDs: [idlist]" content_fin="Mat: [mat]\nLaatu: [quality]\nKäyttö: [usage]\nKpl: [count]\nIDt: [idlist]">
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this textblock -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.5</elemparam>
              <elemparam name="fontsizemodel">59</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="pen">6</elemparam>
            </settings>
          </textblock>

          <!--
          FRAME is optional for the dim drawings, the <frame> tag can be missing from the style definition. It contains the settings for the frame drawn around the projections, dimlines, texts, etc.
          :param foreach: 1=put all different IDs to separate frames (the old way), 0=put one frame around the whole group of plank drawings
          :param horizontalgap: if framed dimdrawings are beside each other, this distance will be between the frames
          :param verticalgap: if framed dimdrawings are on the top of each other, this distance will be between the frames
          :param title: name parameter in the frame object will be filled with this value (#id# will be replaced with ID of a single plank/board, #elemid# will be replaced with the ID of the whole element)
           -->
          <frame foreach="0" horizontalgap="0.2" verticalgap="0.1" title="Frame #elemid#">
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to the frame -->
            <settings>
              <objparam name="framepen">1</objparam>
            </settings>
          </frame>

          <!--
          TABLELAYOUT is optional for the dim drawings, all projections and texts will be drawn on the top of each other, if the <tablelayout> tag is missing from the style definition.
          It has only one parameter, "main", which contains an id of a cell. That cell will be in the central, all other elem will relate to the content of that cell.
          It contains some <row> tags.
          Each <row> tag contains some <cell> tag.
          All cells in one row will be drawn beside each other, while rows will be drawn on the top of each other.
          CELL tags have parameters to define the content and alignment within.
          :param content: can be empty string or an ID of a text or projection element
          :param aligntype: can be set to "full" or "main". Full means the whole content will be taken into calculation and the whole size of neighbouring cells will be matched with that. Main means the master part of the content (e.g. projected element drawing without titles and dimension lines) will be aligned to the master parts to the neighbouring cells.
          :param alignto: can be empty or an ID of a projection element. If aligntype is main, here you can set the matching cell, instead of the default neighbour.
          :param halign: horizontal alignment, can be -1 = left, 0 = center or 1 = right.
          :param valign: vertical alignment, can be -1 = top, 0 = middle or 1 = bottom.
          :param colspan: can be set to a positive integer. It gives the number of cells merged together in this row, to form this bigger single cell.
          :param rowspan: can be set to a positive integer. It gives the number of cells merged together, stepping downward, as in a column. The following rows should skip those cell definitions, which are already merged with rowspan.
          -->
          <tablelayout main="central">
            <row>
              <cell content="text1" colspan="3" halign="-1" valign="-1" aligntype="full" />
            </row>
            <row>
              <cell content="" />
              <cell content="topproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="begproj" halign="1" valign="-1" aligntype="main" alignto="central" />
              <cell id="central" content="frontproj" halign="0" valign="0" />
              <cell content="endproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="" />
              <cell content="bottomproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="" />
              <cell content="backproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
          </tablelayout>
        </dimdrawing>
        <dimdrawing id="dim10_oneperframe" name="One part per frame" name_fin="Yksi osa kehystä kohti" name_pol="Jeden element na ramę">

          <!--
          GENERAL contains the settings for a group of projections + titles + dimensions + textblocks.
          :param groupminwidth: gives minimum value in meter for the width of the whole group of layouts
          :param groupminheight: gives minimum value in meter for the height of the whole group of layouts
          :param groupmaxwidth: gives maximum values in meter for the width of the whole group of layouts
          :param groupmaxheight: gives maximum values in meter for the height of the whole group of layouts
          :param boxmargins: margins around each layout (left, right, top, bottom)
          -->
          <general groupminwidth="4.0" groupminheight="3.0" groupmaxwidth="80.0" groupmaxheight="50.0" boxmargins="0.9,0.9,0.9,0.9">
            <!-- it may contain default settings for all children, and this could be overwritten later -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.1</elemparam>
              <elemparam name="fontsizemodel">55</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="pen">1</elemparam>
            </settings>
          </general>

          <!--
          DIMENSIONLINESETTINGS contains the default settings for all dimension lines, and then individual parameters and settings for each dimension line, separately.
          -->
          <dimensionlinesettings>
            <!-- the following DRILL block with midout parameter is optional, you can overwrite the default setting (midout=1), if the value is 0, then the drillings with center point outside of the object will not have dim lines. -->
            <drill midout="0"></drill>
            <!-- the following REINFORCEMENT block with is optional, you can specify which direction of dimlines has to be shown (the default is to show both horizontal and vertical ones) -->
            <reinforcement horizontal="1" vertical="1"></reinforcement>
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be the base settings for dimension line definitions -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.5</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="markersize">2</elemparam>
              <elemparam name="pen">4</elemparam>
            </settings>
            <!--
                Each DIMLINE tag defines the parameters and setting of a certain type of dimension line.
                :param side: defines positioning, according to the projection (can be top, bottom, left, right, both)
                :param gap: defines distance from the last element on that side, in meter (you can position dimlines relative to each other)
                :param offset: defines distance from the projection, in meter (you can position dimlines in absolute positions, it will overwrite GAP parameter)
                :param showalways: 0 means that this dimline can be skipped (if it contains no new data), 1 means it must be shown
                Their SETTINGS block is optional. -->
            <dimline type="main_horizontal" side="top" gap="0.3" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
                <elemparam name="fontsize">1.7</elemparam>
              </settings>
            </dimline>
            <dimline type="main_vertical" side="left" gap="0.25">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_horizontal" side="top" gap="0.2" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_vertical" side="both" gap="0.3" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_detail" side="bottom" gap="0.2" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_detangle" side="bottom" gap="0.5" showalways="0">
              <settings>
                <elemparam name="radius">0.4</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_dettext" side="bottom" gap="0.2" showalways="0">
              <settings diapre="Ø ">
                <elemparam name="fontname">Arial</elemparam>
                <elemparam name="fontstyle"></elemparam>
                <elemparam name="pen">1</elemparam>
              </settings>
            </dimline>
          </dimensionlinesettings>

          <!--
          PROJECTION contains the settings for one specific element projection. All sides must have distinct definition, so many <projection> tag can appear in one style.
          :param id: unique identifier for using in the layout and for alignment anchor (optional)
          :param type: this tells which side is projected. Can be "top", "bottom", "front", "back", "beg", "end", "real_bottom", "real_back".
          :param margins: margins in a row (left, right, top, bottom)
          :param showalways: 0 means that this projection can be skipped (if it contains no new data in the dimlines), 1 means it must be shown (it also applies to all of its dimlines)
          -->
          <projection id="frontproj" type="front" margins="0.2,0.2,0.2,0.2" showalways="0">
            <!--
            TITLE contains the settings for the title of this projection (this tag is optional).
            :param value: the text to write out for this title
            :param side: on which side of the projection should it be placed
            :param align: -1 / 0 / 1 for left, center, right OR top, middle, bottom (depending on the side parameter)
            :param offset: offset from projection (if x or y axis, that depends on the side parameter)
            -->
            <title value="FRONT" side="bottom" align="0" offset="0.10">
              <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this title -->
              <settings>
                <elemparam name="pen">16</elemparam>
              </settings>
            </title>
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this projection (view of an element) -->
            <settings>
              <elemparam name="linetype">1</elemparam>
              <elemparam name="pen">14</elemparam>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="topproj" type="top" margins="0.1,0.1,0.1,0.1" showalways="0">
            <title value="TOP" side="top" align="0" offset="0.10">
              <settings>
                <elemparam name="pen">15</elemparam>
              </settings>
            </title>
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="begproj" type="beg" margins="0.1,0.1,0.1,0.1" showalways="0">
            <title value="BEGIN" side="left" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="endproj" type="end" margins="0.1,0.1,0.1,0.1" showalways="0">
            <title value="END" side="right" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="backproj" type="back" margins="0.1,0.1,0.1,0.1" showalways="0">
            <title value="BACK" side="left" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="bottomproj" type="bottom" margins="0.1,0.1,0.1,0.1" showalways="0">
            <title value="BOTTOM" side="bottom" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <!--
          TEXTBLOCK contains the settings and content for a block of text.
          :param id: unique identifier for using in the layout and for alignment anchor (optional)
          :param margins: margins in a row (left, right, top, bottom)
          :param minwidth: minimum width in meter (optional)
          :param maxwidth: maximum width in meter (optional)
          :param content: parametrized value to print out (word substitution is applied: [matname], [mat], [quality], [usage] will be replaced with object parameter value, and [count] will be replaced by the number of similar objects)
          :param content_LANG: similar to "content", but translated (use word substitution as in content)
          -->

          <textblock id="text1" margins="0.1,0.1,0.1,0.1" minwidth="2.0" maxwidth="10.0" content="Mat: [matname]\nQuality: [quality]\nUsage: [usage]\nPcs: [count]\nIDs: [idlist]" content_fin="Mat: [mat]\nLaatu: [quality]\nKäyttö: [usage]\nKpl: [count]\nIDt: [idlist]">
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this textblock -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.5</elemparam>
              <elemparam name="fontsizemodel">59</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="pen">6</elemparam>
            </settings>
          </textblock>

          <!--
          FRAME is optional for the dim drawings, the <frame> tag can be missing from the style definition. It contains the settings for the frame drawn around the projections, dimlines, texts, etc.
          :param foreach: 1=put all different IDs to separate frames (the old way), 0=put one frame around the whole group of plank drawings
          :param horizontalgap: if framed dimdrawings are beside each other, this distance will be between the frames
          :param verticalgap: if framed dimdrawings are on the top of each other, this distance will be between the frames
          :param title: name parameter in the frame object will be filled with this value (#id# will be replaced with ID of a single plank/board, #elemid# will be replaced with the ID of the whole element)
           -->
          <frame foreach="1" horizontalgap="0.2" verticalgap="0.1" title="Frame #elemid#">
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to the frame -->
            <settings>
              <objparam name="framepen">1</objparam>
            </settings>
          </frame>

          <!--
          TABLELAYOUT is optional for the dim drawings, all projections and texts will be drawn on the top of each other, if the <tablelayout> tag is missing from the style definition.
          It has only one parameter, "main", which contains an id of a cell. That cell will be in the central, all other elem will relate to the content of that cell.
          It contains some <row> tags.
          Each <row> tag contains some <cell> tag.
          All cells in one row will be drawn beside each other, while rows will be drawn on the top of each other.
          CELL tags have parameters to define the content and alignment within.
          :param content: can be empty string or an ID of a text or projection element
          :param aligntype: can be set to "full" or "main". Full means the whole content will be taken into calculation and the whole size of neighbouring cells will be matched with that. Main means the master part of the content (e.g. projected element drawing without titles and dimension lines) will be aligned to the master parts to the neighbouring cells.
          :param alignto: can be empty or an ID of a projection element. If aligntype is main, here you can set the matching cell, instead of the default neighbour.
          :param halign: horizontal alignment, can be -1 = left, 0 = center or 1 = right.
          :param valign: vertical alignment, can be -1 = top, 0 = middle or 1 = bottom.
          :param colspan: can be set to a positive integer. It gives the number of cells merged together in this row, to form this bigger single cell.
          :param rowspan: can be set to a positive integer. It gives the number of cells merged together, stepping downward, as in a column. The following rows should skip those cell definitions, which are already merged with rowspan.
          -->
          <tablelayout main="central">
            <row>
              <cell content="text1" colspan="3" halign="-1" valign="-1" aligntype="full" />
            </row>
            <row>
              <cell content="" />
              <cell content="topproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="begproj" halign="1" valign="-1" aligntype="main" alignto="central" />
              <cell id="central" content="frontproj" halign="0" valign="0" />
              <cell content="endproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="" />
              <cell content="bottomproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="" />
              <cell content="backproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
          </tablelayout>
        </dimdrawing>
        <dimdrawing id="dim10_dev_bigframe" name="DEV big frame">

          <!--
          GENERAL contains the settings for a group of projections + titles + dimensions + textblocks.
          :param groupminwidth: gives minimum value in meter for the width of the whole group of layouts
          :param groupminheight: gives minimum value in meter for the height of the whole group of layouts
          :param groupmaxwidth: gives maximum values in meter for the width of the whole group of layouts
          :param groupmaxheight: gives maximum values in meter for the height of the whole group of layouts
          :param boxmargins: margins around each layout (left, right, top, bottom)
          -->
          <general groupminwidth="5.0" groupminheight="2.0" groupmaxwidth="80.0" groupmaxheight="50.0" boxmargins="0.9,0.9,0.9,0.9">
            <!-- it may contain default settings for all children, and this could be overwritten later -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.1</elemparam>
              <elemparam name="fontsizemodel">55</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="pen">1</elemparam>
            </settings>
          </general>

          <!--
          DIMENSIONLINESETTINGS contains the default settings for all dimension lines, and then individual parameters and settings for each dimension line, separately.
          -->
          <dimensionlinesettings>
            <!-- the following DRILL block with midout parameter is optional, you can overwrite the default setting (midout=1), if the value is 0, then the drillings with center point outside of the object will not have dim lines. -->
            <drill midout="0"></drill>
            <!-- the following REINFORCEMENT block with is optional, you can specify which direction of dimlines has to be shown (the default is to show both horizontal and vertical ones) -->
            <reinforcement horizontal="1" vertical="1"></reinforcement>
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be the base settings for dimension line definitions -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.5</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="markersize">2</elemparam>
              <elemparam name="pen">4</elemparam>
            </settings>
            <!--
                Each DIMLINE tag defines the parameters and setting of a certain type of dimension line.
                :param side: defines positioning, according to the projection (can be top, bottom, left, right, both)
                :param gap: defines distance from the last element on that side, in meter (you can position dimlines relative to each other)
                :param offset: defines distance from the projection, in meter (you can position dimlines in absolute positions, it will overwrite GAP parameter)
                :param showalways: 0 means that this dimline can be skipped (if it contains no new data), 1 means it must be shown
                Their SETTINGS block is optional. -->
            <dimline type="main_horizontal" side="top" gap="0.333" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
                <elemparam name="fontsize">1.7</elemparam>
              </settings>
            </dimline>
            <dimline type="main_vertical" side="left" gap="0.25">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_horizontal" side="top" gap="0.222" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_vertical" side="both" gap="0.3" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_detail" side="bottom" gap="0.2" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_detangle" side="bottom" gap="0.5" showalways="0">
              <settings>
                <elemparam name="radius">0.4</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_dettext" side="bottom" gap="0.2" showalways="0">
              <settings diapre="Ø ">
                <elemparam name="fontname">Arial</elemparam>
                <elemparam name="fontstyle"></elemparam>
                <elemparam name="pen">1</elemparam>
              </settings>
            </dimline>
          </dimensionlinesettings>

          <!--
          PROJECTION contains the settings for one specific element projection. All sides must have distinct definition, so many <projection> tag can appear in one style.
          :param id: unique identifier for using in the layout and for alignment anchor (optional)
          :param type: this tells which side is projected. Can be "top", "bottom", "front", "back", "beg", "end", "real_bottom", "real_back".
          :param margins: margins in a row (left, right, top, bottom)
          :param showalways: 0 means that this projection can be skipped (if it contains no new data in the dimlines), 1 means it must be shown (it also applies to all of its dimlines)
          -->
          <projection id="frontproj" type="front" margins="0.2,0.1,0.2,0.2" showalways="0">
            <!--
            TITLE contains the settings for the title of this projection (this tag is optional).
            :param value: the text to write out for this title
            :param side: on which side of the projection should it be placed
            :param align: -1 / 0 / 1 for left, center, right OR top, middle, bottom (depending on the side parameter)
            :param offset: offset from projection (if x or y axis, that depends on the side parameter)
            -->
            <title value="FRONT" side="bottom" align="0" offset="0.10">
              <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this title -->
              <settings>
                <elemparam name="pen">16</elemparam>
              </settings>
            </title>
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this projection (view of an element) -->
            <settings>
              <elemparam name="linetype">1</elemparam>
              <elemparam name="pen">14</elemparam>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="topproj" type="top" margins="0.1,0.1,0.2,0.1" showalways="0">
            <title value="TOP" side="top" align="0" offset="0.10">
              <settings>
                <elemparam name="pen">15</elemparam>
              </settings>
            </title>
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="begproj" type="beg" margins="0.1,0.1,0.1,0.1" showalways="0">
            <title value="BEGIN" side="left" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="endproj" type="end" margins="0.11,0.1,0.1,0.1" showalways="0">
            <title value="END" side="right" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="backproj" type="back" margins="0.1,0.1,0.2,0.1" showalways="0">
            <title value="BACK" side="left" align="-1" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="bottomproj" type="bottom" margins="0.1,0.1,0.2,0.2" showalways="0">
            <title value="BOTTOM" side="bottom" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <!--
          TEXTBLOCK contains the settings and content for a block of text.
          :param id: unique identifier for using in the layout and for alignment anchor (optional)
          :param margins: margins in a row (left, right, top, bottom)
          :param minwidth: minimum width in meter (optional)
          :param maxwidth: maximum width in meter (optional)
          :param content: parametrized value to print out (word substitution is applied: [matname], [mat], [quality], [usage] will be replaced with object parameter value, and [count] will be replaced by the number of similar objects)
          :param content_LANG: similar to "content", but translated (use word substitution as in content)
          -->

          <textblock id="text1" margins="0.1,0.1,0.1,0.1" minwidth="2.0" maxwidth="15.5" content="Mat: [matname]\nQuality: [quality]\nUsage: [usage]\nPcs: [count]\nIDs: [idlist]" content_fin="Mat: [mat]\nLaatu: [quality]\nKäyttö: [usage]\nKpl: [count]\nIDt: [idlist]">
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this textblock -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.5</elemparam>
              <elemparam name="fontsizemodel">59</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="pen">6</elemparam>
            </settings>
          </textblock>

          <!--
          FRAME is optional for the dim drawings, the <frame> tag can be missing from the style definition. It contains the settings for the frame drawn around the projections, dimlines, texts, etc.
          :param foreach: 1=put all different IDs to separate frames (the old way), 0=put one frame around the whole group of plank drawings
          :param horizontalgap: if framed dimdrawings are beside each other, this distance will be between the frames
          :param verticalgap: if framed dimdrawings are on the top of each other, this distance will be between the frames
          :param title: name parameter in the frame object will be filled with this value (#id# will be replaced with ID of a single plank/board, #elemid# will be replaced with the ID of the whole element)
           -->
          <frame foreach="0" horizontalgap="0.222" verticalgap="0.111" title="Frame #elemid#">
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to the frame -->
            <settings>
              <objparam name="framepen">1</objparam>
            </settings>
          </frame>

          <!--
          TABLELAYOUT is optional for the dim drawings, all projections and texts will be drawn on the top of each other, if the <tablelayout> tag is missing from the style definition.
          It has only one parameter, "main", which contains an id of a cell. That cell will be in the central, all other elem will relate to the content of that cell.
          It contains some <row> tags.
          Each <row> tag contains some <cell> tag.
          All cells in one row will be drawn beside each other, while rows will be drawn on the top of each other.
          CELL tags have parameters to define the content and alignment within.
          :param content: can be empty string or an ID of a text or projection element
          :param aligntype: can be set to "full" or "main". Full means the whole content will be taken into calculation and the whole size of neighbouring cells will be matched with that. Main means the master part of the content (e.g. projected element drawing without titles and dimension lines) will be aligned to the master parts to the neighbouring cells.
          :param alignto: can be empty or an ID of a projection element. If aligntype is main, here you can set the matching cell, instead of the default neighbour.
          :param halign: horizontal alignment, can be -1 = left, 0 = center or 1 = right.
          :param valign: vertical alignment, can be -1 = top, 0 = middle or 1 = bottom.
          :param colspan: can be set to a positive integer. It gives the number of cells merged together in this row, to form this bigger single cell.
          :param rowspan: can be set to a positive integer. It gives the number of cells merged together, stepping downward, as in a column. The following rows should skip those cell definitions, which are already merged with rowspan.
          -->
          <tablelayout main="central">
            <row>
              <cell content="text1" colspan="3" halign="-1" valign="-1" aligntype="full" />
            </row>
            <row>
              <cell content="" />
              <cell content="topproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="begproj" halign="1" valign="-1" aligntype="main" alignto="central" />
              <cell id="central" content="frontproj" halign="0" valign="0" />
              <cell content="endproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="" />
              <cell content="bottomproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="" />
              <cell content="backproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
          </tablelayout>
        </dimdrawing>
        <dimdrawing id="dim10_dev_showall" name="DEV show all dims">

          <!--
          GENERAL contains the settings for a group of projections + titles + dimensions + textblocks.
          :param groupminwidth: gives minimum value in meter for the width of the whole group of layouts
          :param groupminheight: gives minimum value in meter for the height of the whole group of layouts
          :param groupmaxwidth: gives maximum values in meter for the width of the whole group of layouts
          :param groupmaxheight: gives maximum values in meter for the height of the whole group of layouts
          :param boxmargins: margins around each layout (left, right, top, bottom)
          -->
          <general groupminwidth="3.0" groupminheight="2.0" groupmaxwidth="80.0" groupmaxheight="50.0" boxmargins="0.9,0.9,0.9,0.9">
            <!-- it may contain default settings for all children, and this could be overwritten later -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.1</elemparam>
              <elemparam name="fontsizemodel">55</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="pen">1</elemparam>
            </settings>
          </general>

          <!--
          DIMENSIONLINESETTINGS contains the default settings for all dimension lines, and then individual parameters and settings for each dimension line, separately.
          -->
          <dimensionlinesettings>
            <!-- the following DRILL block with midout parameter is optional, you can overwrite the default setting (midout=1), if the value is 0, then the drillings with center point outside of the object will not have dim lines. -->
            <drill midout="0"></drill>
            <!-- the following REINFORCEMENT block with is optional, you can specify which direction of dimlines has to be shown (the default is to show both horizontal and vertical ones) -->
            <reinforcement horizontal="1" vertical="1"></reinforcement>
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be the base settings for dimension line definitions -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.5</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="markersize">2</elemparam>
              <elemparam name="pen">4</elemparam>
            </settings>
            <!--
                Each DIMLINE tag defines the parameters and setting of a certain type of dimension line.
                :param side: defines positioning, according to the projection (can be top, bottom, left, right, both)
                :param gap: defines distance from the last element on that side, in meter (you can position dimlines relative to each other)
                :param offset: defines distance from the projection, in meter (you can position dimlines in absolute positions, it will overwrite GAP parameter)
                :param showalways: 0 means that this dimline can be skipped (if it contains no new data), 1 means it must be shown
                Their SETTINGS block is optional. -->
            <dimline type="main_horizontal" side="top" gap="0.333" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
                <elemparam name="fontsize">1.7</elemparam>
              </settings>
            </dimline>
            <dimline type="main_vertical" side="right" gap="0.25">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_horizontal" side="top" gap="0.222" showalways="1">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_vertical" side="both" gap="0.3" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_detail" side="bottom" gap="0.2" showalways="1">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_detangle" side="bottom" gap="0.5" showalways="1">
              <settings>
                <elemparam name="radius">0.4</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_dettext" side="bottom" gap="0.2" showalways="1">
              <settings diapre="Ø ">
                <elemparam name="fontname">Arial</elemparam>
                <elemparam name="fontstyle"></elemparam>
                <elemparam name="pen">1</elemparam>
              </settings>
            </dimline>
          </dimensionlinesettings>

          <!--
          PROJECTION contains the settings for one specific element projection. All sides must have distinct definition, so many <projection> tag can appear in one style.
          :param id: unique identifier for using in the layout and for alignment anchor (optional)
          :param type: this tells which side is projected. Can be "top", "bottom", "front", "back", "beg", "end", "real_bottom", "real_back".
          :param margins: margins in a row (left, right, top, bottom)
          :param showalways: 0 means that this projection can be skipped (if it contains no new data in the dimlines), 1 means it must be shown (it also applies to all of its dimlines)
          -->
          <projection id="frontproj" type="front" margins="0.2,0.1,0.2,0.2" showalways="1">
            <!--
            TITLE contains the settings for the title of this projection (this tag is optional).
            :param value: the text to write out for this title
            :param side: on which side of the projection should it be placed
            :param align: -1 / 0 / 1 for left, center, right OR top, middle, bottom (depending on the side parameter)
            :param offset: offset from projection (if x or y axis, that depends on the side parameter)
            -->
            <title value="FRONT" side="bottom" align="0" offset="0.10">
              <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this title -->
              <settings>
                <elemparam name="pen">16</elemparam>
              </settings>
            </title>
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this projection (view of an element) -->
            <settings>
              <elemparam name="linetype">1</elemparam>
              <elemparam name="pen">14</elemparam>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="topproj" type="top" margins="0.1,0.1,0.2,0.1" showalways="1">
            <title value="TOP" side="top" align="0" offset="0.10">
              <settings>
                <elemparam name="pen">15</elemparam>
              </settings>
            </title>
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="begproj" type="beg" margins="0.1,0.1,0.1,0.1" showalways="1">
            <title value="BEGIN" side="left" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="endproj" type="end" margins="0.1,0.1,0.1,0.1" showalways="1">
            <title value="END" side="right" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="backproj" type="back" margins="0.1,0.1,0.2,0.1" showalways="1">
            <title value="BACK" side="left" align="-1" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="bottomproj" type="bottom" margins="0.1,0.1,0.2,0.2" showalways="1">
            <title value="BOTTOM" side="bottom" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <!--
          TEXTBLOCK contains the settings and content for a block of text.
          :param id: unique identifier for using in the layout and for alignment anchor (optional)
          :param margins: margins in a row (left, right, top, bottom)
          :param minwidth: minimum width in meter (optional)
          :param maxwidth: maximum width in meter (optional)
          :param content: parametrized value to print out (word substitution is applied: [matname], [mat], [quality], [usage] will be replaced with object parameter value, and [count] will be replaced by the number of similar objects)
          :param content_LANG: similar to "content", but translated (use word substitution as in content)
          -->

          <textblock id="text1" margins="0.1,0.1,0.1,0.1" minwidth="2.0" maxwidth="15.5" content="Mat: [matname]\nQuality: [quality]\nUsage: [usage]\nPcs: [count]\nIDs: [idlist]" content_fin="Mat: [mat]\nLaatu: [quality]\nKäyttö: [usage]\nKpl: [count]\nIDt: [idlist]">
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this textblock -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.5</elemparam>
              <elemparam name="fontsizemodel">59</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="pen">6</elemparam>
            </settings>
          </textblock>

          <!--
          FRAME is optional for the dim drawings, the <frame> tag can be missing from the style definition. It contains the settings for the frame drawn around the projections, dimlines, texts, etc.
          :param foreach: 1=put all different IDs to separate frames (the old way), 0=put one frame around the whole group of plank drawings
          :param horizontalgap: if framed dimdrawings are beside each other, this distance will be between the frames
          :param verticalgap: if framed dimdrawings are on the top of each other, this distance will be between the frames
          :param title: name parameter in the frame object will be filled with this value (#id# will be replaced with ID of a single plank/board, #elemid# will be replaced with the ID of the whole element)
           -->
          <frame foreach="0" horizontalgap="0.222" verticalgap="0.111" title="Frame #elemid#">
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to the frame -->
            <settings>
              <objparam name="framepen">1</objparam>
            </settings>
          </frame>

          <!--
          TABLELAYOUT is optional for the dim drawings, all projections and texts will be drawn on the top of each other, if the <tablelayout> tag is missing from the style definition.
          It has only one parameter, "main", which contains an id of a cell. That cell will be in the central, all other elem will relate to the content of that cell.
          It contains some <row> tags.
          Each <row> tag contains some <cell> tag.
          All cells in one row will be drawn beside each other, while rows will be drawn on the top of each other.
          CELL tags have parameters to define the content and alignment within.
          :param content: can be empty string or an ID of a text or projection element
          :param aligntype: can be set to "full" or "main". Full means the whole content will be taken into calculation and the whole size of neighbouring cells will be matched with that. Main means the master part of the content (e.g. projected element drawing without titles and dimension lines) will be aligned to the master parts to the neighbouring cells.
          :param alignto: can be empty or an ID of a projection element. If aligntype is main, here you can set the matching cell, instead of the default neighbour.
          :param halign: horizontal alignment, can be -1 = left, 0 = center or 1 = right.
          :param valign: vertical alignment, can be -1 = top, 0 = middle or 1 = bottom.
          :param colspan: can be set to a positive integer. It gives the number of cells merged together in this row, to form this bigger single cell.
          :param rowspan: can be set to a positive integer. It gives the number of cells merged together, stepping downward, as in a column. The following rows should skip those cell definitions, which are already merged with rowspan.
          -->
          <tablelayout main="central">
            <row>
              <cell content="text1" colspan="3" halign="-1" valign="-1" aligntype="full" />
            </row>
            <row>
              <cell content="" />
              <cell content="topproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="begproj" halign="1" valign="-1" aligntype="main" alignto="central" />
              <cell id="central" content="frontproj" halign="0" valign="0" />
              <cell content="endproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="" />
              <cell content="bottomproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="" />
              <cell content="backproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
          </tablelayout>
        </dimdrawing>
        <dimdrawing id="dim10_dev_boards" name="DEV for boards">

          <!--
          GENERAL contains the settings for a group of projections + titles + dimensions + textblocks.
          :param groupminwidth: gives minimum value in meter for the width of the whole group of layouts
          :param groupminheight: gives minimum value in meter for the height of the whole group of layouts
          :param groupmaxwidth: gives maximum values in meter for the width of the whole group of layouts
          :param groupmaxheight: gives maximum values in meter for the height of the whole group of layouts
          :param boxmargins: margins around each layout (left, right, top, bottom)
          -->
          <general groupminwidth="3.0" groupminheight="2.0" groupmaxwidth="80.0" groupmaxheight="50.0" boxmargins="0.9,0.9,0.9,0.9">
            <!-- it may contain default settings for all children, and this could be overwritten later -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.1</elemparam>
              <elemparam name="fontsizemodel">55</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="pen">1</elemparam>
            </settings>
          </general>

          <!--
          DIMENSIONLINESETTINGS contains the default settings for all dimension lines, and then individual parameters and settings for each dimension line, separately.
          -->
          <dimensionlinesettings>
            <!-- the following DRILL block with midout parameter is optional, you can overwrite the default setting (midout=1), if the value is 0, then the drillings with center point outside of the object will not have dim lines. -->
            <drill midout="0"></drill>
            <!-- the following REINFORCEMENT block with is optional, you can specify which direction of dimlines has to be shown (the default is to show both horizontal and vertical ones) -->
            <reinforcement horizontal="1" vertical="1"></reinforcement>
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be the base settings for dimension line definitions -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.5</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="markersize">2</elemparam>
              <elemparam name="pen">4</elemparam>
            </settings>
            <!--
                Each DIMLINE tag defines the parameters and setting of a certain type of dimension line.
                :param side: defines positioning, according to the projection (can be top, bottom, left, right, both)
                :param gap: defines distance from the last element on that side, in meter (you can position dimlines relative to each other)
                :param offset: defines distance from the projection, in meter (you can position dimlines in absolute positions, it will overwrite GAP parameter)
                :param showalways: 0 means that this dimline can be skipped (if it contains no new data), 1 means it must be shown
                Their SETTINGS block is optional. -->
            <dimline type="main_horizontal" side="top" gap="0.333" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
                <elemparam name="fontsize">1.7</elemparam>
              </settings>
            </dimline>
            <dimline type="main_vertical" side="right" gap="0.25">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_horizontal" side="top" gap="0.222" showalways="1">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_vertical" side="both" gap="0.3" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_detail" side="bottom" gap="0.2" showalways="1">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_detangle" side="bottom" gap="0.5" showalways="1">
              <settings>
                <elemparam name="radius">0.4</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_dettext" side="bottom" gap="0.2" showalways="1">
              <settings diapre="Ø ">
                <elemparam name="fontname">Arial</elemparam>
                <elemparam name="fontstyle"></elemparam>
                <elemparam name="pen">1</elemparam>
              </settings>
            </dimline>
          </dimensionlinesettings>

          <!--
          PROJECTION contains the settings for one specific element projection. All sides must have distinct definition, so many <projection> tag can appear in one style.
          :param id: unique identifier for using in the layout and for alignment anchor (optional)
          :param type: this tells which side is projected. Can be "top", "bottom", "front", "back", "beg", "end", "real_bottom", "real_back".
          :param margins: margins in a row (left, right, top, bottom)
          :param showalways: 0 means that this projection can be skipped (if it contains no new data in the dimlines), 1 means it must be shown (it also applies to all of its dimlines)
          -->
          <projection id="frontproj" type="front" margins="0.2,0.1,0.2,0.2" showalways="1">
            <!--
            TITLE contains the settings for the title of this projection (this tag is optional).
            :param value: the text to write out for this title
            :param side: on which side of the projection should it be placed
            :param align: -1 / 0 / 1 for left, center, right OR top, middle, bottom (depending on the side parameter)
            :param offset: offset from projection (if x or y axis, that depends on the side parameter)
            -->
            <title value="FRONT" side="bottom" align="0" offset="0.10">
              <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this title -->
              <settings>
                <elemparam name="pen">16</elemparam>
              </settings>
            </title>
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this projection (view of an element) -->
            <settings>
              <elemparam name="linetype">1</elemparam>
              <elemparam name="pen">14</elemparam>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
              <objparam name="iDimLines">1</objparam>
            </settings>
          </projection>

          <projection id="topproj" type="top" margins="0.1,0.1,0.2,0.1" showalways="1">
            <title value="TOP" side="top" align="0" offset="0.10">
              <settings>
                <elemparam name="pen">15</elemparam>
              </settings>
            </title>
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="begproj" type="beg" margins="0.1,0.1,0.1,0.1" showalways="1">
            <title value="BEGIN" side="left" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="endproj" type="end" margins="0.1,0.1,0.1,0.1" showalways="1">
            <title value="END" side="right" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="backproj" type="real_back" margins="0.1,0.1,0.2,0.1" showalways="1">
            <title value="BACK" side="left" align="-1" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="bottomproj" type="real_bottom" margins="0.1,0.1,0.2,0.2" showalways="1">
            <title value="BOTTOM" side="bottom" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <!--
          TEXTBLOCK contains the settings and content for a block of text.
          :param id: unique identifier for using in the layout and for alignment anchor (optional)
          :param margins: margins in a row (left, right, top, bottom)
          :param minwidth: minimum width in meter (optional)
          :param maxwidth: maximum width in meter (optional)
          :param content: parametrized value to print out (word substitution is applied: [matname], [mat], [quality], [usage] will be replaced with object parameter value, and [count] will be replaced by the number of similar objects)
          :param content_LANG: similar to "content", but translated (use word substitution as in content)
          -->

          <textblock id="text1" margins="0.1,0.1,0.1,0.1" minwidth="2.0" maxwidth="15.5" content="Mat: [matname]\nQuality: [quality]\nUsage: [usage]\nPcs: [count]\nIDs: [idlist]" content_fin="Mat: [mat]\nLaatu: [quality]\nKäyttö: [usage]\nKpl: [count]\nIDt: [idlist]">
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this textblock -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.5</elemparam>
              <elemparam name="fontsizemodel">59</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="pen">6</elemparam>
            </settings>
          </textblock>

          <!--
          FRAME is optional for the dim drawings, the <frame> tag can be missing from the style definition. It contains the settings for the frame drawn around the projections, dimlines, texts, etc.
          :param foreach: 1=put all different IDs to separate frames (the old way), 0=put one frame around the whole group of plank drawings
          :param horizontalgap: if framed dimdrawings are beside each other, this distance will be between the frames
          :param verticalgap: if framed dimdrawings are on the top of each other, this distance will be between the frames
          :param title: name parameter in the frame object will be filled with this value (#id# will be replaced with ID of a single plank/board, #elemid# will be replaced with the ID of the whole element)
           -->
          <frame foreach="1" horizontalgap="0.222" verticalgap="0.111" title="Frame #elemid#">
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to the frame -->
            <settings>
              <objparam name="framepen">1</objparam>
            </settings>
          </frame>

          <!--
          TABLELAYOUT is optional for the dim drawings, all projections and texts will be drawn on the top of each other, if the <tablelayout> tag is missing from the style definition.
          It has only one parameter, "main", which contains an id of a cell. That cell will be in the central, all other elem will relate to the content of that cell.
          It contains some <row> tags.
          Each <row> tag contains some <cell> tag.
          All cells in one row will be drawn beside each other, while rows will be drawn on the top of each other.
          CELL tags have parameters to define the content and alignment within.
          :param content: can be empty string or an ID of a text or projection element
          :param aligntype: can be set to "full" or "main". Full means the whole content will be taken into calculation and the whole size of neighbouring cells will be matched with that. Main means the master part of the content (e.g. projected element drawing without titles and dimension lines) will be aligned to the master parts to the neighbouring cells.
          :param alignto: can be empty or an ID of a projection element. If aligntype is main, here you can set the matching cell, instead of the default neighbour.
          :param halign: horizontal alignment, can be -1 = left, 0 = center or 1 = right.
          :param valign: vertical alignment, can be -1 = top, 0 = middle or 1 = bottom.
          :param colspan: can be set to a positive integer. It gives the number of cells merged together in this row, to form this bigger single cell.
          :param rowspan: can be set to a positive integer. It gives the number of cells merged together, stepping downward, as in a column. The following rows should skip those cell definitions, which are already merged with rowspan.
          -->
          <tablelayout main="central">
            <row>
              <cell content="text1" colspan="3" halign="-1" valign="-1" aligntype="full" />
            </row>
            <row>
              <cell content="" />
              <cell content="topproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="begproj" halign="1" valign="-1" aligntype="main" alignto="central" />
              <cell id="central" content="frontproj" halign="0" valign="0" />
              <cell content="endproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="" />
              <cell content="bottomproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="" />
              <cell content="backproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
          </tablelayout>
        </dimdrawing>
        <dimdrawing id="dim10_dev_compact" name="DEV compact (no text, no frame)">

          <!--
          GENERAL contains the settings for a group of projections + titles + dimensions + textblocks.
          :param groupminwidth: gives minimum value in meter for the width of the whole group of layouts
          :param groupminheight: gives minimum value in meter for the height of the whole group of layouts
          :param groupmaxwidth: gives maximum values in meter for the width of the whole group of layouts
          :param groupmaxheight: gives maximum values in meter for the height of the whole group of layouts
          :param boxmargins: margins around each layout (left, right, top, bottom)
          -->
          <general groupminwidth="3.0" groupminheight="1.0" groupmaxwidth="80.0" groupmaxheight="50.0" boxmargins="0.9,0.9,0.9,0.9">
            <!-- it may contain default settings for all children, and this could be overwritten later -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.1</elemparam>
              <elemparam name="fontsizemodel">55</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="pen">1</elemparam>
            </settings>
          </general>

          <!--
          DIMENSIONLINESETTINGS contains the default settings for all dimension lines, and then individual parameters and settings for each dimension line, separately.
          -->
          <dimensionlinesettings>
            <!-- the following DRILL block with midout parameter is optional, you can overwrite the default setting (midout=1), if the value is 0, then the drillings with center point outside of the object will not have dim lines. -->
            <drill midout="0"></drill>
            <!-- the following REINFORCEMENT block with is optional, you can specify which direction of dimlines has to be shown (the default is to show both horizontal and vertical ones) -->
            <reinforcement horizontal="1" vertical="1"></reinforcement>
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be the base settings for dimension line definitions -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.5</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="markersize">2</elemparam>
              <elemparam name="pen">4</elemparam>
            </settings>
            <!--
                Each DIMLINE tag defines the parameters and setting of a certain type of dimension line.
                :param side: defines positioning, according to the projection (can be top, bottom, left, right, both)
                :param gap: defines distance from the last element on that side, in meter (you can position dimlines relative to each other)
                :param offset: defines distance from the projection, in meter (you can position dimlines in absolute positions, it will overwrite GAP parameter)
                :param showalways: 0 means that this dimline can be skipped (if it contains no new data), 1 means it must be shown
                Their SETTINGS block is optional. -->
            <dimline type="main_horizontal" side="top" gap="0.333" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
                <elemparam name="fontsize">1.7</elemparam>
              </settings>
            </dimline>
            <dimline type="main_vertical" side="left" gap="0.25">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_horizontal" side="top" gap="0.222" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_vertical" side="both" gap="0.3" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_detail" side="bottom" gap="0.2" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_detangle" side="bottom" gap="0.5" showalways="0">
              <settings>
                <elemparam name="radius">0.4</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_dettext" side="bottom" gap="0.2" showalways="0">
              <settings diapre="Ø ">
                <elemparam name="fontname">Arial</elemparam>
                <elemparam name="fontstyle"></elemparam>
                <elemparam name="pen">1</elemparam>
              </settings>
            </dimline>
          </dimensionlinesettings>

          <!--
          PROJECTION contains the settings for one specific element projection. All sides must have distinct definition, so many <projection> tag can appear in one style.
          :param id: unique identifier for using in the layout and for alignment anchor (optional)
          :param type: this tells which side is projected. Can be "top", "bottom", "front", "back", "beg", "end", "real_bottom", "real_back".
          :param margins: margins in a row (left, right, top, bottom)
          :param showalways: 0 means that this projection can be skipped (if it contains no new data in the dimlines), 1 means it must be shown (it also applies to all of its dimlines)
          -->
          <projection id="frontproj" type="front" margins="0.2,0.1,0.2,0.2" showalways="0">
            <!--
            TITLE contains the settings for the title of this projection (this tag is optional).
            :param value: the text to write out for this title
            :param side: on which side of the projection should it be placed
            :param align: -1 / 0 / 1 for left, center, right OR top, middle, bottom (depending on the side parameter)
            :param offset: offset from projection (if x or y axis, that depends on the side parameter)
            -->
            <title value="FRONT" side="bottom" align="0" offset="0.10">
              <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this title -->
              <settings>
                <elemparam name="pen">16</elemparam>
              </settings>
            </title>
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this projection (view of an element) -->
            <settings>
              <elemparam name="linetype">1</elemparam>
              <elemparam name="pen">14</elemparam>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="topproj" type="top" margins="0.1,0.1,0.2,0.1" showalways="0">
            <title value="TOP" side="top" align="0" offset="0.10">
              <settings>
                <elemparam name="pen">15</elemparam>
              </settings>
            </title>
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="begproj" type="beg" margins="0.1,0.1,0.1,0.1" showalways="0">
            <title value="BEGIN" side="left" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="endproj" type="end" margins="0.11,0.1,0.1,0.1" showalways="0">
            <title value="END" side="right" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="backproj" type="back" margins="0.1,0.1,0.2,0.1" showalways="0">
            <title value="BACK" side="left" align="-1" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="bottomproj" type="bottom" margins="0.1,0.1,0.2,0.2" showalways="0">
            <title value="BOTTOM" side="bottom" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <!--
          TABLELAYOUT is optional for the dim drawings, all projections and texts will be drawn on the top of each other, if the <tablelayout> tag is missing from the style definition.
          It has only one parameter, "main", which contains an id of a cell. That cell will be in the central, all other elem will relate to the content of that cell.
          It contains some <row> tags.
          Each <row> tag contains some <cell> tag.
          All cells in one row will be drawn beside each other, while rows will be drawn on the top of each other.
          CELL tags have parameters to define the content and alignment within.
          :param content: can be empty string or an ID of a text or projection element
          :param aligntype: can be set to "full" or "main". Full means the whole content will be taken into calculation and the whole size of neighbouring cells will be matched with that. Main means the master part of the content (e.g. projected element drawing without titles and dimension lines) will be aligned to the master parts to the neighbouring cells.
          :param alignto: can be empty or an ID of a projection element. If aligntype is main, here you can set the matching cell, instead of the default neighbour.
          :param halign: horizontal alignment, can be -1 = left, 0 = center or 1 = right.
          :param valign: vertical alignment, can be -1 = top, 0 = middle or 1 = bottom.
          :param colspan: can be set to a positive integer. It gives the number of cells merged together in this row, to form this bigger single cell.
          :param rowspan: can be set to a positive integer. It gives the number of cells merged together, stepping downward, as in a column. The following rows should skip those cell definitions, which are already merged with rowspan.
          -->
          <tablelayout main="central">
            <row>
              <cell content="" />
              <cell content="topproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="begproj" halign="1" valign="-1" aligntype="main" alignto="central" />
              <cell id="central" content="frontproj" halign="0" valign="0" />
              <cell content="endproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="" />
              <cell content="bottomproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="" />
              <cell content="backproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
          </tablelayout>
        </dimdrawing>

        <dimdrawing id="dim10_dev_specialcut" name="DEV special cut angles">
          <!--
          GENERAL contains the settings for a group of projections + titles + dimensions + textblocks.
          :param groupminwidth: gives minimum value in meter for the width of the whole group of layouts
          :param groupminheight: gives minimum value in meter for the height of the whole group of layouts
          :param groupmaxwidth: gives maximum values in meter for the width of the whole group of layouts
          :param groupmaxheight: gives maximum values in meter for the height of the whole group of layouts
          :param boxmargins: margins around each layout (left, right, top, bottom)
          -->
          <general groupminwidth="3.0" groupminheight="2.0" groupmaxwidth="80.0" groupmaxheight="50.0" boxmargins="0.9,0.9,0.9,0.9">
            <!-- it may contain default settings for all children, and this could be overwritten later -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.1</elemparam>
              <elemparam name="fontsizemodel">55</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="pen">1</elemparam>
            </settings>
          </general>

          <!--
          DIMENSIONLINESETTINGS contains the default settings for all dimension lines, and then individual parameters and settings for each dimension line, separately.
          -->
          <dimensionlinesettings>
            <!-- the following DRILL block with midout parameter is optional, you can overwrite the default setting (midout=1), if the value is 0, then the drillings with center point outside of the object will not have dim lines. -->
            <drill midout="0"></drill>
            <!-- the following CUTS block is optional, you can overwrite the default settings (parallelmode=0 parallelgap=0.1 anglemode=outside). The other option for anglemode is "inside". -->
            <cuts parallelmode="1" parallelgap="0.123" anglemode="inside"></cuts>
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be the base settings for dimension line definitions -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.5</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="markersize">2</elemparam>
              <elemparam name="pen">4</elemparam>
            </settings>
            <!--
                Each DIMLINE tag defines the parameters and setting of a certain type of dimension line.
                :param side: defines positioning, according to the projection (can be top, bottom, left, right, both)
                :param gap: defines distance from the last element on that side, in meter (you can position dimlines relative to each other)
                :param offset: defines distance from the projection, in meter (you can position dimlines in absolute positions, it will overwrite GAP parameter)
                :param showalways: 0 means that this dimline can be skipped (if it contains no new data), 1 means it must be shown
                Their SETTINGS block is optional. -->
            <dimline type="main_horizontal" side="top" gap="0.333" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
                <elemparam name="fontsize">1.7</elemparam>
              </settings>
            </dimline>
            <dimline type="main_vertical" side="right" gap="0.25">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_horizontal" side="top" gap="0.222" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_vertical" side="both" gap="0.3" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_detail" side="bottom" gap="0.2" showalways="0">
              <settings>
                <elemparam name="dimensiontype">linear</elemparam>
                <elemparam name="witness">1</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_detangle" side="bottom" gap="0.5" showalways="0">
              <settings>
                <elemparam name="fontsize">1</elemparam>
                <elemparam name="radius">0.15</elemparam>
              </settings>
            </dimline>
            <dimline type="machining_dettext" side="bottom" gap="0.2" showalways="0">
              <settings diapre="Ø ">
                <elemparam name="fontname">Arial</elemparam>
                <elemparam name="fontstyle"></elemparam>
                <elemparam name="pen">1</elemparam>
              </settings>
            </dimline>
          </dimensionlinesettings>

          <!--
          PROJECTION contains the settings for one specific element projection. All sides must have distinct definition, so many <projection> tag can appear in one style.
          :param id: unique identifier for using in the layout and for alignment anchor (optional)
          :param type: this tells which side is projected. Can be "top", "bottom", "front", "back", "beg", "end", "real_bottom", "real_back".
          :param margins: margins in a row (left, right, top, bottom)
          :param showalways: 0 means that this projection can be skipped (if it contains no new data in the dimlines), 1 means it must be shown (it also applies to all of its dimlines)
          -->
          <projection id="frontproj" type="front" margins="0.2,0.1,0.2,0.2" showalways="1">
            <!--
            TITLE contains the settings for the title of this projection (this tag is optional).
            :param value: the text to write out for this title
            :param side: on which side of the projection should it be placed
            :param align: -1 / 0 / 1 for left, center, right OR top, middle, bottom (depending on the side parameter)
            :param offset: offset from projection (if x or y axis, that depends on the side parameter)
            -->
            <title value="FRONT" side="bottom" align="0" offset="0.10">
              <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this title -->
              <settings>
                <elemparam name="pen">16</elemparam>
              </settings>
            </title>
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this projection (view of an element) -->
            <settings>
              <elemparam name="linetype">1</elemparam>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="topproj" type="top" margins="0.1,0.1,0.2,0.1" showalways="1">
            <title value="TOP" side="top" align="0" offset="0.10">
              <settings>
                <elemparam name="pen">15</elemparam>
              </settings>
            </title>
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="begproj" type="beg" margins="0.1,0.1,0.1,0.1" showalways="1">
            <title value="BEGIN" side="left" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <projection id="endproj" type="end" margins="0.1,0.1,0.1,0.1" showalways="1">
            <title value="END" side="right" align="0" offset="0.10" />
            <settings>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>
          <projection id="backproj" type="back" margins="0.1,0.1,0.2,0.1" showalways="1">
            <title value="BACK" side="left" align="-1" offset="0.10" />
            <settings>
              <elemparam name="pen">14</elemparam>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>
          <projection id="bottomproj" type="bottom" margins="0.1,0.1,0.2,0.2" showalways="1">
            <title value="BOTTOM" side="bottom" align="0" offset="0.10" />
            <settings>
              <elemparam name="pen">14</elemparam>
              <objparam name="#useobjlinetype">0</objparam>
              <objparam name="iFillFrom3D">0</objparam>
              <objparam name="iFillPen"></objparam>
              <objparam name="iFill">0</objparam>
            </settings>
          </projection>

          <!--
          TEXTBLOCK contains the settings and content for a block of text.
          :param id: unique identifier for using in the layout and for alignment anchor (optional)
          :param margins: margins in a row (left, right, top, bottom)
          :param minwidth: minimum width in meter (optional)
          :param maxwidth: maximum width in meter (optional)
          :param content: parametrized value to print out (word substitution is applied: [matname], [mat], [quality], [usage] will be replaced with object parameter value, and [count] will be replaced by the number of similar objects)
          :param content_LANG: similar to "content", but translated (use word substitution as in content)
          -->

          <textblock id="text1" margins="0.1,0.1,0.1,0.1" minwidth="2.0" maxwidth="15.5" content="Mat: [matname]\nQuality: [quality]\nUsage: [usage]\nPcs: [count]\nIDs: [idlist]" content_fin="Mat: [mat]\nLaatu: [quality]\nKäyttö: [usage]\nKpl: [count]\nIDt: [idlist]">
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to this textblock -->
            <settings>
              <elemparam name="fontname">Arial</elemparam>
              <elemparam name="fontsize">1.5</elemparam>
              <elemparam name="fontsizemodel">59</elemparam>
              <elemparam name="fontstyle"></elemparam>
              <elemparam name="pen">6</elemparam>
            </settings>
          </textblock>

          <!--
          FRAME is optional for the dim drawings, the <frame> tag can be missing from the style definition. It contains the settings for the frame drawn around the projections, dimlines, texts, etc.
          :param foreach: 1=put all different IDs to separate frames (the old way), 0=put one frame around the whole group of plank drawings
          :param horizontalgap: if framed dimdrawings are beside each other, this distance will be between the frames
          :param verticalgap: if framed dimdrawings are on the top of each other, this distance will be between the frames
          :param title: name parameter in the frame object will be filled with this value (#id# will be replaced with ID of a single plank/board, #elemid# will be replaced with the ID of the whole element)
           -->
          <frame foreach="0" horizontalgap="0.222" verticalgap="0.111" title="">
            <!-- the following SETTINGS block is optional, you can overwrite the default setting (coming from general tag), the result will be applied only to the frame -->
            <settings>
              <objparam name="framepen">1</objparam>
            </settings>
          </frame>

          <!--
          TABLELAYOUT is optional for the dim drawings, all projections and texts will be drawn on the top of each other, if the <tablelayout> tag is missing from the style definition.
          It has only one parameter, "main", which contains an id of a cell. That cell will be in the central, all other elem will relate to the content of that cell.
          It contains some <row> tags.
          Each <row> tag contains some <cell> tag.
          All cells in one row will be drawn beside each other, while rows will be drawn on the top of each other.
          CELL tags have parameters to define the content and alignment within.
          :param content: can be empty string or an ID of a text or projection element
          :param aligntype: can be set to "full" or "main". Full means the whole content will be taken into calculation and the whole size of neighbouring cells will be matched with that. Main means the master part of the content (e.g. projected element drawing without titles and dimension lines) will be aligned to the master parts to the neighbouring cells.
          :param alignto: can be empty or an ID of a projection element. If aligntype is main, here you can set the matching cell, instead of the default neighbour.
          :param halign: horizontal alignment, can be -1 = left, 0 = center or 1 = right.
          :param valign: vertical alignment, can be -1 = top, 0 = middle or 1 = bottom.
          :param colspan: can be set to a positive integer. It gives the number of cells merged together in this row, to form this bigger single cell.
          :param rowspan: can be set to a positive integer. It gives the number of cells merged together, stepping downward, as in a column. The following rows should skip those cell definitions, which are already merged with rowspan.
          -->
          <tablelayout main="central">
            <row>
              <cell content="text1" colspan="3" halign="-1" valign="-1" aligntype="full" />
            </row>
            <row>
              <cell content="" />
              <cell content="topproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="begproj" halign="1" valign="-1" aligntype="main" alignto="central" />
              <cell id="central" content="frontproj" halign="0" valign="0" />
              <cell content="endproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="" />
              <cell content="bottomproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
            <row>
              <cell content="" />
              <cell content="backproj" halign="-1" valign="-1" aligntype="main" alignto="central" />
            </row>
          </tablelayout>
        </dimdrawing>
      </dimdrawings>
    </misc>

    <!-- Different usage types to be used in object and in add/edit palette -->
    <usagetypes>
      <usagetype id="C24" name="C24">
      </usagetype>
      <usagetype id="general" name="General">
      </usagetype>
      <usagetype id="IF" name="IF">
      </usagetype>
    </usagetypes>

    <!-- For CLT-board front & back types preset-list -->
    <clt_bothsides>
      <item name="No texts" name_fin="Ei tekstejä" name_ger="No texts" name_pol="Bez tekstów">
        <!-- These are used if there is no lang version matching current AF language -->
        <settings>
          <objparam name="markFront"></objparam>
          <objparam name="markBack"></objparam>
          <!--objparam name="iMarkTypeFront">Arrow</objparam-->
          <!--objparam name="iMarkTypeBack">Arrow</objparam-->
        </settings>
      </item>
      <item name="BVI" name_ger="BVI">
        <!-- These are used if there is no lang version matching current AF language -->
        <settings>
          <objparam name="markFront">Front: visible</objparam>
          <objparam name="markBack">Back: visible</objparam>
          <objparam name="iMarkTypeFront">Lines</objparam>
          <objparam name="iMarkTypeBack">Lines</objparam>
        </settings>

        <settings lang="fin">
          <objparam name="markFront">Etu: näkyy</objparam>
          <objparam name="markBack">Taka: näkyy</objparam>
          <objparam name="iMarkTypeFront">Lines</objparam>
          <objparam name="iMarkTypeBack">Lines</objparam>
        </settings>

        <settings lang="ger">
          <objparam name="markFront">Front: visible</objparam>
          <objparam name="markBack">Back: visible</objparam>
          <objparam name="iMarkTypeFront">Lines</objparam>
          <objparam name="iMarkTypeBack">Lines</objparam>
        </settings>

         <settings lang="pol">
          <objparam name="markFront">oznaczenie Front</objparam>
          <objparam name="markBack">oznaczenie Tył</objparam>
          <objparam name="iMarkTypeFront">Lines</objparam>
          <objparam name="iMarkTypeBack">Lines</objparam>
        </settings>
      </item>
      <item name="VI - Front" name_ger="VI - Front">
        <!-- These are used if there is no lang version matching current AF language -->
        <settings>
          <objparam name="markFront">Front: visible</objparam>
          <objparam name="markBack">Back: not visible</objparam>
          <objparam name="iMarkTypeFront">Lines</objparam>
          <objparam name="iMarkTypeBack">Single line</objparam>
        </settings>

        <settings lang="fin">
          <objparam name="markFront">Etu: näkyy</objparam>
          <objparam name="markBack">Taka: ei näy</objparam>
          <objparam name="iMarkTypeFront">Lines</objparam>
          <objparam name="iMarkTypeBack">Single line</objparam>
        </settings>
        
        <settings lang="ger">
          <objparam name="markFront">Front: visible</objparam>
          <objparam name="markBack">Back: not visible</objparam>
          <objparam name="iMarkTypeFront">Lines</objparam>
          <objparam name="iMarkTypeBack">Single line</objparam>
        </settings>

        <settings lang="pol">
          <objparam name="markFront">oznaczenie Front</objparam>
          <objparam name="markBack">oznaczenie Tył</objparam>
          <objparam name="iMarkTypeFront">Lines</objparam>
          <objparam name="iMarkTypeBack">Single line</objparam>
        </settings>
      </item>
      <item name="VI - Back" name_ger="VI - Back">
        <!-- These are used if there is no lang version matching current AF language -->
        <settings>
          <objparam name="markFront">Front: not visible</objparam>
          <objparam name="markBack">Back: visible</objparam>
          <objparam name="iMarkTypeFront">Single line</objparam>
          <objparam name="iMarkTypeBack">Lines</objparam>
        </settings>

        <settings lang="fin">
          <objparam name="markFront">Etu: ei näy</objparam>
          <objparam name="markBack">Taka: näkyy</objparam>
          <objparam name="iMarkTypeFront">Single line</objparam>
          <objparam name="iMarkTypeBack">Lines</objparam>
        </settings>

        <settings lang="ger">
          <objparam name="markFront">Front: not visible</objparam>
          <objparam name="markBack">Back: visible</objparam>
          <objparam name="iMarkTypeFront">Single line</objparam>
          <objparam name="iMarkTypeBack">Lines</objparam>
        </settings>

        <settings lang="pol">
          <objparam name="markFront">oznaczenie Front</objparam>
          <objparam name="markBack">oznaczenie Tył</objparam>
          <objparam name="iMarkTypeFront">Single line</objparam>
          <objparam name="iMarkTypeBack">Lines</objparam>
        </settings>
      </item>
      <item name="NVI" name_ger="NVI">
        <!-- These are used if there is no lang version matching current AF language -->
        <settings>
          <objparam name="markFront">Front: not visible</objparam>
          <objparam name="markBack">Back: not visible</objparam>
          <objparam name="iMarkTypeFront">Single line</objparam>
          <objparam name="iMarkTypeBack">Single line</objparam>
        </settings>

        <settings lang="fin">
          <objparam name="markFront">Etu: ei näy</objparam>
          <objparam name="markBack">Taka: ei näy</objparam>
          <objparam name="iMarkTypeFront">Single line</objparam>
          <objparam name="iMarkTypeBack">Single line</objparam>
        </settings>

        <settings lang="ger">
          <objparam name="markFront">Front: not visible</objparam>
          <objparam name="markBack">Back: not visible</objparam>
          <objparam name="iMarkTypeFront">Single line</objparam>
          <objparam name="iMarkTypeBack">Single line</objparam>
        </settings>

        <settings lang="pol">
          <objparam name="markFront">oznaczenie Front</objparam>
          <objparam name="markBack">oznaczenie Tył</objparam>
          <objparam name="iMarkTypeFront">Single line</objparam>
          <objparam name="iMarkTypeBack">Single line</objparam>
        </settings>
      </item>
    </clt_bothsides>

    <!-- For CLT-board front & back types preset-list -->
    <clt_front>
      <item name="">
        <settings>
          <objparam name="markFront"></objparam>
        </settings>
      </item>

      <item name="Front: visible" name_fin="Etu: näkyy" name_ger="Front: visible" name_pol="Front: widoczny">
        <settings>
          <objparam name="markFront">Front: visible</objparam>
          <!--objparam name="iMarkTypeFront">Lines</objparam-->
        </settings>

        <settings lang="fin">
          <objparam name="markFront">Etu: näkyy</objparam>
          <!--objparam name="iMarkTypeFront">Lines</objparam-->
        </settings>

        <settings lang="ger">
          <objparam name="markFront">Front: visible</objparam>
          <!--objparam name="iMarkTypeFront">Lines</objparam-->
        </settings>

        <settings lang="pol">
          <objparam name="markFront">oznaczenie Front</objparam>
          <!--objparam name="typ oznaczenia Front">Lines</objparam-->
        </settings>
      </item>

      <item name="Front: not visible" name_fin="Etu: ei näy" name_ger="Front: not visible" name_pol="Front: niewidoczny">
        <settings>
          <objparam name="markFront">Front: not visible</objparam>
          <!--objparam name="iMarkTypeFront">Single line</objparam-->
        </settings>

        <settings lang="fin">
          <objparam name="markFront">Etu: ei näy</objparam>
          <!--objparam name="iMarkTypeFront">Single line</objparam-->
        </settings>
        
        <settings lang="ger">
          <objparam name="markFront">Front: not visible</objparam>
          <!--objparam name="iMarkTypeFront">Single line</objparam-->
        </settings>

        <settings lang="pol">
          <objparam name="markFront">oznaczenie Front</objparam>
          <!--objparam name="typ oznaczenia Front">Single line</objparam-->
        </settings>
      </item>

      <item name="Front: treated" name_fin="Etu: käsitelty" name_ger="Front: treated" name_pol="Front: poddany obróbce">
        <settings>
          <objparam name="markFront">Front: treated</objparam>
          <!--objparam name="iMarkTypeFront">Lines</objparam-->
        </settings>

        <settings lang="fin">
          <objparam name="markFront">Etu: käsitelty</objparam>
          <!--objparam name="iMarkTypeFront">Lines</objparam-->
        </settings>
        
        <settings lang="ger">
          <objparam name="markFront">Front: treated</objparam>
          <!--objparam name="iMarkTypeFront">Lines</objparam-->
        </settings>

        <settings lang="pol">
          <objparam name="markFront">oznaczenie Front</objparam>
          <!--objparam name="typ oznaczenia Front">Lines</objparam-->
        </settings>
      </item>
    </clt_front>

    <clt_back>
      <item name="">
        <settings>
          <objparam name="markBack"></objparam>
        </settings>
      </item>

      <item name="Back: visible" name_fin="Taka: näkyy" name_ger="Back: visible" name_pol="Tył: widoczny">
        <settings>
          <objparam name="markBack">Back: visible</objparam>
          <!--objparam name="iMarkTypeBack">Lines</objparam-->
        </settings>

        <settings lang="fin">
          <objparam name="markBack">Taka: näkyy</objparam>
          <!--objparam name="iMarkTypeBack">Lines</objparam-->
        </settings>
        
        <settings lang="ger">
          <objparam name="markBack">Back: visible</objparam>
          <!--objparam name="iMarkTypeBack">Lines</objparam-->
        </settings>

        <settings lang="pol">
          <objparam name="markBack">oznaczenie Tył</objparam>
          <!--objparam name="typ oznaczenia Tył">Lines</objparam-->
        </settings>
      </item>

      <item name="Back: not visible" name_fin="Taka: ei näy" name_ger="Back: not visible" name_pol="Tył: niewidoczny">
        <settings>
          <objparam name="markBack">Back: not visible</objparam>
          <!--objparam name="iMarkTypeBack">Single line</objparam-->
        </settings>

        <settings lang="fin">
          <objparam name="markBack">Taka: ei näy</objparam>
          <!--objparam name="iMarkTypeBack">Single line</objparam-->
        </settings>

        <settings lang="ger">
          <objparam name="markBack">Back: not visible</objparam>
          <!--objparam name="iMarkTypeBack">Single line</objparam-->
        </settings>

         <settings lang="pol">
          <objparam name="markBack">oznaczenie Tył</objparam>
          <!--objparam name="typ oznaczenia Tył">Single line</objparam-->
        </settings>
      </item>

      <item name="Back: treated" name_fin="Taka: käsitelty" name_ger="Back: treated" name_pol="Tył: poddany obróbce">
        <settings>
          <objparam name="markBack">Back: treated</objparam>
          <!--objparam name="iMarkTypeBack">Lines</objparam-->
        </settings>

        <settings lang="fin">
          <objparam name="markBack">Taka: käsitelty</objparam>
          <!--objparam name="iMarkTypeBack">Lines</objparam-->
        </settings>

        <settings lang="ger">
          <objparam name="markBack">Back: treated</objparam>
          <!--objparam name="iMarkTypeBack">Lines</objparam-->
        </settings>

        <settings lang="pol">
          <objparam name="markBack">oznaczenie Tył</objparam>
          <!--objparam name="typ oznaczenia Tył">Lines</objparam-->
        </settings>
      </item>
    </clt_back>

    <!-- List of hidden balk joint shoes -->
    <balkhiddenjoints>
      <balkhiddenjoint name="Hidden balk joint 1" id="HIDDENBALKJOINT1" cutwidth="0.050" cutheight="0.150" cutdepth="0.005" grodepth="0.100" growidth="0.008" drilly1="0.050" drilldist="0.080" drillsize="0.010" drillspace="0.040" drillcount="3" cutheight_customy1="drilly1+0.100">
      </balkhiddenjoint>
    </balkhiddenjoints>

    <!-- General default for tenon&mortise -->
    <mortisetenon len="0.056" lenrelative="0.5" bordertop="0.02" borderbot="0.005" borderside="0.01" roundingr="0.0225" endgap="0.001" sidegap="0.001" topgap="0.010">
    </mortisetenon>

    <!-- General default for dovetail -->
    <dovetail len="0.038" bordertop="0.00" borderbot="0.050" bottomwidth="0.06" roundingr="0.0225" endgap="0.000" sidegap="0.000" angle="6" >
    </dovetail>

    <!-- General default for balkwedge -->
    <balkwedge len="0.010" bordertop="0.0" borderbot="0.050" bottomwidth="0.06" roundingr="0.0225" sidegap="0.001">
    </balkwedge>

    <!-- List of hobafix-joints -->
    <hobafixes>
      <hobafix name="Hobafix 50x100" id="HOBAFIX 60X100" thickness="0.010" width="0.060" height="0.100" roundingr="0.020" acmat="" len="0.010">
      </hobafix>
      <hobafix name="Hobafix 60x200" id="HOBAFIX 60X200" thickness="0.010" width="0.060" height="0.200" roundingr="0.020" acmat="" len="0.010">
      </hobafix>
    </hobafixes>

    <metalconnectors>
      <!-- Anchor point x,y is the point where the metal connector is anchored to the plank, it is defined in the local coordinate system of the metal connector -->
      <!-- Attribute plankend can have values bottom, middle, top anchoring the metal piece's anchor point to the given surface point of the plank -->
      <!-- x_to_global_z is defined to 1 for connectors used in columns only allowing connecting angled pieces to it. -->
      <!-- Oversize thickness defines how much wider the slot will be than the thickness of the metal piece (applied two times to both sides), over_end is used in generated groove's bottom, over_side on sides and should be radius of the milling tool (applied twice to both sides) -->
      <metalconnector name="Metal connector 50x100" id="METAL CONNECTOR 50X100" thickness="0.010" x="0.050" y="0.025" plankend="middle" x_to_global_z="0" over_thickness="0.001" over_side="0.010" over_end="0.001">
        <!-- Similar definition as for cladding panel's cross section, can be dumped from a fill using AF main tool palette/arrow/Dump profile from fill. Allows generating a GDL object later on from the definition. -->
        <profile>
          <point xym="0.000 0.000 15" />
          <point xym="0.100 0.000 15" />
          <point xym="0.100 0.050 15" />
          <point xym="0.000 0.050 15" />
        </profile>

        <!-- The drillings, depth zero will dill through, non-zero drillings will be added to both sides of the target planks -->
        <drillings>
          <drill x="0.010" y="0.010" diameter="0.010" depth="0"/>
          <drill x="0.010" y="0.040" diameter="0.010" depth="0"/>
          <drill x="0.030" y="0.010" diameter="0.010" depth="0"/>
          <drill x="0.030" y="0.040" diameter="0.010" depth="0"/>
          
          <drill x="0.010" y="0.010" diameter="0.020" depth="0.010"/>
          <drill x="0.010" y="0.040" diameter="0.020" depth="0.010"/>
          <drill x="0.030" y="0.010" diameter="0.020" depth="0.010"/>
          <drill x="0.030" y="0.040" diameter="0.020" depth="0.010"/>

          <drill x="0.070" y="0.010" diameter="0.010" depth="0"/>
          <drill x="0.070" y="0.040" diameter="0.010" depth="0"/>
          <drill x="0.090" y="0.010" diameter="0.010" depth="0"/>
          <drill x="0.090" y="0.040" diameter="0.010" depth="0"/>

          <drill x="0.070" y="0.010" diameter="0.020" depth="0.010"/>
          <drill x="0.070" y="0.040" diameter="0.020" depth="0.010"/>
          <drill x="0.090" y="0.010" diameter="0.020" depth="0.010"/>
          <drill x="0.090" y="0.040" diameter="0.020" depth="0.010"/>
        </drillings>
      </metalconnector>

      <metalconnector name="Metal connector 50x200" id="METAL CONNECTOR 50X200" thickness="0.010" x="0.100" y="0.025" plankend="middle" x_to_global_z="0" over_thickness="0.001" over_side="0.010" over_end="0.001">
        <!-- Similar definition as for cladding panel's cross section, can be dumped from a fill using AF main tool palette/arrow/Dump profile from fill. Allows generating a GDL object later on from the definition. -->
        <profile>
          <point xym="0.000 0.010 15" />
          <point xym="0.050 0.010 15" />
          <point xym="0.050 0.000 15" />
          <point xym="0.150 0.000 15" />
          <point xym="0.150 0.010 15" />
          <point xym="0.200 0.010 15" />
          <point xym="0.200 0.040 15" />
          <point xym="0.150 0.040 15" />
          <point xym="0.150 0.050 15" />
          <point xym="0.050 0.050 15" />
          <point xym="0.050 0.040 15" />
          <point xym="0.000 0.040 15" />
        </profile>

        <!-- The drillings, depth zero will dill through, non-zero drillings will be added to both sides of the target planks -->
        <drillings>
          <drill x="0.010" y="0.010" diameter="0.010" depth="0"/>
          <drill x="0.010" y="0.040" diameter="0.010" depth="0"/>
          <drill x="0.030" y="0.010" diameter="0.010" depth="0"/>
          <drill x="0.030" y="0.040" diameter="0.010" depth="0"/>

          <drill x="0.010" y="0.010" diameter="0.020" depth="0.010"/>
          <drill x="0.010" y="0.040" diameter="0.020" depth="0.010"/>
          <drill x="0.030" y="0.010" diameter="0.020" depth="0.010"/>
          <drill x="0.030" y="0.040" diameter="0.020" depth="0.010"/>

          <drill x="0.170" y="0.010" diameter="0.010" depth="0"/>
          <drill x="0.170" y="0.040" diameter="0.010" depth="0"/>
          <drill x="0.190" y="0.010" diameter="0.010" depth="0"/>
          <drill x="0.190" y="0.040" diameter="0.010" depth="0"/>

          <drill x="0.170" y="0.010" diameter="0.020" depth="0.010"/>
          <drill x="0.170" y="0.040" diameter="0.020" depth="0.010"/>
          <drill x="0.190" y="0.010" diameter="0.020" depth="0.010"/>
          <drill x="0.190" y="0.040" diameter="0.020" depth="0.010"/>
        </drillings>
      </metalconnector>


      <metalconnector name="Metal connector 50x200 Angled" id="METAL CONNECTOR 50X200 ANGLED" thickness="0.010" x="0.100" y="0.025" plankend="middle" x_to_global_z="0" over_thickness="0.001" over_side="0.010" over_end="0.001">
        <!-- Similar definition as for cladding panel's cross section, can be dumped from a fill using AF main tool palette/arrow/Dump profile from fill. Allows generating a GDL object later on from the definition. -->
        <profile>
          <point xym="0.000 0.005 15" />
          <point xym="0.050 0.005 15" />
          <point xym="0.100 0.000 15" />
          <point xym="0.150 0.005 15" />
          <point xym="0.200 0.005 15" />
          <point xym="0.200 0.050 15" />
          <point xym="0.000 0.050 15" />
        </profile>

        <!-- The drillings, depth zero will dill through, non-zero drillings will be added to both sides of the target planks -->
        <drillings>
          <drill x="0.010" y="0.010" diameter="0.010" depth="0"/>
          <drill x="0.010" y="0.040" diameter="0.010" depth="0"/>
          <drill x="0.030" y="0.010" diameter="0.010" depth="0"/>
          <drill x="0.030" y="0.040" diameter="0.010" depth="0"/>

          <drill x="0.010" y="0.010" diameter="0.020" depth="0.010"/>
          <drill x="0.010" y="0.040" diameter="0.020" depth="0.010"/>
          <drill x="0.030" y="0.010" diameter="0.020" depth="0.010"/>
          <drill x="0.030" y="0.040" diameter="0.020" depth="0.010"/>

          <drill x="0.170" y="0.010" diameter="0.010" depth="0"/>
          <drill x="0.170" y="0.040" diameter="0.010" depth="0"/>
          <drill x="0.190" y="0.010" diameter="0.010" depth="0"/>
          <drill x="0.190" y="0.040" diameter="0.010" depth="0"/>

          <drill x="0.170" y="0.010" diameter="0.020" depth="0.010"/>
          <drill x="0.170" y="0.040" diameter="0.020" depth="0.010"/>
          <drill x="0.190" y="0.010" diameter="0.020" depth="0.010"/>
          <drill x="0.190" y="0.040" diameter="0.020" depth="0.010"/>
        </drillings>
      </metalconnector>

    </metalconnectors>


    <!-- General default for narrowed balk joint -->
    <balkborder bordertop="0.02" borderbot="0.005" borderside="0.01" overtop="0.001" overbot="0.000" overside="0.001" overlen="0.000" >
    </balkborder>

    <!-- General default for whole balk joint -->
    <balkcut overtop="0.01" overbot="0.000" overside="0.001" >
    </balkcut>

    <!-- List of reinforcement plates -->
    <reinforcements>
      <item name="SF200" id="SF200" ymid="0.099" width="0.600" height="0.104" thickness="0.018" inside="1" bothsides="1" mat="*osb*">
      </item>
      <item name="SF220" id="SF220" ymid="0.109" width="0.600" height="0.134" thickness="0.018" inside="1" bothsides="1" mat="*osb*">
      </item>
      <item name="SF250" id="SF250" ymid="0.124" width="0.600" height="0.154" thickness="0.018" inside="1" bothsides="1" mat="*osb*">
      </item>
      <item name="SF250 OUT" id="SF250 OUT" ymid="0.124" width="0.600" height="0.154" thickness="0.018" inside="0" bothsides="1">
      </item>
      <item name="SF300" id="SF300" ymid="0.149" width="0.600" height="0.204" thickness="0.018" inside="1" bothsides="1" mat="*osb*">
      </item>
      <item name="SF350" id="SF350" ymid="0.174" width="0.600" height="0.254" thickness="0.018" inside="1" bothsides="1" mat="*osb*">
      </item>
      <item name="SF400" id="SF400" ymid="0.199" width="0.600" height="0.304" thickness="0.018" inside="1" bothsides="1" mat="*osb*">
      </item>
      <item name="SF450" id="SF450" ymid="0.224" width="0.600" height="0.354" thickness="0.018" inside="1" bothsides="1" mat="*osb*">
      </item>
      <item name="SF500" id="SF500" ymid="0.249" width="0.600" height="0.404" thickness="0.018" inside="1" bothsides="1" mat="*osb*">
      </item>
      <item name="SF550" id="SF550" ymid="0.274" width="0.600" height="0.454" thickness="0.018" inside="1" bothsides="1" mat="*osb*">
      </item>
      <item name="SF600" id="SF600" ymid="0.299" width="0.600" height="0.504" thickness="0.018" inside="1" bothsides="1" mat="*osb*">
      </item>
    </reinforcements>

    <plankdefaults defaultlayer="Wall drawings.2d" plankminlen="0.01">
      <elemparam name="pen">1</elemparam>
      <objparam name="iPenErr">3</objparam>
      <objparam name="iPenLocked">3</objparam>
      <objparam name="iPenNoCnc">3</objparam>
      <objparam name="iLengthFormat">mm</objparam>
      <objparam name="iFontSizeBase">10</objparam>
      <objparam name="iShowID">1</objparam>
      <objparam name="iShowID3D">1</objparam>
      <objparam name="iYoffID">0</objparam>
      <objparam name="iMaxLenForCncOnly">0</objparam>
      <objparam name="iBuildingmat"></objparam>
      <class system="ARCHICAD Classification" system_fin="ARCHICAD-luokitus" system_pol="ARCHICAD Classification">
        <classpath name="Materials" name_fin="Materiaalit" name_pol="Materiały"/>
        <classpath name="Wood" name_fin="Puu" name_pol="Drewno"/>
      </class>
    </plankdefaults>

    <!-- To guide cnc-related operations -->
    <!-- To optimize length of the planks having angled tenons and dt-tenons you can specify the angle of dt-tool to dtangle-attribute. With value 0 no optimization is done to either tenons or dt-tenons -->
    <cnclimits gromaxdepth="0.160" nailmindistplank="0.0031" nailmindistboard="0.0031" elemgeo="1" dtangle="0"></cnclimits>

    <dimpresets>
      <dimpreset name="Settings from dim tool" name_fin="Asetukset mittatyökalusta" name_ger="Einstellungen vom Vermessungswerkzeug" name_pol="Ustawienia narzędzia wymiarowanie">
      </dimpreset>

      <dimpreset name="C/C text to front" name_fin="C/C teksti alkuun" name_ger="C/C Text am Anfang" name_pol="C/C Tekst na Front" setmin="0" setmid="1" setmax="0">
        <dimlinesettings>
          <elemparam name="dimensiontype" >linear</elemparam>
          <elemparam name="fontname">Arial</elemparam>
          <elemparam name="fontsize">1.5</elemparam>
          <elemparam name="fontstyle"></elemparam>
        </dimlinesettings>
        <text content="C/C" textid="0" anchor="6" marg="0.2">
          <elemparam name="pen">11</elemparam>
          <elemparam name="fontname">arial</elemparam>
          <elemparam name="fontsize">1.5</elemparam>
          <elemparam name="fontstyle"></elemparam>
        </text>
      </dimpreset>

      <dimpreset name="Left cumulative" name_fin="Vasen juokseva" name_ger="Links anwachsend" name_pol="Do lewej" setmin="1" setmid="0" setmax="0">
        <dimlinesettings>
          <elemparam name="dimensiontype" >cumulative</elemparam>
          <elemparam name="fontname">Arial</elemparam>
          <elemparam name="fontsize">1.5</elemparam>
          <elemparam name="fontstyle"></elemparam>
        </dimlinesettings>
        <text content="LEFT" textid="0" anchor="6" marg="0.2">
          <elemparam name="pen">11</elemparam>
          <elemparam name="fontname">arial</elemparam>
          <elemparam name="fontsize">1.5</elemparam>
          <elemparam name="fontstyle"></elemparam>
        </text>
      </dimpreset>

      <dimpreset name="Truss center" name_fin="Ristikko keski" name_pol="Kratownica centralna" setmin="0" setmid="1" setmax="0">
        <dimlinesettings>
          <elemparam name="dimensiontype">cumulative</elemparam>
          <elemparam name="markertype">5</elemparam>
          <elemparam name="fontname">Arial</elemparam>
          <elemparam name="fontsize">1.5</elemparam>
          <elemparam name="fontstyle"></elemparam>
        </dimlinesettings>
        <text content="Truss" content_fin="Ristikko" content_pol="Kratownica" textid="0" anchor="6" marg="0.2">
          <elemparam name="pen">1</elemparam>
          <elemparam name="fontname">arial</elemparam>
          <elemparam name="fontsize">1.5</elemparam>
          <elemparam name="fontstyle"></elemparam>
        </text>
      </dimpreset>
    </dimpresets>

    <selautomations>
      <script name="Show all layers starting with AF and space (AF *)" name_fin="Näytä kaikki AF ja välilyönti -alkuiset tasot (AF *)" name_nor="Vis konstruksjon (AF *)" name_pol="Pokaż wszystkie warstwy rozpoczynające się od AF i spacji (AF *)" openundo="0">
        <![CDATA[
ac_environment("layer", "af *", 1)
ac_environment("rebuild", 1)
]]>
      </script>

      <script name="Hide all layers starting with AF and space (AF *)" name_fin="Piilota kaikki AF ja välilyönti -alkuiset tasot (AF *)" name_nor="Skjul konstruksjon (AF *)" name_pol="Ukryj wszystkie warstwy rozpoczynające się od AF i spacji (AF )" openundo="0">
        <![CDATA[
ac_environment("layer", "af *", 0)
ac_environment("rebuild", 1)
]]>
      </script>

      <script name="Excel plank list to ArchiFrameBlocks.xml" openundo="0">
        <![CDATA[
ac_environment("tolog", "This helper reads given Excel file and dumps xml material list (Windows only).\nExcel columns must be:\nA=Width mm\nB=Height mm\nC=Optional maximum length in METERS")
fileName=ac_environment("filedialog", false, "Open Excel file for materials", "All files (*.*)|*.*|", "xls")
if fileName then
  excelStarted=nil
    gExcel=luacom.GetObject("Excel.Application")
    if gExcel==nil then
        gExcel = luacom.CreateObject("Excel.Application")
        excelStarted = gExcel
    end

    wb = gExcel.Workbooks:Open(fileName)
    ws = wb.Worksheets(1)

  -- Read until two empty rows
  emptyRows=0
  for rowNum=1,9999 do
    if ws.Cells(rowNum,1).Value2==nil or ws.Cells(rowNum,1).Value2=="" then
      emptyRows=emptyRows+1
      if emptyRows==2 then
        break
      end
    else
      emptyRows=0
      width=ws.Cells(rowNum,1).Value2
      height=ws.Cells(rowNum,2).Value2
      maxlen=ws.Cells(rowNum,3).Value2
      if width then
        if maxlen==nil or maxlen=="" then
          maxlen=""
        else
          maxlen=string.format(" maxlen=\"%s\"", maxlen)
        end
        s=string.format("<material id=\"%sx%s\" name=\"%sx%s\" thickness=\"%0.5f\" height=\"%0.5f\" shape=\"block\"%s>\n</material>\n\n", width, height, width, height, tonumber(width)/1000, tonumber(height)/1000, maxlen)
        ac_environment("tolog", s)      
      end
    end
  end

    ws=nil
    wb=nil
    if excelStarted~=nil then
        excelStarted:Quit()
        excelStarted=nil
    end
end
]]>
      </script>

      <script name="Limit selection to vertical planks" openundo="0">
        <![CDATA[
tblPlanks=af_request("getselplanks")
tblVert={}
vert=0
for i,v in pairs(tblPlanks) do
  plankInfo=af_request("plankinfo", v)
  if math.abs(plankInfo.vecx.z)>0.999 then
    vert=vert+1
    tblVert[vert]=v
  end
end

if vert==0 then
  ac_environment("setsel", nil)
else
  ac_environment("setsel", tblVert)
end

]]>
      </script>

    </selautomations>

  </settings>

  <!-- Event handlers - loaded when these settings are loaded and kept in memory for performance -->
  <observer>
    <![CDATA[
gDegToRad=3.1415927/180
EPS=0.0001

-- Dumps given variable into string
function DumpTblInt(o)
  local s
  
  if type(o) == 'table' then
    s = '{ '
    for k,v in pairs(o) do
      if type(k) ~= 'number' then k = '"'..k..'"' end
      s = s .. '['..k..'] = ' .. DumpTblInt(v) .. ','
    end
    s=s .. '} '
  else
    s=tostring(o)
  end
  return s
end


function DumpTbl(o)
  ac_environment( "tolog", DumpTblInt(o) )
end


function GetLang()
  local lang
  
  lang=af_request("aflang")
  if lang==nil then
    lang="eng"
  end
  return lang
end


function GetMcRow(row)
  local tbl

  tbl={}
  tbl.index=row
  cols=ac_objectget("iMc", 0, -1)
  for col=1,cols do
    tbl[col]=ac_objectget("iMc", row, col)
  end

  return tbl
end


function IsSameMc(tbl1, tbl2)
  local col
  
  -- Skip last column - it is opid
  for col=1,15 do
    if math.abs(tbl1[col]-tbl2[col])>0.0001 then
      return false
    end
  end

  return true
end


-- Checks if reinforcement covers the groove
function ReinforceCoversGro(tblReinforce, tblGro)
  local x1, x2, xGro
  
  x1=tblReinforce[2]-tblReinforce[4]*0.5
  x2=x1+tblReinforce[4]
  
  xGro=tblGro[2]
  return x1<xGro and x2>xGro
end


-- Gets groove info for current plank and mc tblGroMc
-- Sets also boundbox of all lines at side surfaces: sidex1,sidey1,sidex2,sidey2
function GetGroInfo( plankInfo, tblGroMc )
    local tblGro, tblGroInfo, x1, y1, x2, y2

    tblGro={}
    tblGro.guid = plankInfo.ptr
    tblGro.x1   = tblGroMc[2]
    tblGro.y1   = tblGroMc[3]
    tblGro.x2   = tblGroMc[4]
    tblGro.y2   = tblGroMc[5]
    tblGro.depth    = tblGroMc[6]
    tblGro.width    = tblGroMc[7]
    tblGro.groAngleRad  = tblGroMc[8]*gDegToRad
    tblGro.face   = tblGroMc[9]
    tblGro.groTiltAngleRad  = tblGroMc[10]*gDegToRad

  tblGroInfo=af_request("mc_getgroinfo", tblGro)

  x1=tblGroInfo.projside1.linebot.x1
  y1=tblGroInfo.projside1.linebot.y1
  x2=tblGroInfo.projside1.linebot.x2
  y2=tblGroInfo.projside1.linebot.y2

  if tblGroInfo.projside1.lineref.len>0 then
    x1=math.min(x1, tblGroInfo.projside1.lineref.x1)
    y1=math.min(y1, tblGroInfo.projside1.lineref.y1)
    x2=math.max(x2, tblGroInfo.projside1.lineref.x2)
    y2=math.max(y2, tblGroInfo.projside1.lineref.y2)
  end

  if tblGroInfo.projside1.lineother.len>0 then
    x1=math.min(x1, tblGroInfo.projside1.lineother.x1)
    y1=math.min(y1, tblGroInfo.projside1.lineother.y1)
    x2=math.max(x2, tblGroInfo.projside1.lineother.x2)
    y2=math.max(y2, tblGroInfo.projside1.lineother.y2)
  end

  tblGroInfo.sidex1=x1
  tblGroInfo.sidey1=y1
  tblGroInfo.sidex2=x2
  tblGroInfo.sidey2=y2

    return tblGroInfo
end


-- Returns reinforcement id, its height
function GetReinforceCode(height)
  local s, dy

  if height<0.2195 then
    s="SF200"
    dy=0.104
  elseif height<0.2495 then
    s="SF220"
    dy=0.134
  elseif height<0.2995 then
    s="SF250"
    dy=0.154
  elseif height<0.3495 then
    s="SF300"
    dy=0.204
  elseif height<0.3995 then
    s="SF350"
    dy=0.254
  elseif height<0.4495 then
    s="SF400"
    dy=0.304
  elseif height<0.4995 then
    s="SF450"
    dy=0.354
  elseif height<0.5495 then
    s="SF500"
    dy=0.404
  elseif height<0.5995 then
    s="SF550"
    dy=0.454
  else
    s="SF600"
    dy=0.504
  end
  
  return s,dy
end


-- Calculates reinforcement for given groove, sets tblGro.groInfo also
-- Returns: tbl=reinforcement table with fields x1, x2, groInfo
--          nil=no automatic reinforcement for this groove
function AddReinforce(plankInfo, tblGro)
  local tblGroInfo, extend, tbl, tanTilt, cosTilt, len2, add1, add2

  -- Must be bottom surface
  if tblGro[9]~=3 then
    return nil
  end

  tblGroInfo=GetGroInfo(plankInfo, tblGro)

  -- CONDITION: at least 16 mm and for angled planks >=24 mm will cause reinforcement
  if tblGroInfo.sidey2<0.0155 or (tblGroInfo.sidey2<0.0235 and math.abs(plankInfo.vecx.z)>0.05) then
    return nil
  end

  -- Extend 200 mm projected to horizontal
  extend=0.2
  tbl={}
  tbl.x1=tblGroInfo.sidex1
  tbl.x2=tblGroInfo.sidex2
  tbl.groInfo=tblGroInfo
  tblGro.groInfo=tblGroInfo

  cosTilt=math.sqrt(plankInfo.vecx.x*plankInfo.vecx.x + plankInfo.vecx.y*plankInfo.vecx.y)
  if cosTilt>0.01 then
    local s, dy, height

    tanTilt=plankInfo.vecx.z/cosTilt
    height=plankInfo.height
    s,dy=GetReinforceCode(height)
    
    tbl.x1=tbl.x1+(height-dy)*0.5*tanTilt-extend/cosTilt
    tbl.x2=tbl.x2+(height-dy)*0.5*tanTilt+extend/cosTilt

    if tanTilt<0 then
      -- Need to extend beg
      tbl.x1=tbl.x1+dy*tanTilt
    else
      tbl.x2=tbl.x2+dy*tanTilt
    end
  end

  -- Extend to the end if close enough
  if tbl.x1<0.5005 then
    tbl.x1=0
  end
  if tbl.x2>plankInfo.len-0.5005 then
    tbl.x2=plankInfo.len
  end

--ac_environment("tolog", string.format("tbl.x1=%f tbl.x2=%f len=%f", tbl.x1, tbl.x2, plankInfo.len))
  if tbl.x1<0 then
    tbl.x1=0
  end
  if tbl.x2>plankInfo.len then
    tbl.x2=plankInfo.len
  end

  len2=(RoundLen(tbl.x2-tbl.x1)-(tbl.x2-tbl.x1))*0.5
  add1=len2
  add2=len2
  if tbl.x1<add1 then
    add2=add2+add1-tbl.x1
  end
  if plankInfo.len-tbl.x2<add2 then
    add1=add1+add2-(plankInfo.len-tbl.x2)
    if tbl.x1<add1 then
      add1=tbl.x1
    end
  end
  tbl.x1=tbl.x1-add1
  tbl.x2=tbl.x2+add2

  tblGro.extbeg=add1
  tblGro.extend=add2

  return tbl
end


-- Creates reinforce with given values
-- tbl contains just fields x1, x2
-- Returns table of the new mc[16], row to next mc
function CreateReinforce(plankInfo, tbl, row)
  local height, s, dy, mat, i, x, tblRes

  height=plankInfo.height
  s,dy=GetReinforceCode(height)

  mat=ac_environment("findattr", 6, "*tre-osb*")
  if mat==nil then
    mat=1
  end

  -- New reinforement
  ac_objectset("iMc", 304, row, 1)
  ac_objectset("iMc", (tbl.x1+tbl.x2)*0.5, row, 2)
  ac_objectset("iMc", plankInfo.height*0.5, row, 3)
  ac_objectset("iMc", tbl.x2-tbl.x1, row, 4)
  ac_objectset("iMc", dy, row, 5)
  ac_objectset("iMc", 0.018, row, 6)
  ac_objectset("iMc", 2, row, 7)
  ac_objectset("iMc", 1, row, 8)
  ac_objectset("iMc", 1, row, 9)
  ac_objectset("iMc", mat, row, 10)
  ac_objectset("iMc", 0, row, 11)
  ac_objectset("iMc", 1, row, 12)   -- Flag as automation created
  ac_objectset("iMc", 0, row, 13)
  ac_objectset("iMc", 0, row, 14)
  ac_objectset("iMc", 0, row, 15)
  ac_objectset("iMcStr", s, row)

  tblRes={}
  tblRes.index=row
  for i=1,16 do
    tblRes[i]=ac_objectget("iMc", row, i)
  end
  return tblRes, row+1
end


-- extraLen How much the reinforcement has been extended to match next stock length
-- Returns next mc row
function AddNailGroup( plankInfo, tblNail, nDir, cosTilt, tanTilt, dyReinforce, x, y, row, extraLen )
  local i, angleX, x1, x2, xOld, xbot
  
  if nDir>0 then
    angleX=0
    x1=x
    x2=x+0.150/cosTilt
  else
    angleX=180
    x1=x-0.150/cosTilt
    x2=x
  end
  
  -- Check if already covered
  for i=1,tblNail.count do
    if tblNail[i]~=nil then
      xOld=tblNail[i][2]
      if xOld>x1 and xOld<x2 then
        -- (Non-automatic) Nailing exists on nailing, forget
        return row
      end
    end
  end

  -- Let ArchiFrame clean up nails outside the plank
  ac_objectset("iMc", 306, row, 1)
  ac_objectset("iMc", x, row, 2)     -- x1
  ac_objectset("iMc", y, row, 3)       -- y1
  ac_objectset("iMc", 3, row, 4)        -- cols
  ac_objectset("iMc", 5, row, 5)        -- rows
  ac_objectset("iMc", angleX, row, 6)        -- anglex
  ac_objectset("iMc", 90-math.atan2(plankInfo.vecx.z,cosTilt)/gDegToRad, row, 7)        -- angley
  ac_objectset("iMc", 0.025/cosTilt, row, 8)        -- spacingx
  ac_objectset("iMc", 0.25*(dyReinforce-0.050)/cosTilt, row, 9)        -- spacingy
  ac_objectset("iMc", 3, row, 10)       -- flags, both sides+automatic
  ac_objectset("iMc", 2, row, 11)       -- side
  row=row+1
    
  -- Two nails further. Actually add as two separate nailings to have 25 mm gap vertically from end.
  -- Lower
  x=x+nDir*0.150/cosTilt
  xbot=x
  if (nDir>0 and tanTilt>0) or (nDir<0 and tanTilt<0) then
    -- Forward
    xbot=x+(dyReinforce-0.050)*math.abs(tanTilt)*nDir
  end
  xbot=xbot+nDir*extraLen

  ac_objectset("iMc", 306, row, 1)
  ac_objectset("iMc", xbot, row, 2)     -- x1
  ac_objectset("iMc", y, row, 3)        -- y1
  ac_objectset("iMc", 1, row, 4)        -- cols
  ac_objectset("iMc", 2, row, 5)        -- rows
  ac_objectset("iMc", angleX, row, 6)        -- anglex
  ac_objectset("iMc", 90, row, 7)        -- angley
  ac_objectset("iMc", 0.025/cosTilt, row, 8)        -- spacingx
  ac_objectset("iMc", dyReinforce-0.050, row, 9)        -- spacingy
  ac_objectset("iMc", 3, row, 10)       -- flags, both sides+automatic
  ac_objectset("iMc", 2, row, 11)       -- side
  row=row+1

  return row
end

-- Creates reinforce for given groove and also the related nail groups
-- tblNail: Existing nail groups
-- row, where to save next mc
-- Returns row to next mc
function CreateNails(plankInfo, tblGro, tblNail, row)
  local height, s, dy, mat, x
  
  if tblGro.groInfo==nil then
    return row
  end

  height=plankInfo.height
  s,dy=GetReinforceCode(height)

  -- Add nailings. Find x1&x2 coordinates at plank's bottom
  local y1, x1, x2, cosTilt, tanTilt
  
  cosTilt=math.sqrt(plankInfo.vecx.x*plankInfo.vecx.x + plankInfo.vecx.y*plankInfo.vecx.y)
  if cosTilt<0.01 then
    return row
  end
  tanTilt=plankInfo.vecx.z/cosTilt

  x1=99999
  x2=-99999
  if tblGro.groInfo.projside1.linebot.y1<0.001 then
    x1=math.min(x1, tblGro.groInfo.projside1.linebot.x1)
    x2=math.max(x2, tblGro.groInfo.projside1.linebot.x1)
  end
  if tblGro.groInfo.projside1.linebot.y2<0.001 then
    x1=math.min(x1, tblGro.groInfo.projside1.linebot.x2)
    x2=math.max(x2, tblGro.groInfo.projside1.linebot.x2)
  end

  if tblGro.groInfo.projside1.lineref.len>0 then
    if tblGro.groInfo.projside1.lineref.y1<0.001 then
      x1=math.min(x1, tblGro.groInfo.projside1.lineref.x1)
      x2=math.max(x2, tblGro.groInfo.projside1.lineref.x1)
    end
    if tblGro.groInfo.projside1.lineref.y2<0.001 then
      x1=math.min(x1, tblGro.groInfo.projside1.lineref.x2)
      x2=math.max(x2, tblGro.groInfo.projside1.lineref.x2)
    end
  end

  if tblGro.groInfo.projside1.lineother.len>0 then
    if tblGro.groInfo.projside1.lineother.y1<0.001 then
      x1=math.min(x1, tblGro.groInfo.projside1.lineother.x1)
      x2=math.max(x2, tblGro.groInfo.projside1.lineother.x1)
    end
    if tblGro.groInfo.projside1.lineother.y2<0.001 then
      x1=math.min(x1, tblGro.groInfo.projside1.lineother.x2)
      x2=math.max(x2, tblGro.groInfo.projside1.lineother.x2)
    end
  end
  
  y1=(plankInfo.height-dy)*0.5 + 0.025
  x=x1-(0.025/cosTilt-y1*tanTilt)
  if x>0.080 then
    if tblGro.extbeg==nil then
      tblGro.extbeg=0
    end
    row=AddNailGroup( plankInfo, tblNail, -1, cosTilt, tanTilt, dy, x, y1, row, tblGro.extbeg )
  end

  x=x2+(0.025/cosTilt+y1*tanTilt)
  if x<plankInfo.len-0.080 then
    if tblGro.extend==nil then
      tblGro.extend=0
    end
    row=AddNailGroup( plankInfo, tblNail, 1, cosTilt, tanTilt, dy, x, y1, row, tblGro.extend )
  end

  return row
end


-- Adds automatic reinforcement to table.
-- tbl contains just fields x1, x2
function AddToAutoTbl(tblReinforceAuto, tblNew)
  local i2
  -- Join to existing
  for i2=1,tblReinforceAuto.count do
    if tblReinforceAuto[i2] and (tblNew.x1-0.001<tblReinforceAuto[i2].x2 and tblNew.x2+0.001>tblReinforceAuto[i2].x1) then
      -- Join with existing one and continue joining with other parts
      tblNew.x1=math.min(tblNew.x1, tblReinforceAuto[i2].x1)
      tblNew.x2=math.max(tblNew.x2, tblReinforceAuto[i2].x2)
      tblReinforceAuto[i2]=nil
    end
  end

  tblReinforceAuto.count=tblReinforceAuto.count+1
  tblReinforceAuto[tblReinforceAuto.count]=tblNew
end


-- nSgn 1=begin, -1=end
function CalcBegEndGroDist(plankInfo, tblGroMcs, nSgn)
  local i, maxDist, nSide

  maxDist=0      -- How much further we need to go from begin
  nSide=5
  if nSgn<0 then
    nSide=6
  end

  for i=1,tblGroMcs.count do
    tblNums=tblGroMcs[i]
    if tblNums[9]==nSide then
      -- Groove at begin surface, get its geometry
        local tblGroInfo, tblGro, x1, x2, cosTilt
      
        tblGro={}
        tblGro.guid = plankInfo.ptr
        tblGro.x1   = tblNums[2]
        tblGro.y1   = tblNums[3]
        tblGro.x2   = tblNums[4]
        tblGro.y2   = tblNums[5]
        tblGro.depth    = tblNums[6]
        tblGro.width    = tblNums[7]
        tblGro.groAngleRad  = tblNums[8]*gDegToRad
        tblGro.face         = tblNums[9]
        tblGro.groTiltAngleRad  = tblNums[10]*gDegToRad

        tblGroInfo = af_request("mc_getgroinfo", tblGro)
--DumpTbl(tblGro)
--DumpTbl(tblGroInfo)
      
      x1=tblGro.depth*tblGroInfo.vecDown.x*nSgn
      x2=x1+tblGro.width*tblGroInfo.vecLeft.x*nSgn
      if x2>x1 then
        x1=x2
      end

      cosTilt=math.cos(tblGro.groTiltAngleRad)
      if math.abs(tblGro.groTiltAngleRad)>0.1 then
        -- Use projected coordinates, x2=distance from end
        if tblGroInfo.projside1.linebot.len>0 then
          if nSgn>0 then
            x2=math.max(tblGroInfo.projside1.linebot.x1, tblGroInfo.projside1.linebot.x2, tblGroInfo.projside2.linebot.x1, tblGroInfo.projside2.linebot.x2)
          else
            x2=math.min(tblGroInfo.projside1.linebot.x1, tblGroInfo.projside1.linebot.x2, tblGroInfo.projside2.linebot.x1, tblGroInfo.projside2.linebot.x2)
            x2=plankInfo.len-x2
          end

          if x2>x1 then
            x1=x2
          end
        end
      end

      if x1>maxDist then
        maxDist=x1
      end
    end
  end
  
  return maxDist
end


function RoundLen(len)
  if len<0.401 then
    return 0.400
  end
  
  if len<0.601 then
    return 0.600
  end

  if len<0.801 then
    return 0.800
  end

  if len<1.201 then
    return 1.200
  end

  if len<1.501 then
    return 1.500
  end
  
  return len
end


-- Returns reinforcement needed for begin, creates the nails already
function DoBeg(plankInfo, tblNail, row, tblGroMcs)
  local tbl, sCode, dy, cosTilt, tanTilt, tblNums
  local extend, x, y, groDist, extraLen

  sCode,dy=GetReinforceCode(plankInfo.height)
  
  tbl={}
  tbl.xmid=1
  tbl.width=2
  tbl.ymid=plankInfo.height*0.5  
  tbl.height=dy
  tbl.thickness=0.010
  tbl.side=2
  tbl.bothsides=1
  tbl.begend=-1
  x,y=af_request("mc_reinforcecalcsupport", tbl)

  -- Extend 25 + 200 mm projected to horizontal
  extend=0.225
  tbl={}
  tbl.x1=0
  tbl.x2=x

  cosTilt=math.sqrt(plankInfo.vecx.x*plankInfo.vecx.x + plankInfo.vecx.y*plankInfo.vecx.y)
  if cosTilt<0.01 then
    return nil
  end

  -- Check if grooves at begin (for the I-steel beams)
  groDist=CalcBegEndGroDist(plankInfo, tblGroMcs, 1)
--ac_environment( "tolog", string.format("BEG: x=%f groDist%f", x, groDist) )

  tbl.x2=tbl.x2+extend/cosTilt+groDist
  tanTilt=plankInfo.vecx.z/cosTilt
  if tanTilt>0 then
    tbl.x2=tbl.x2+dy*tanTilt
  else
    -- Move nailings forward if needed
    local minx

    minx=-(dy-0.025)*tanTilt
    if x<minx then
      tbl.x2=tbl.x2+minx-x
      x=minx
    end
  end
  
  extraLen=RoundLen(tbl.x2)-tbl.x2
  if tbl.x2+extraLen>plankInfo.len then
    extraLen=plankInfo.len-tbl.x2
  end
  tbl.x2=tbl.x2+extraLen

  -- Nails
  y1=(plankInfo.height-dy)*0.5 + 0.025
  x=x+0.025/cosTilt+0.025*tanTilt+groDist
  row=AddNailGroup( plankInfo, tblNail, 1, cosTilt, tanTilt, dy, x, y1, row, extraLen )

  return tbl, row
end


-- Returns reinforcement needed for end, creates the nails already
function DoEnd(plankInfo, tblNail, row, tblGroMcs)
  local tbl, sCode, dy, cosTilt, tanTilt, groDist
  local extend, x, y, extraLen

  sCode,dy=GetReinforceCode(plankInfo.height)
  
  tbl={}
  tbl.xmid=plankInfo.len-1
  tbl.width=2
  tbl.ymid=plankInfo.height*0.5  
  tbl.height=dy
  tbl.thickness=0.010
  tbl.side=2
  tbl.bothsides=1
  tbl.begend=1
  x,y=af_request("mc_reinforcecalcsupport", tbl)

  -- Extend 25 + 200 mm projected to horizontal
  extend=0.225
  tbl={}
  tbl.x1=x
  tbl.x2=plankInfo.len
 
  cosTilt=math.sqrt(plankInfo.vecx.x*plankInfo.vecx.x + plankInfo.vecx.y*plankInfo.vecx.y)
  if cosTilt<0.01 then
    return nil
  end

  -- Check if grooves at begin (for the I-steel beams)
  groDist=CalcBegEndGroDist(plankInfo, tblGroMcs, -1)
--ac_environment( "tolog", string.format("END: plankInfo.len-x=%f groDist%f", plankInfo.len-x, groDist) )
  x=x

  tbl.x1=tbl.x1-extend/cosTilt-groDist
  tanTilt=plankInfo.vecx.z/cosTilt
  if tanTilt<0 then
    tbl.x1=tbl.x1+dy*tanTilt
  else
    -- Move nailings forward if needed
    local minx

    minx=(dy-0.025)*tanTilt
    if plankInfo.len-x<minx then
      tbl.x1=tbl.x1-(minx-(plankInfo.len-x))
      x=plankInfo.len-minx
    end
  end
  
  extraLen=RoundLen(tbl.x2-tbl.x1)-(tbl.x2-tbl.x1)
  if tbl.x1-extraLen<0 then
    extraLen=tbl.x1
  end
  tbl.x1=tbl.x1-extraLen

  -- Nails
  y1=(plankInfo.height-dy)*0.5 + 0.025
  x=x-0.025/cosTilt+0.025*tanTilt-groDist
  row=AddNailGroup( plankInfo, tblNail, -1, cosTilt, tanTilt, dy, x, y1, row, extraLen )

  return tbl, row
end


function Len2Str(len)
  return ac_environment("ntos", len, "length", "dim")
end


-- Generates info text for current piece (similar functions in ArchiFrameBlocks.xml and ArchiFrameElements.xml)
function GetInfoText(plankinfo, bCladding)
  local i, count, res, mc, nUnknown
  local lang
  
  lang=GetLang()
  res=""
  count=ac_objectget("iMc",-1)
  nUnknown=0
  for i=1,count do
    mc=ac_objectget("iMc", i, 1)
    if mc==301 and not bCladding then
      -- Groove
      local side, x1, x2, y1, y2, width, angleDeg, tiltDeg, groType

      x1=ac_objectget("iMc", i, 2)
      y1=ac_objectget("iMc", i, 3)
      x2=ac_objectget("iMc", i, 4)
      y2=ac_objectget("iMc", i, 5)
      depth=ac_objectget("iMc", i, 6)
      width=ac_objectget("iMc", i, 7)
      angleDeg=ac_objectget("iMc", i, 8)
      side=ac_objectget("iMc", i, 9)
      tiltDeg=ac_objectget("iMc", i, 10)
      groType=ac_objectget("iMc", i, 11)

        if (side==5 or side==6) and groType==0 and angleDeg==0 and tiltDeg==0 and x1<EPS and x2>plankinfo.width-EPS and math.abs(y2-y1)<EPS then
            -- Move gro to top/bottom if possible
            if y1<EPS or y1+width+EPS>plankinfo.height then
                local orgSide, depthOrg

                orgSide=side
          depthOrg=depth
                if y1<EPS then
                    side=3
                else
                    side=1
                end
                if orgSide==5 then
                    x1=depth
                else
                    x1=plankinfo.len
                end
                x2=x1
                y1=0
                y2=plankinfo.width
                depth=width
                width=depthOrg
            end
        end

      if (side==3 or side==1) and groType==0 and angleDeg==0 and tiltDeg==0 and y1<EPS and y2>plankinfo.width-EPS and math.abs(x2-x1)<EPS then
        local distBot, distTop, s
        
        distBot=x1-width
        distTop=plankinfo.len-x1

        if res~="" then
          res=res .. ", "
        end
        
        if math.abs(distBot)<0.0004 then
          distBot=0
        end
        if math.abs(distTop)<0.0004 then
          distTop=0
        end

        if plankinfo.vecx.z>0.999 then
          s="front"
          if side==1 then
            s="back"
          end
          if lang=="fin" then
            s="etu"
            if side==1 then
              s="taka"
            end
          end
        else
          s="bottom"
          if side==1 then
            s="top"
          end
          if lang=="fin" then
            s="ala"
            if side==1 then
              s="ylä"
            end
          end
        end

        if math.abs(distBot)<math.abs(distTop) then
          if plankinfo.vecx.z>0.99 then
            if lang=="fin" then
              s=string.format("Lovi %s %sx%s ar:sta %s", s, Len2Str(depth), Len2Str(width), Len2Str(distBot))
            else
              s=string.format("Slot %s %sx%s from bot %s", s, Len2Str(depth), Len2Str(width), Len2Str(distBot))
            end
          else
            if lang=="fin" then
              s=string.format("Lovi %s %sx%s alusta %s", s, Len2Str(depth), Len2Str(width), Len2Str(distBot))
            else
              s=string.format("Slot %s %sx%s from begin %s", s, Len2Str(depth), Len2Str(width), Len2Str(distBot))
            end
          end
        else
          if plankinfo.vecx.z>0.99 then
            if lang=="fin" then
              s=string.format("Lovi %s %sx%s yr:sta %s", s, Len2Str(depth), Len2Str(width), Len2Str(distTop))
            else
              s=string.format("Slot %s %sx%s from top %s", s, Len2Str(depth), Len2Str(width), Len2Str(distTop))
            end
          else
            if lang=="fin" then
              s=string.format("Lovi %s %sx%s lopusta %s", s, Len2Str(depth), Len2Str(width), Len2Str(distTop))
            else
              s=string.format("Slot %s %sx%s from end %s", s, Len2Str(depth), Len2Str(width), Len2Str(distTop))
            end
          end
        end
        res=res .. s
      else
        nUnknown=nUnknown+1
      end
    elseif mc==101 or mc==201 then
      -- Cut beg/end
      local a1, a2, fmt
      
      a1=ac_objectget("iMc", i, 2)
      a2=ac_objectget("iMc", i, 3)
      fmt="Angled beg"
      if mc==201 then
        fmt="Angled end"
      end
      if lang=="fin" then
        fmt="Viiste alku"
        if mc==201 then
          fmt="Viiste loppu"
        end
      end
      

      if res~="" then
        res=res .. ", "
      end
      if math.abs(a1-90)>0.4 and math.abs(a2-90)<0.4 then
        s=string.format("%s %.0f°", fmt, math.abs(a1-90))
      elseif math.abs(a1-90)<0.4 and math.abs(a2-90)>0.4 then
        if lang=="fin" then
          s=string.format("%s korksuunnassa %.1f°", fmt, math.abs(a2-90))
        else
          s=string.format("%s in height dir %.1f°", fmt, math.abs(a2-90))
        end
      else
        if lang=="fin" then
          s=string.format("%s kahteen suuntaan, katso ohje", fmt)
        else
          s=string.format("%s double angled, see detail", fmt)
        end
      end
      res=res .. s
      
    elseif mc==305 then
      -- Lengthwise cut
      local side, x1, width, depth, yoff, angle_c, angle_d, handled, w2, depth, height, plankInfo
      
      side=ac_objectget("iMc", i, 2)
      x1=ac_objectget("iMc", i, 3)
      width=ac_objectget("iMc", i, 4)
      depth=ac_objectget("iMc", i, 5)
      yoff=ac_objectget("iMc", i, 6)
      angle_c=ac_objectget("iMc", i, 7)
      angle_d=ac_objectget("iMc", i, 8)

--ac_environment("tolog", string.format("x1=%f width=%f depth=%f yoff=%f angle_c=%f angle_d=%f", x1, width, depth, yoff, angle_c, angle_d))
      w2=plankinfo.height*0.5
      if x1<0.001 and width<0.001 and math.abs(depth)<0.001 and (side==2 or side==4) then
        if angle_c>0 and math.abs(angle_d)<0.1 then
          -- Top of the surface cut
          -- 0.017453292=PI/180
          depth=w2-yoff
              height=depth*math.tan(angle_c*0.017453292)
        elseif angle_d>0 and math.abs(angle_c)<0.1 then
          -- Bottom of the surface cut
          depth=w2+yoff
              height=depth*math.tan(angle_d*0.017453292)
        end
        
            plankInfo=af_request("plankinfo")
        if depth>0 and height>0 and depth<plankInfo.height and height<plankInfo.width then
              if res~="" then
                  res=res .. ", "
              end
          if lang=="fin" then
            s=string.format("viiste %sx%s", Len2Str(depth), Len2Str(height))
          else
            s=string.format("lengthwise cut %sx%s", Len2Str(depth), Len2Str(height))
          end
              res=res .. s
              handled=true
        end
        end
      
      if not handled then
        nUnknown=nUnknown+1
      end
    elseif mc>0 then
        -- Do not calculate as unknown: EMcMarking = 303, EMcNailGroup = 306, EMcNailLine = 307, EMetalShoeEnd = 1000, EMetalHobaFix = 1001
        if mc~=303 and mc~=306 and mc~=307 and mc~=1000 and mc~=1001 then
          nUnknown=nUnknown+1
        end
    end
  end
  
  if nUnknown>0 and not bCladding then
    if res~="" then
      res=res .. ", "
    end
    if lang=="fin" then
      s=string.format("muita työstöjä %d kpl - katso ohje", nUnknown)
    else
      s=string.format("other cuts %d pcs - see detail", nUnknown)
    end
    res=res .. s
  end
  return res
end


function SetCalcPars()
  local t, s, s2
  
  t=af_request("plankinfo")
  if not t then
    return
  end
  if t.matname then   -- Missing of old prog version?
    s=ac_objectget("iMatName")
--ac_environment("tolog", string.format("s=%s, t.matname=%s", s, t.matname))
    if s and s~=t.matname then
      ac_objectset("iMatName", t.matname)
    end
  end

  -- Machinings text
  s=ac_objectget("iMachiningText")
  s2=GetInfoText(t)
  if s and s2 and s~=s2 then
--ac_environment("tolog", string.format("s=%s, s2=%s", s, s2))
    ac_objectset("iMachiningText", s2)
  end
end


function OpenObj(sGuid)
  ac_objectopen(sGuid)
end

-- Called just before the plank is saved just after normal cleanup only for master planks (no 2D projections handled here). sGuid is in @ptr form
-- nCode  1=new plank, 2=edit old
-- Return value: 0=no change, 1=changed - do cleanup
function OnPostClean( sGuid, nCode )
  local row, rows, col, cols, mc, tblGro, tblReinforce, tblReinforceAuto, tblNail, guid, s, tbl, doBeg, doEnd, doGro, forceRefresh, plankInfo

  --ac_objectopen(sGuid)
  row, s=pcall(OpenObj, sGuid)   -- Silent fail
  if not row then
    return 0
  end
  s=ac_objectget("iMatId")

--ac_environment("tolog", string.format("OnPreSave( %s, %d ), guid=%s", sGuid, nCode, ac_objectget("#guid")))

  SetCalcPars()   -- Added 1/2020

  rows=ac_objectget("iMc", -1)
  if rows==1 then
    -- Bail out if no mcs
    ac_objectclose()
    return 0
  end

  -- Birkeland uses the settings from bits 0...3, the common version uses from 10...13
  row=ac_objectget("iFlagsCustom")
  if row==nil then
    -- Bail out if old library
    ac_objectclose()
    return 0
  end
  doBeg=ac_environment("bittest", row, 10)
  doEnd=ac_environment("bittest", row, 11)
  doGro=ac_environment("bittest", row, 12)      -- Default is off for general use
  
  forceRefresh=false
  if ac_environment("bittest", row, 13)==1 then
    forceRefresh=true
    ac_objectset("iFlagsCustom", row-8192)
  end

  if doBeg+doEnd+doGro==0 then
    -- No automation
    ac_objectclose()
    return 0
  end

  tblGro={}
  tblGro.count=0
  tblReinforce={}
  tblReinforce.count=0
  tblReinforceAuto={}
  tblReinforceAuto.count=0
  tblNail={}
  tblNail.count=0
  
  plankInfo=af_request("plankinfo")
  
  for row=1,rows do
    mc=ac_objectget("iMc", row, 1)
    if mc==301 then
      -- Groove
      tblGro.count=tblGro.count+1
      tblGro[tblGro.count]=GetMcRow(row)
    elseif mc==304 then
      -- Reinforce
      tbl=GetMcRow(row)
      if ac_environment("bittest", tbl[12], 0)==1 then
        tblReinforceAuto.count=tblReinforceAuto.count+1
        tblReinforceAuto[tblReinforceAuto.count]=tbl
      else
        tblReinforce.count=tblReinforce.count+1
        tblReinforce[tblReinforce.count]=tbl
      end
    elseif mc==306 then
      -- Nail group
      tblNail.count=tblNail.count+1
      tblNail[tblNail.count]=GetMcRow(row)
    end
  end
  guid=ac_objectget("#guid")
  ac_objectclose()
  
  local nChangedGro

  nChangedGro=tblGro.count
  if nCode==2 then
    -- Edit old - open previous version and set all mcs similar to old one to nil
    local tbl, scan, found

    ac_objectopen(">" .. guid)
    rows=ac_objectget("iMc", -1)
    
    for row=1,rows do
      mc=ac_objectget("iMc", row, 1)
      if mc==301 then
        -- Groove
        tbl=GetMcRow(row)
        found=false
        for scan=1,tblGro.count do
          if IsSameMc(tbl, tblGro[scan]) then
            nChangedGro=nChangedGro-1
            found=true
            break
          end
        end
        
        if not found then
          nChangedGro=nChangedGro+1000
        end
      end
    end

    if doGro~=ac_environment("bittest", ac_objectget("iFlagsCustom"), 12) then
      -- Changed from off to on, recreate
      nChangedGro=nChangedGro+1000
    end

    ac_objectclose()
  end

  local nRes

  nRes=0
  if (doGro==1 and (nChangedGro~=0 or forceRefresh)) or doBeg==1 or doEnd==1 then
    -- Changes in grooves or automatic begin and end, recreate all automatic reinforcements
    local i1, i2, found, x1, x2, row

    ac_objectopen(sGuid)
    
    -- Delete every existing automatic reinforcement
    for i1=1,tblReinforceAuto.count do
      ac_objectset("iMc", 0, tblReinforceAuto[i1].index, 1)
    end

    -- The same for the nailing groups
    for i1=1,tblNail.count do
      if ac_environment("bittest", tblNail[i1][10], 1)==1 then
        -- Automatic nail (bit1)
        ac_objectset("iMc", 0, tblNail[i1].index, 1)
        tblNail[i1]=nil
      end
    end

    tblReinforceAuto={}
    tblReinforceAuto.count=0

    row=ac_objectget("iMc", -1)
    if ac_objectget("iMc", row, 1)~=0 then
      row=row+1
    end

    if doGro==1 then
      -- Create new ones GRO
      for i1=1,tblGro.count do
        tbl=AddReinforce(plankInfo, tblGro[i1])
        if tbl then
          AddToAutoTbl(tblReinforceAuto, tbl)
        end
      end
      
      -- Nails for grooves
      for i1=1,tblGro.count do
        row=CreateNails(plankInfo, tblGro[i1], tblNail, row)
      end
    end

    if doBeg==1 then
      tbl,row=DoBeg(plankInfo, tblNail, row, tblGro)
      AddToAutoTbl(tblReinforceAuto, tbl)
    end

    if doEnd==1 then
      tbl,row=DoEnd(plankInfo, tblNail, row, tblGro)
      AddToAutoTbl(tblReinforceAuto, tbl)
    end

    -- Create mcs
    -- Create automatic reinforcements
    for i1=1,tblReinforceAuto.count do
      -- Combine with existing non-automatic ones
      tbl=tblReinforceAuto[i1]
      if tbl~=nil then
        for i2=1,tblReinforce.count do
          x2=tblReinforce[i2][4]
          x1=tblReinforce[i2][2]-x2*0.5
          x2=x1+x2
          if tbl.x1-0.001<x2 and tbl.x2+0.001>x1 then
            x1=math.min(x1,tbl.x1)
            x2=math.max(x2,tbl.x2)
            tblReinforce[i2][2]=(x1+x2)*0.5
            tblReinforce[i2][4]=x2-x1
            ac_objectset("iMc", tblReinforce[i2][2], tblReinforce[i2].index, 2)     -- mid
            ac_objectset("iMc", tblReinforce[i2][4], tblReinforce[i2].index, 4)     -- width
            tbl=nil
            break
          end
        end
        
        if tbl then
          local tblAdded
            
          tblAdded, row=CreateReinforce(plankInfo, tbl, row)
          -- Add to current reinforcement tbl to work with begin and end, not needed actually
          --tblReinforce.count=tblReinforce.count+1
          --tblReinforce[tblReinforce.count]=tblAdded
        end
      end
    end

    ac_objectclose()
    nRes=1
  end

  return nRes
end
]]>
  </observer>

  <materials>

    <!--
        shape must be specified block/plane/round even if custom profile is given
        m3factor is the coefficient factor to get m3-quantity from the material. If you omit it, default formula will be used.
    -->

    <material id="block" name="Block" thickness="0.000" height="0.000" shape="block">
    </material>

    <material id="plane" name="Plane" thickness="0.000" height="0.000" shape="plane">
    </material>

    <material id="round" name="Round" thickness="0.000" height="0.000" shape="round">
    </material>

    <material id="22x50" name="22x50" thickness="0.022" height="0.050" shape="block" maxlen="99" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="22x100" name="22x100" thickness="0.022" height="0.100" shape="block" maxlen="99" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="42x42" name="42x42" thickness="0.042" height="0.042" shape="block" maxlen="99" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="42x73" name="42x73" thickness="0.042" height="0.073" shape="block" maxlen="6" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="42x98" name="42x98" thickness="0.042" height="0.098" shape="block" maxlen="6" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="42x123" name="42x123" thickness="0.042" height="0.123" shape="block" maxlen="6" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="42x148" name="42x148" thickness="0.042" height="0.148" shape="block" maxlen="6" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="42x173" name="42x173" thickness="0.042" height="0.173" shape="block" maxlen="6" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="42x198" name="42x198" thickness="0.042" height="0.198" shape="block" maxlen="6" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="42x198 C24" name="42x198 C24" thickness="0.042" height="0.198" shape="block" maxlen="6" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="42x220" name="42x220" thickness="0.042" height="0.220" shape="block" maxlen="10" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="48x40" name="48x40" thickness="0.048" height="0.040" shape="block" maxlen="6" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="48x48" name="48x48" thickness="0.048" height="0.048" shape="block" maxlen="6" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="48x73" name="48x73" thickness="0.048" height="0.073" shape="block" maxlen="6" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="48x98" name="48x98" thickness="0.048" height="0.098" shape="block" maxlen="6" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="48x123" name="48x123" thickness="0.048" height="0.123" shape="block" maxlen="6" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="48x148" name="48x148" thickness="0.048" height="0.148" shape="block" maxlen="6" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="48x173" name="48x173" thickness="0.048" height="0.173" shape="block" maxlen="6" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="48x198" name="48x198" thickness="0.048" height="0.198" shape="block" maxlen="6" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="48x220" name="48x220" thickness="0.048" height="0.220" shape="block" maxlen="10" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="KP 39x66" name="KP 39x66" thickness="0.039" height="0.066" shape="block" maxlen="6" m3factor="0.000" excel_quality="C22" excel_type="KERTO">
    </material>

    <material id="KP 39x92" name="KP 39x92" thickness="0.039" height="0.092" shape="block" maxlen="6" m3factor="0.000" excel_quality="C22" excel_type="KERTO">
    </material>

    <material id="KP 45x200" name="KP 45x200" thickness="0.045" height="0.200" shape="block" maxlen="12" m3factor="0.000" excel_quality="C22" excel_type="KERTO">
    </material>

    <material id="KP 45x300" name="KP 45x300" thickness="0.045" height="0.300" shape="block" maxlen="6" m3factor="0.000" excel_quality="C22" excel_type="KERTO">
    </material>

    <material id="LP 90x225" name="LP 90x225" thickness="0.090" height="0.225" shape="block" maxlen="99" m3factor="0.000" excel_quality="C22" excel_type="GL">
    </material>

    <material id="LP 90x270" name="LP 90x270" thickness="0.090" height="0.270" shape="block" maxlen="99" m3factor="0.000" excel_quality="C22" excel_type="GL">
    </material>

    <material id="LP 90x315" name="LP 90x315" thickness="0.090" height="0.315" shape="block" maxlen="99" m3factor="0.000" excel_quality="C22" excel_type="GL">
    </material>

    <material id="LP 90x360" name="LP 90x360" thickness="0.090" height="0.360" shape="block" maxlen="99" m3factor="0.000" excel_quality="C22" excel_type="GL">
    </material>

    <material id="LP 115x225" name="LP 115x225" thickness="0.115" height="0.225" shape="block" maxlen="99" m3factor="0.000" excel_quality="C22" excel_type="GL">
    </material>

    <material id="LP 115x270" name="LP 115x270" thickness="0.115" height="0.270" shape="block" maxlen="99" m3factor="0.000" excel_quality="C22" excel_type="GL">
    </material>

    <material id="LP 115x315" name="LP 115x315" thickness="0.115" height="0.315" shape="block" maxlen="99" m3factor="0.000" excel_quality="C22" excel_type="GL">
    </material>

    <material id="LP 115x360" name="LP 115x360" thickness="0.115" height="0.360" shape="block" maxlen="99" m3factor="0.000" excel_quality="C22" excel_type="GL">
    </material>

    <material id="LP 115x405" name="LP 115x405" thickness="0.115" height="0.405" shape="block" maxlen="99" m3factor="0.000" excel_quality="C22" excel_type="GL">
    </material>

    <material id="LP 140x225" name="LP 140x225" thickness="0.140" height="0.225" shape="block" maxlen="99" m3factor="0.000" excel_quality="C22" excel_type="GL">
    </material>

    <material id="LP 140x270" name="LP 140x270" thickness="0.140" height="0.270" shape="block" maxlen="99" m3factor="0.000" excel_quality="C22" excel_type="GL">
    </material>

    <material id="LP 140x315" name="LP 140x315" thickness="0.140" height="0.315" shape="block" maxlen="99" m3factor="0.000" excel_quality="C22" excel_type="GL">
    </material>

    <material id="LP 140x360" name="LP 140x360" thickness="0.140" height="0.360" shape="block" maxlen="99" m3factor="0.000" excel_quality="C22" excel_type="GL">
    </material>

    <material id="LP 140x405" name="LP 140x405" thickness="0.140" height="0.405" shape="block" maxlen="99" m3factor="0.000" excel_quality="C22" excel_type="GL">
    </material>

    <material id="50x50" name="50x50" thickness="0.050" height="0.050" shape="block" maxlen="6" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="50x100" name="50x100" thickness="0.050" height="0.100" shape="block" maxlen="6" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="20x50" name="20x50" thickness="0.020" height="0.050" shape="block" maxlen="99" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="20x70" name="20x70" thickness="0.020" height="0.070" shape="block" maxlen="99" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="32x100" name="32x100" thickness="0.032" height="0.100" shape="block" maxlen="6" m3factor="0.000" excel_quality="" excel_type="">
    </material>

    <material id="I 300" name="I 300" thickness="0.047" height="0.300" shape="block" maxlen="6" m3factor="0.000" excel_quality="" excel_type="">
      <settings>
        <plankdefaults>
          <objparam name="iPenMid">1</objparam>
          <objparam name="iLineMid">*dash*|*katko*</objparam>
          <objparam name="iColLines">0</objparam>
        </plankdefaults>
      </settings>
      <profile>
        <point xym="-0.02350000 0.00000000 15"></point>
        <point xym="0.02350000 0.00000000 15"></point>
        <point xym="0.02350000 0.04700000 15"></point>
        <point xym="0.00500000 0.04700000 15"></point>
        <point xym="0.00500000 0.25300000 15"></point>
        <point xym="0.02350000 0.25300000 15"></point>
        <point xym="0.02350000 0.30000000 15"></point>
        <point xym="-0.02350000 0.30000000 15"></point>
        <point xym="-0.02350000 0.25300000 15"></point>
        <point xym="-0.00500000 0.25300000 15"></point>
        <point xym="-0.00500000 0.04700000 15"></point>
        <point xym="-0.02350000 0.04700000 15"></point>
        <point xym="-0.02350000 0.00000000 -1"></point>
      </profile>
    </material>

    <material id="I 360" name="I 360" thickness="0.047" height="0.360" shape="block" maxlen="99" m3factor="0.000" excel_quality="" excel_type="">
      <settings>
        <plankdefaults>
          <objparam name="iPenMid">1</objparam>
          <objparam name="iLineMid">*dash*|*katko*</objparam>
          <objparam name="iColLines">0</objparam>
        </plankdefaults>
      </settings>
      <profile>
        <point xym="-0.02350000 0.04700000 15"></point>
        <point xym="-0.02350000 0.00000000 15"></point>
        <point xym="0.02350000 0.00000000 15"></point>
        <point xym="0.02350000 0.04700000 15"></point>
        <point xym="0.00500000 0.04700000 15"></point>
        <point xym="0.00500000 0.31300000 15"></point>
        <point xym="0.02350000 0.31300000 15"></point>
        <point xym="0.02350000 0.36000000 15"></point>
        <point xym="-0.02350000 0.36000000 15"></point>
        <point xym="-0.02350000 0.31300000 15"></point>
        <point xym="-0.00500000 0.31300000 15"></point>
        <point xym="-0.00500000 0.04700000 15"></point>
        <point xym="-0.02350000 0.04700000 -1"></point>
      </profile>
    </material>


    <!-- METAL EXAMPLE BEG -->
    <material id="40x95 METAL" name="40x95 METAL" thickness="0.040" height="0.095" shape="block" maxlen="99" m3factor="0.000" excel_quality="" excel_type="">
      <settings>
        <plankdefaults>
          <objparam name="iColLines">0</objparam>
        </plankdefaults>
      </settings>
      <profile>
        <point xym="-0.02000008 0.00000000 15"></point>
        <point xym="0.02000008 0.00000000 15"></point>
        <point xym="0.02000008 0.00651000 15"></point>
        <point xym="0.01884007 0.00767000 15"></point>
        <point xym="0.01850007 0.00734000 15"></point>
        <point xym="0.01952008 0.00632000 15"></point>
        <point xym="0.01952008 0.00047000 15"></point>
        <point xym="-0.01953007 0.00047000 15"></point>
        <point xym="-0.01953007 0.00671000 15"></point>
        <point xym="-0.01803007 0.00970000 15"></point>
        <point xym="-0.01803007 0.01530000 15"></point>
        <point xym="-0.01953007 0.01831000 15"></point>
        <point xym="-0.01953007 0.07741999 15"></point>
        <point xym="-0.01803039 0.08041999 15"></point>
        <point xym="-0.01803007 0.08725999 15"></point>
        <point xym="-0.01953007 0.09024999 15"></point>
        <point xym="-0.01953007 0.09451998 15"></point>
        <point xym="0.01752007 0.09451998 15"></point>
        <point xym="0.01752007 0.09017999 15"></point>
        <point xym="0.01650006 0.08915999 15"></point>
        <point xym="0.01684006 0.08881999 15"></point>
        <point xym="0.01800007 0.08997999 15"></point>
        <point xym="0.01800007 0.09499998 15"></point>
        <point xym="-0.02000008 0.09499998 15"></point>
        <point xym="-0.02000008 0.09013999 15"></point>
        <point xym="-0.01850007 0.08714999 15"></point>
        <point xym="-0.01850007 0.08052999 15"></point>
        <point xym="-0.02000008 0.07752999 15"></point>
        <point xym="-0.02000008 0.01820000 15"></point>
        <point xym="-0.01850007 0.01519000 15"></point>
        <point xym="-0.01850007 0.00982000 15"></point>
        <point xym="-0.02000008 0.00682000 15"></point>
        <point xym="-0.02000008 0.00000000 -1"></point>
      </profile>
    </material>

    <material id="37x95 METAL TOPBOT" name="37x95 METAL TOPBOT" thickness="0.037" height="0.095" shape="block" maxlen="99" m3factor="0.000" excel_quality="" excel_type="">
      <settings>
        <plankdefaults>
          <objparam name="iColLines">0</objparam>
        </plankdefaults>
      </settings>
      <profile>
        <point xym="-0.01850001 0.09601000 15"></point>
        <point xym="-0.01850001 0.09555000 15"></point>
        <point xym="0.01804001 0.09555000 15"></point>
        <point xym="0.01804001 0.08988000 15"></point>
        <point xym="0.01654001 0.08688000 15"></point>
        <point xym="0.01654001 0.08107000 15"></point>
        <point xym="0.01804001 0.07810000 15"></point>
        <point xym="0.01804001 0.01621000 15"></point>
        <point xym="0.01654001 0.01321000 15"></point>
        <point xym="0.01654001 0.00615000 15"></point>
        <point xym="0.01804001 0.00316000 15"></point>
        <point xym="0.01804001 -0.00055000 15"></point>
        <point xym="-0.01850001 -0.00055000 15"></point>
        <point xym="-0.01850001 -0.00100000 15"></point>
        <point xym="0.01850001 -0.00100000 15"></point>
        <point xym="0.01850001 0.00327000 15"></point>
        <point xym="0.01700001 0.00626000 15"></point>
        <point xym="0.01700001 0.01310000 15"></point>
        <point xym="0.01850001 0.01610000 15"></point>
        <point xym="0.01850001 0.07821000 15"></point>
        <point xym="0.01700001 0.08118000 15"></point>
        <point xym="0.01700001 0.08678000 15"></point>
        <point xym="0.01850001 0.08977000 15"></point>
        <point xym="0.01850001 0.09601000 15"></point>
        <point xym="-0.01850001 0.09601000 -1"></point>
      </profile>
    </material>
    <!-- METAL EXAMPLE END -->

    <material id="XX 204x275" name="XX 204x275" thickness="0.204" height="0.275" shape="block" maxlen="6" m3factor="0.000" excel_quality="" excel_type="">
      <profile>
        <point xym="-0.10200000 0.23900000 15"></point>
        <point xym="-0.10200000 0.02000000 15"></point>
        <point xym="-0.08666940 0.00115990 79"></point>
        <point xym="-0.08430000 0.00299995 900"></point>
        <point xym="0 115.13916275 4079"></point>
        <point xym="-0.08162768 0.00163667 79"></point>
        <point xym="-0.07489160 0.01627220 79"></point>
        <point xym="-0.07043770 0.01399998 900"></point>
        <point xym="0 -62.97088617 4079"></point>
        <point xym="-0.07043770 0.01900000 79"></point>
        <point xym="-0.06600000 0.01900000 15"></point>
        <point xym="-0.06400000 0.01450000 15"></point>
        <point xym="-0.06200000 0.01900000 15"></point>
        <point xym="-0.05300000 0.01900000 15"></point>
        <point xym="-0.05100000 0.01450000 15"></point>
        <point xym="-0.04900000 0.01900000 15"></point>
        <point xym="0.04900000 0.01900000 15"></point>
        <point xym="0.05100000 0.01450000 15"></point>
        <point xym="0.05300000 0.01900000 15"></point>
        <point xym="0.06200000 0.01900000 15"></point>
        <point xym="0.06400000 0.01450000 15"></point>
        <point xym="0.06600000 0.01900000 15"></point>
        <point xym="0.07043780 0.01900000 79"></point>
        <point xym="0.07043780 0.01400000 900"></point>
        <point xym="0 -62.97090300 4079"></point>
        <point xym="0.07489168 0.01627222 79"></point>
        <point xym="0.08162770 0.00163660 79"></point>
        <point xym="0.08429999 0.00299995 900"></point>
        <point xym="0 115.13916275 4079"></point>
        <point xym="0.08666944 0.00115996 79"></point>
        <point xym="0.10200000 0.02000000 15"></point>
        <point xym="0.10200000 0.23900000 15"></point>
        <point xym="0.08200000 0.25900000 15"></point>
        <point xym="0.07500000 0.27400000 15"></point>
        <point xym="0.06600000 0.27500000 15"></point>
        <point xym="-0.06600000 0.27500000 15"></point>
        <point xym="-0.07500000 0.27400000 15"></point>
        <point xym="-0.08200000 0.25900000 15"></point>
        <point xym="-0.10200000 0.23900000 -1"></point>
      </profile>
    </material>

    <material id="XX 204x275B" name="XX 204x275B" thickness="0.204" height="0.275" shape="block" maxlen="6" m3factor="0.000" excel_quality="" excel_type="">
      <profile_xz>
        <beg>
          <point xym="0.00000000 0.27500000 79"></point>
          <point xym="0.00000000 0.10000000 79"></point>
          <point xym="0.00934396 0.09840845 79"></point>
          <point xym="0.01858918 0.09631837 79"></point>
          <point xym="0.02770908 0.09373575 79"></point>
          <point xym="0.03667744 0.09066802 79"></point>
          <point xym="0.04546849 0.08712400 79"></point>
          <point xym="0.05405694 0.08311388 79"></point>
          <point xym="0.06241811 0.07864919 79"></point>
          <point xym="0.07052795 0.07374277 79"></point>
          <point xym="0.07836315 0.06840871 79"></point>
          <point xym="0.08590119 0.06266236 79"></point>
          <point xym="0.09312039 0.05652024 79"></point>
          <point xym="0.10000000 0.05000000 79"></point>
          <point xym="0.10608825 0.04250404 79"></point>
          <point xym="0.11273700 0.03550045 79"></point>
          <point xym="0.11990657 0.02903103 79"></point>
          <point xym="0.12755417 0.02313439 79"></point>
          <point xym="0.13563415 0.01784573 79"></point>
          <point xym="0.14409830 0.01319660 79"></point>
          <point xym="0.15289609 0.00921476 79"></point>
          <point xym="0.16197501 0.00592397 79"></point>
          <point xym="0.17128089 0.00334388 79"></point>
          <point xym="0.18075816 0.00148987 79"></point>
          <point xym="0.19035029 0.00037302 79"></point>
          <point xym="0.20000000 0.00000000 79"></point>
          <point xym="0.25000000 0.00000000 79"></point>
          <point xym="0.25000000 0.27500000 79"></point>
          <point xym="0.00000000 0.27500000 -1"></point>
        </beg>
        <mid>
          <point xym="2.00000000 0.27500000 15"></point>
          <point xym="0.00000000 0.27500000 15"></point>
          <point xym="0.00000000 0.00000000 15"></point>
          <point xym="0.05000000 0.05000000 15"></point>
          <point xym="0.10000000 0.00000000 15"></point>
          <point xym="0.15000000 0.05000000 15"></point>
          <point xym="0.20000000 0.00000000 15"></point>
          <point xym="0.25000000 0.05000000 15"></point>
          <point xym="0.30000000 0.00000000 15"></point>
          <point xym="0.35000000 0.05000000 15"></point>
          <point xym="0.40000000 0.00000000 15"></point>
          <point xym="0.45000000 0.05000000 15"></point>
          <point xym="0.50000000 0.00000000 15"></point>
          <point xym="0.55000000 0.05000000 15"></point>
          <point xym="0.60000000 0.00000000 15"></point>
          <point xym="0.65000000 0.05000000 15"></point>
          <point xym="0.70000000 0.00000000 15"></point>
          <point xym="0.75000000 0.05000000 15"></point>
          <point xym="0.80000000 0.00000000 15"></point>
          <point xym="0.85000000 0.05000000 15"></point>
          <point xym="0.90000000 0.00000000 15"></point>
          <point xym="0.95000000 0.05000000 15"></point>
          <point xym="1.00000000 0.00000000 15"></point>
          <point xym="1.05000000 0.05000000 15"></point>
          <point xym="1.10000000 0.00000000 15"></point>
          <point xym="1.15000000 0.05000000 15"></point>
          <point xym="1.20000000 0.00000000 15"></point>
          <point xym="1.25000000 0.05000000 15"></point>
          <point xym="1.30000000 0.00000000 15"></point>
          <point xym="1.35000000 0.05000000 15"></point>
          <point xym="1.40000000 0.00000000 15"></point>
          <point xym="1.45000000 0.05000000 15"></point>
          <point xym="1.50000000 0.00000000 15"></point>
          <point xym="1.55000000 0.05000000 15"></point>
          <point xym="1.60000000 0.00000000 15"></point>
          <point xym="1.65000000 0.05000000 15"></point>
          <point xym="1.70000000 0.00000000 15"></point>
          <point xym="1.75000000 0.05000000 15"></point>
          <point xym="1.80000000 0.00000000 15"></point>
          <point xym="1.85000000 0.05000000 15"></point>
          <point xym="1.90000000 0.00000000 15"></point>
          <point xym="1.95000000 0.05000000 15"></point>
          <point xym="2.00000000 0.00000000 15"></point>
          <point xym="2.00000000 0.27500000 -1"></point>
        </mid>
        <end>
          <point xym="0.00000000 0.27500000 79"></point>
          <point xym="0.00000000 0.10000000 79"></point>
          <point xym="0.00934396 0.09840845 79"></point>
          <point xym="0.01858918 0.09631837 79"></point>
          <point xym="0.02770908 0.09373575 79"></point>
          <point xym="0.03667744 0.09066802 79"></point>
          <point xym="0.04546849 0.08712400 79"></point>
          <point xym="0.05405694 0.08311388 79"></point>
          <point xym="0.06241811 0.07864919 79"></point>
          <point xym="0.07052795 0.07374277 79"></point>
          <point xym="0.07836315 0.06840871 79"></point>
          <point xym="0.08590119 0.06266236 79"></point>
          <point xym="0.09312039 0.05652024 79"></point>
          <point xym="0.10000000 0.05000000 79"></point>
          <point xym="0.10608825 0.04250404 79"></point>
          <point xym="0.11273700 0.03550045 79"></point>
          <point xym="0.11990657 0.02903103 79"></point>
          <point xym="0.12755417 0.02313439 79"></point>
          <point xym="0.13563415 0.01784573 79"></point>
          <point xym="0.14409830 0.01319660 79"></point>
          <point xym="0.15289609 0.00921476 79"></point>
          <point xym="0.16197501 0.00592397 79"></point>
          <point xym="0.17128089 0.00334388 79"></point>
          <point xym="0.18075816 0.00148987 79"></point>
          <point xym="0.19035029 0.00037302 79"></point>
          <point xym="0.20000000 0.00000000 79"></point>
          <point xym="0.25000000 0.00000000 79"></point>
          <point xym="0.25000000 0.27500000 79"></point>
          <point xym="0.00000000 0.27500000 -1"></point>
        </end>
      </profile_xz>
    </material>

    <material id="COVER DECO1" name="COVER DECO1" thickness="0.025" height="0.100" shape="block" maxlen="6" m3factor="0.000" fixlen="0.250">
      <profile_xz>
        <beg>
          <point xym="0.07322393 0.06614473 79"></point>
          <point xym="0.00000000 0.00000000 79"></point>
          <point xym="0.25000000 0.00000000 79"></point>
          <point xym="0.16607323 0.08392677 79"></point>
          <point xym="0.07322393 0.06614473 -1"></point>
        </beg>
      </profile_xz>
    </material>

    <material id="COVER DECO2" name="COVER DECO2" thickness="0.025" height="0.084" shape="block" maxlen="6" m3factor="0.000" fixlen="0.1572">
      <profile_xz>
        <beg>
          <point xym="0.07327324 0.08392676 79"></point>
          <point xym="0.00000000 0.00000000 79"></point>
          <point xym="0.15720000 0.00000000 79"></point>
          <point xym="0.07327324 0.08392676 -1"></point>
        </beg>
      </profile_xz>
    </material>


    <!-- Not to be selected by ArchiFrame Add/Edit, but targets for tenon&mortise etc. (from ArchiLogs) -->
    <material tolist="0" id="LOG xxx" name="LOG xxx" thickness="0.150" height="0.250" overlap="0.015" shape="plane" m3factor="0.000" excel_quality="" excel_type="">
      <settings>
        <!-- Tenon&mortise defaults -->
        <mortisetenon len="0.056" bordertop="0.02" borderbot="0.015" borderside="0.01" roundingr="0.0225" endgap="0.001" sidegap="0.001" topgap="0.010" >
        </mortisetenon>

        <!-- Dovetail defaults -->
        <dovetail len="0.038" bordertop="0.00" borderbot="0.050" bottomwidth="0.06" roundingr="0.0225" endgap="0.000" sidegap="0.0000" angle="6" >
        </dovetail>

        <!-- Balk defaults -->
        <balkborder bordertop="0.02" borderbot="0.02" borderside="0.01" overtop="0.001" overbot="0.000" overside="0.001" overlen="0.000" >
        </balkborder>

        <!-- Through going balk defaults -->
        <balkcut overtop="0.01" overbot="0.000" overside="0.001" >
        </balkcut>
      </settings>
    </material>

  </materials>

  <!-- Added to main plank tools -->
  <mctools>
    <mctool name="Add reinforcement">
      <![CDATA[
EPS=0.0001
PI=3.141592653589793
PI2=PI/2.0
PI180=PI/180.0
PI1800=PI/1800.0


function dump(o)
  if type(o) == 'table' then
    local s = '{ '
    for k,v in pairs(o) do
      if type(k) ~= 'number' then k = '"'..k..'"' end
      s = s .. '['..k..'] = ' .. dump(v) .. ','
    end
    return s .. '} '
  else
    return tostring(o)
  end
end


-- Gets groove info as Birkeland btl-writer
function GetGroInfo(i)
    local tblGroInfo, tblGro

    x1      =ac_objectget("iMc", i, 2)
    y1      =ac_objectget("iMc", i, 3)
    x2      =ac_objectget("iMc", i, 4)
    y2      =ac_objectget("iMc", i, 5)
    groDepth=ac_objectget("iMc", i, 6)
    groWidth=ac_objectget("iMc", i, 7)
    groAngle=ac_objectget("iMc", i, 8)*PI/180.0
    groFace =ac_objectget("iMc", i, 9)
    groAngleLen=ac_objectget("iMc", i, 10)*PI/180.0

    tblGro={}
    tblGro.guid = ac_objectget("#guid")
    tblGro.x1   = x1
    tblGro.y1   = y1
    tblGro.x2   = x2
    tblGro.y2   = y2
    tblGro.depth    = groDepth
    tblGro.width    = groWidth
    tblGro.groAngleRad  = groAngle
    tblGro.face         = groFace
    tblGro.groTiltAngleRad  = groAngleLen

    if y1>y2 then
        -- To have positive angle
        af_request("mc_swapgroref", tblGro)
        x1  = tblGro.x1
        y1  = tblGro.y1
        x2  = tblGro.x2
        y2  = tblGro.y2
        groDepth    = tblGro.depth
        groAngle    = tblGro.groAngleRad
        groAngleLen = tblGro.groTiltAngleRad
    end

    tblGroInfo = af_request("mc_getgroinfo", tblGro)
  return tblGroInfo, tblGro
end  


-- Asks for the material to use. Last selected plank must be opened when calling this
-- Returns (len=0 if not to be added, all nil if canceled): lenbeg, lenend, tblGroInfos
function SettingsDlg()
  local  tblSettings, bRes
  local  tblGroInfos, s, nGro, i, mc, tblTemp, strSep, mcCount


  tblGroInfos={}
  nGro=0
  strSep=""
  s=""
  mcCount=ac_objectget("iMc", -1)
  for i=1,mcCount do
    mc=ac_objectget("iMc", i, 1)
    if not mc then
      break
    end
    if mc==301 then
      -- Groove
      tblTemp=GetGroInfo(i)
      if tblTemp.isBird then
          mulDir2=1
--ac_environment("tolog", dump(tblTemp))
          x=tblTemp.projside1.lineref.x1
          y=tblTemp.projside1.lineref.y1
          if tblTemp.projside1.lineref.len<tblTemp.projside1.lineother.len then
              mulDir2=-1
              x=tblTemp.projside1.lineother.x2
              y=tblTemp.projside1.lineother.y2
          end
        
        nGro=nGro+1
        tblGroInfos[nGro]={}
        tblGroInfos[nGro].x=x
        tblGroInfos[nGro].len=0

        --s=string.format("%s%s\"%s:%.0f mm\"", s, strSep, nGro, x*1000)
        --strSep=","
      end
    end
  end

  tblSettings={}
  tblSettings[1]      ={}
  tblSettings[1].cfgonly =0
  tblSettings[1].type    =3
  tblSettings[1].prompt  ="Length beg (0=none)"
  tblSettings[1].key    ="lenbeg"
  tblSettings[1].defvalue  =0

  tblSettings[2]      ={}
  tblSettings[2].cfgonly  =0
  tblSettings[2].type    =3
  tblSettings[2].prompt  ="Length end (0=none)"
  tblSettings[2].key    ="lenend"
  tblSettings[2].defvalue  =0

  for i=1,nGro do
    tblSettings[2+i]      ={}
    tblSettings[2+i].cfgonly  =0
    tblSettings[2+i].type    =3
    tblSettings[2+i].prompt  =string.format("Length groove at %.0f (0=none)", 1000*tblGroInfos[i].x)
    tblSettings[2+i].key    =string.format("lengro%d", i)
    tblSettings[2+i].value  =0    -- These always zero as default
  end

  bRes,sErr=ac_optiondlg("LDPR", "Add reinforcement", tblSettings)
  if not bRes then
    return
  end

  for i=1,nGro do
    tblGroInfos[i].len=tblSettings[2+i].value
  end

  return tblSettings[1].value, tblSettings[2].value, tblGroInfos
end


function AddReinforcement( posMid, dx )
  local i, count, add, plankInfo, s, height, dy, mat

  plankInfo=af_request("plankinfo")
  height=plankInfo.height

  count=ac_objectget("iMc", -1)
  add=count+1
  for i=1,count do
    if ac_objectget("iMc", i, 1)==0 then
      add=i
      break
    end
  end

--MC fields:
--xMid;         // 2
--yMid;         // 3
--dWidth;           // 4
--dHeight;      // 5
--dThickness;       // 6
--dSideOneBased;    // 7
--dBothSides;       // 8
--dInside;      // 9
--dAcMat;           // 10, zero=use plank's material

  if height<0.2195 then
    s="SF200"
    dy=0.104
  elseif height<0.2495 then
    s="SF220"
    dy=0.134
  elseif height<0.2995 then
    s="SF250"
    dy=0.154
  elseif height<0.3495 then
    s="SF300"
    dy=0.204
  elseif height<0.3995 then
    s="SF350"
    dy=0.254
  elseif height<0.4495 then
    s="SF400"
    dy=0.304
  elseif height<0.4995 then
    s="SF450"
    dy=0.354
  elseif height<0.5495 then
    s="SF500"
    dy=0.404
  elseif height<0.5995 then
    s="SF550"
    dy=0.454
  else
    s="SF600"
    dy=0.504
  end

  ac_objectset("iMc", 304,    add, 1)
  ac_objectset("iMc", posMid, add, 2)
  ac_objectset("iMc", height*0.5-0.001, add, 3 )
  ac_objectset("iMc", dx,     add, 4)
  ac_objectset("iMc", dy,     add, 5)
  ac_objectset("iMc", 0.018,  add, 6)
  ac_objectset("iMc", 2,      add, 7)
  ac_objectset("iMc", 1,      add, 8)
  ac_objectset("iMc", 1,      add, 9)
  
  mat=ac_environment("findattr", 6, "*osb*")
  if mat==nil then
    mat=1
  end
  ac_objectset("iMc", mat, add, 10)
  ac_objectset("iMcStr", s, add)

end


function Do()
  local lenBeg, lenEnd, xGro, lenGro, nPlanks, tblSel, i, v, tblInfo, tblGro, iGro, vGro
  
  tblSel=af_request("getselplanks")
  if tblSel==nil then
    return "Please select target planks first"
  end

  nPlanks=0
  ac_objectopen(tblSel[0])
  lenBeg, lenEnd, tblGro=SettingsDlg()
  ac_objectclose()
  if not lenBeg then
    return "Canceled"
  end

  for i,v in pairs(tblSel) do
    ac_objectopen(v)
    tblInfo=af_request("plankinfo")
    
    if lenBeg>0 then
      if lenBeg>tblInfo.len then
        lenBeg=tblInfo.len
      end
      AddReinforcement(lenBeg*0.5, lenBeg)
    end
    
    if lenEnd>0 then
      if lenEnd>tblInfo.len then
        lenEnd=tblInfo.len
      end
      AddReinforcement(tblInfo.len-lenEnd*0.5, lenEnd)
    end
    
    for iGro,vGro in ipairs(tblGro) do
    
      if vGro.len>tblInfo.len then
        vGro.len=tblInfo.len
      end
      if vGro.len>0 then
        AddReinforcement(vGro.x, vGro.len)
      end
    end

    nPlanks=nPlanks+1
    
    ac_objectclose()
  end

  return string.format("Processed %d", nPlanks)
end

gsStatus=Do()
]]>
    </mctool>


    <mctool name="Automatic reinforcement settings">
      <![CDATA[
gBeg=0
gEnd=0
gGro=0
gDelAuto=1
      
-- Asks for the material to use. Last selected plank must be opened when calling this
-- Returns in globals
function SettingsDlg()
  local  tblSettings, bRes
  local  tblGroInfos, s, nGro, i, mc, tblTemp, strSep, mcCount


  tblSettings={}
  tblSettings[1]      ={}
  tblSettings[1].cfgonly =0
  tblSettings[1].type    =2
  tblSettings[1].prompt  ="Automatic reinforcement & nails begin"
  tblSettings[1].key    ="autobeg"
  tblSettings[1].value  =gBeg

  tblSettings[2]      ={}
  tblSettings[2].cfgonly =0
  tblSettings[2].type    =2
  tblSettings[2].prompt  ="Automatic reinforcement & nails end"
  tblSettings[2].key    ="autoend"
  tblSettings[2].value  =gEnd

  tblSettings[3]      ={}
  tblSettings[3].cfgonly =0
  tblSettings[3].type    =2
  tblSettings[3].prompt  ="Automatic reinforcement & nails grooves"
  tblSettings[3].key    ="autogro"
  tblSettings[3].value  =gGro

  tblSettings[4]      ={}
  tblSettings[4].cfgonly =0
  tblSettings[4].type    =2
  tblSettings[4].prompt  ="Delete all existing automatic (selected are recreated)"
  tblSettings[4].key    ="delauto"
  tblSettings[4].value  =gDelAuto

  bRes,sErr=ac_optiondlg("LDPA", "Automatic reinforcement", tblSettings)
  if not bRes then
    return false
  end

  gBeg=tblSettings[1].value
  gEnd=tblSettings[2].value
  gGro=tblSettings[3].value
  gDelAuto=tblSettings[4].value
  
  return true
end


function Do()
  local nPlanks, tblSel, flags, i, v, row
  
  tblSel=af_request("getselplanks")
  if tblSel==nil then
    return "Please select target planks first"
  end

  nPlanks=0
  ac_objectopen(tblSel[0])
  flags=ac_objectget("iFlagsCustom")
  ac_objectclose()
  
  gBeg=ac_environment("bittest", flags, 10)
  gEnd=ac_environment("bittest", flags, 11)
  gGro=ac_environment("bittest", flags, 12)
  
  if not SettingsDlg() then
    return "Canceled"
  end

  -- bit10-12
  flags=1024*gBeg + 2048*gEnd + 4096*gGro
  for i,v in pairs(tblSel) do
    ac_objectopen(v)
    ac_objectset("iFlagsCustom", flags+8192)         -- Force refresh for all
    
    if gDelAuto==1 then
      local row, rows, mc

      rows=ac_objectget("iMc", -1)
      for row=1,rows do
        mc=ac_objectget("iMc", row, 1)
        if mc==304 and ac_environment("bittest", ac_objectget("iMc", row, 12), 0)==1 then
          -- Automatic reinforce
          ac_objectset("iMc", 0, row, 1)
        elseif mc==306 and ac_environment("bittest", ac_objectget("iMc", row, 10), 1)==1 then
          -- Nail group
          ac_objectset("iMc", 0, row, 1)
        end
      end
    end

    ac_objectclose()
    nPlanks=nPlanks+1
  end

  return string.format("Processed %d", nPlanks)
end

gsStatus=Do()
]]>
    </mctool>


    <mctool name="Add element extension piece">
      <![CDATA[
EPS=0.0001
PI=3.141592653589793
PI2=PI/2.0
PI180=PI/180.0
PI1800=PI/1800.0


function dump(o)
  if type(o) == 'table' then
    local s = '{ '
    for k,v in pairs(o) do
      if type(k) ~= 'number' then k = '"'..k..'"' end
      s = s .. '['..k..'] = ' .. dump(v) .. ','
    end
    return s .. '} '
  else
    return tostring(o)
  end
end


-- Asks for the material to use. Last selected plank must be opened when calling this
-- Returns: newHeight, offset in elem dir, offset to top/bottom, bIsTop
function SettingsDlg()
  local  tblSettings, bRes, sErr
  local  tblGroInfos, s, nGro, i, mc, tblTemp, strSep, mcCount


  tblSettings={}
  tblSettings[1]      ={}
  tblSettings[1].cfgonly =0
  tblSettings[1].type    =3
  tblSettings[1].prompt  ="Height of new pieces"
  tblSettings[1].key    ="height"
  tblSettings[1].defvalue  =0.100

  tblSettings[2]      ={}
  tblSettings[2].cfgonly =0
  tblSettings[2].type    =3
  tblSettings[2].prompt  ="Move in element's watching dir"
  tblSettings[2].key    ="movecam"
  tblSettings[2].defvalue  =0

  tblSettings[3]      ={}
  tblSettings[3].cfgonly  =0
  tblSettings[3].type    =3
  tblSettings[3].prompt  ="Offset from top or bottom"
  tblSettings[3].key    ="movetop"
  tblSettings[3].defvalue  =0.048

  tblSettings[4]      ={}
  tblSettings[4].cfgonly  =0
  tblSettings[4].type    =2
  tblSettings[4].prompt  ="To top (if unchecked to bottom)"
  tblSettings[4].key    ="istop"
  tblSettings[4].defvalue  =0

  bRes,sErr=ac_optiondlg("LDBE", "Add extension piece", tblSettings)
  if not bRes then
    return
  end
  
  bRes=false
  if tblSettings[4].value==1.0 then
    bRes=true
  end

  return tblSettings[1].value, tblSettings[2].value, tblSettings[3].value, bRes
end


function Do()
  local nPlanks, tblSel, i, v, newHeight, offCam, offLevel, bTop, tblInfo, elemGuid
  
  tblSel=af_request("getselplanks")
  if tblSel==nil then
    return "Please select target planks first"
  end

  nPlanks=0
  newHeight, offCam, offLevel, bTop=SettingsDlg()
  ac_objectclose()
  if not newHeight then
    return "Canceled"
  end

  -- Find owner element
  elemGuid=nil
  for i,v in pairs(tblSel) do
    ac_objectopen(v)
    tblInfo=af_request("plankinfo")
    if not elemGuid then
      elemGuid=tblInfo.ownerelemguid
      if not elemGuid then
        return "Supported only for planks belonging to an element"
      end
    elseif elemGuid~=tblInfo.ownerelemguid then
      return "Supported only for planks belonging to an element"
    end

    nPlanks=nPlanks+1
    ac_objectclose()
  end
  
  -- Open element
  local nCreate, plank
  
  af_request("elem_openparent", elemGuid)
  af_request("elem_openlayer", elemGuid)
  af_request("elem_getpoly ", 1)
  
  gtblCreate={}
  nCreate=0
  
  for i,v in pairs(tblSel) do
      ac_objectopen(v)
      tblInfo=af_request("plankinfo")
      tblInfo.elemdata=ac_objectget("#af_elemdata")

      plank={}
      plank.guidsettings=tblInfo.elemdata.ptr
      plank.group=ac_objectget("iElemGroup")
      plank.x1=tblInfo.elemdata.x1
      plank.x2=tblInfo.elemdata.x2
      plank.zoff=tblInfo.elemdata.z1+offCam

      if bTop then
        plank.y1=tblInfo.elemdata.y2+offLevel
        plank.y2=plank.y1+newHeight
      else
        plank.y2=tblInfo.elemdata.y1-offLevel
        plank.y1=plank.y2-newHeight
      end

      nCreate=nCreate+1
      gtblCreate[nCreate]=plank
      ac_objectclose()
  end

  af_request("elem_createplanks")
  --af_request("elem_closelayer")
  af_request("elem_closeparent", 1)
  return string.format("Processed %d", nPlanks)
end

gsStatus=Do()
]]>
    </mctool>


    <mctool name="Extend 1st selected over 2nd selected">
      <![CDATA[
EPS=0.0001
PI=3.141592653589793
PI2=PI/2.0
PI180=PI/180.0
PI1800=PI/1800.0


function dump(o)
  if type(o) == 'table' then
    local s = '{ '
    for k,v in pairs(o) do
      if type(k) ~= 'number' then k = '"'..k..'"' end
      s = s .. '['..k..'] = ' .. dump(v) .. ','
    end
    return s .. '} '
  else
    return tostring(o)
  end
end


function KeepLongest(tblPlanks)
  local i, v, tbl, dx, dy, dz
  
  if #tblPlanks<2 then
    return
  end
  
  tbl={}
  for i,v in ipairs(tblPlanks) do
    tbl[i]={}
    tbl[i].guid=v
    ac_objectopen(v)
    dx=ac_objectget("iEndX")-ac_objectget("iBegX")
    dy=ac_objectget("iEndY")-ac_objectget("iBegY")
    dz=ac_objectget("iEndZ")-ac_objectget("iBegZ")
    tbl[i].len=math.sqrt(dx*dx + dy*dy + dz*dz)
    ac_objectclose()
  end
  
  table.sort(tbl, function(p1,p2)
      return p1.len>p2.len
    end)

  i=2
  while tbl[i] do
--ac_environment("tolog", string.format("DEL %s, len=%f", tbl[i].guid, tbl[i].len))
    ac_objectopen(tbl[i].guid)
    af_request("delplank")
    ac_objectclose()
    i=i+1
  end
end


function Do()
  local tblSel, tblSettings, tblOp, tblRes
  
  tblSel=af_request("getselplanks")
  if tblSel==nil or tblSel[0]==nil or tblSel[1]==nil then
    return "Please select two planks, first to be longer"
  end

  tblSettings={}
  tblSettings.endshape=2
  tblSettings.cuttoendplane=1
  tblSettings.expandopfind=0.001
  tblSettings.skipopsides=16+32     -- Do not check the ends
  
  tblOp={}
  tblOp[1]=tblSel[1]

  tblRes=af_request("adjusttoside", tblSettings, tblSel[0], tblOp)
  if tblRes==nil then
    return "WARNING: NOTHING DONE"
  end
  
  -- In case of angled corners the result may be split - keep just the longest parts
  KeepLongest(tblRes)
  
  -- Short (if changing)
  tblSettings.cuttoendplane=0
  tblOp[1]=tblSel[0]
  tblRes=af_request("adjusttoside", tblSettings, tblSel[1], tblOp)
  if tblRes then
    KeepLongest(tblRes)
  end
end

gsStatus=Do()
]]>
    </mctool>


    <mctool name="Check that there are no machinings in selected planks">
      <![CDATA[
EPS=0.0001
PI=3.141592653589793
PI180=PI/180.0


function Do()
  local tblSel, i, v, b, cmc, imc, tblMcPlanks, nPlanks, s, nChecked, elem
  
  tblSel=ac_environment("getsel")
  if tblSel==nil then
    return "Please select the planks"
  end

  tblMcPlanks={}
  nPlanks=0
  nChecked=0
  for i,v in pairs(tblSel) do
    elem=ac_elemget(v)
    if elem.header.typeID==6 then
      ac_objectopen(v)
    
      cmc=ac_objectget("iMc",-1)
      if cmc and cmc>0 then
        nChecked=nChecked+1
        b=false
        for imc=1,cmc do
          if ac_objectget("iMc",imc, 1)>0 then
            b=true
            break
          end
        end      
    
        if b then
          nPlanks=nPlanks+1
          tblMcPlanks[nPlanks]=v
        end
      end
      ac_objectclose()
    end
  end
  
  s=string.format("No machinings found, checked %d", nChecked)
  if nPlanks>0 then
    local b
    
    b = ac_environment("suspendgroups", true)
    ac_environment("setsel", tblMcPlanks)
    s=""
    if not b then
      s=". Suspended groups"
    end
    s=string.format("Mcs found from %d/%d planks%s", nPlanks, nChecked, s)
  end
  
  return s
end

gsStatus=Do()
]]>
    </mctool>

    <mctool name="Select planks with reinforcements">
      <![CDATA[
EPS=0.0001
PI=3.141592653589793
PI180=PI/180.0


function Do()
  local tblSel, i, v, b, cmc, imc, tblMcPlanks, nPlanks, s, nChecked, elem, bSkipProj, val
  
  tblSel=ac_environment("getsel")
  if tblSel==nil then
    tblSel=ac_environment("getall", -1, 6)
  end
  
  bSkipProj=true
  if ac_environment("getcurrwindow")==1 then
    bSkipProj=false
  end

  tblMcPlanks={}
  nPlanks=0
  nChecked=0
  for i,v in pairs(tblSel) do
    elem=ac_elemget(v)
    if elem.header.typeID==6 then
      ac_objectopen(v)
    
      cmc=ac_objectget("iMc",-1)
      val=ac_objectget("iIsProjOnly")
      if cmc and cmc>0 and val and (bSkipProj==false or val==0) then
        nChecked=nChecked+1
        b=false
        for imc=1,cmc do
          if ac_objectget("iMc",imc, 1)==304 then
            b=true
            break
          end
        end      
    
        if b then
          nPlanks=nPlanks+1
          tblMcPlanks[nPlanks]=v
        end
      end
      ac_objectclose()
    end
  end
  
  s=string.format("No reinforcements found, checked %d", nChecked)
  if nPlanks>0 then
    local b
    
    b = ac_environment("suspendgroups", true)
    ac_environment("setsel", tblMcPlanks)
    s=""
    if not b then
      s=". Suspended groups"
    end
    s=string.format("Reinforcements found from %d/%d planks%s", nPlanks, nChecked, s)
  end
  
  return s
end

gsStatus=Do()
]]>
    </mctool>

    <mctool name="Plank ID as beam on/off">
      <![CDATA[
EPS=0.0001
PI=3.141592653589793
PI180=PI/180.0


function Do()
  local tblSel, i, v, s, set, count
  
  tblSel=af_request("getselplanks")
  if tblSel==nil then
    return "Please select the planks"
  end

  count=0
  for i,v in pairs(tblSel) do
    ac_objectopen(v)
    
    s=ac_objectget("iIDContent")
    if s==nil then
      return "Old library version - no supported"
    end
    
    if set==nil then
      set=false
      if s=="" then
        set=true
      end
    end

    s=""
    if set then
      local lp, lang
      
      lang=af_request("aflang")
      if not lang then
        lang="eng"
      end
      
      lp="GL "
      if lang=="fin" then
        lp="LP "
      elseif lang=="nor" or lang=="swe" then
        lp="L "
      end

      s=lp .. "[width]x[height] - [length]"
      if ac_objectget("iShowID")==0 then
        ac_objectset("iShowID", 1)
      end
    end
    ac_objectset("iIDContent", s)
    count=count+1

    ac_objectclose()
  end
  
  return string.format("Set %d IDs", count)
end

gsStatus=Do()
]]>
    </mctool>


    <mctool name="Gap between selected boards" name_fin="Rako valittujen levyjen välille" name_pol="Przerwa między wybranymi płytami">
      <![CDATA[
EPS=0.0001
PI=3.141592653589793
PI180=PI/180.0


function Do()
  local tblSel, tblSettings, t, count
  local bRes,sErr

  tblSel=af_request ("getselplanks", "board")
  if tblSel==nil then
    return "Please select the boards"
  end
  
  tblSettings={}
  tblSettings[1]      ={}
  tblSettings[1].cfgonly =1
  tblSettings[1].type    =3
  tblSettings[1].prompt  ="Gap between the boards"
  tblSettings[1].key    ="gap"
  tblSettings[1].defvalue  =0.003

  bRes,sErr=ac_optiondlg("LDBG", "Board gaps", tblSettings)
  if not bRes then
    return
  end
  
  t={}
  t.gap=tblSettings[1].value
  if t.gap<0.0001 then
    return "GAP NEEDS TO BE > 0.0001"
  end

  count=af_request("boardgap", tblSel, t)
  return string.format("Edited %d boards", count)
end

gsStatus=Do()
]]>
    </mctool>

		<mctool name="Move selected boards' top and bottom" name_fin="Siirrä valittujen levyjen ala- ja yläreunoja">
			<![CDATA[
EPS=0.0001
PI=3.141592653589793
PI180=PI/180.0


function AdjustBoards(tblSel, extendbot, extendtop)
  local i, v, guidElem, infoElem, d, tblHandle, miny, maxy, t, rows, row, y

	-- Get owner element of the first board and use it as projection world
	v = af_request("plankinfo", tblSel[0])
	if v and v.ownerelemguid then
	  infoElem = af_request("plankinfo", v.ownerelemguid)
		infoElem.vecy, infoElem.vecz = infoElem.vecz, infoElem.vecy
	end

	-- Find min and max y and filter out unsuitable boards
	miny = 1E100
	maxy = -1E100
	tblHandle = {}    -- Will have fields guid, info, contourend telling points in the contour line
  for i,v in pairs(tblSel) do
	  ac_objectopen(v)
		
		d = ac_objectget("iRotAnglePar")
		if d and math.abs(d)>EPS then
		  ac_environment("tolog", string.format("WARNING: Board %s has unsupported rotation - skipped", ac_objectget("#id")))
		else
		  -- Find min & max y-coords
			rows = ac_objectget("iPolygon", -1)
			
			t = {}
			t.guid = v
			t.info = af_request("plankinfo", nil, infoElem)
			t.contourend = rows
			for row=1,rows do
			  y = t.info.elemdata.y1 + ac_objectget("iPolygon", row, 2)
			  if y > maxy then
				  maxy = y
				end
			  if y < miny then
				  miny = y
				end
				
				if ac_objectget("iPolygon", row, 3)==-1 then
				  t.contourend = row
				  break
				end
			end

--ac_environment("tolog", string.format("%s: elemdata.y1=%f, elemdata.by1=%f", ac_objectget("#id"), t.info.elemdata.y1, t.info.elemdata.by1))
		  tblHandle[#tblHandle+1] = t
	  end
		
		ac_objectclose()
	end
	
--ac_environment("tolog", string.format("miny=%f maxy=%f #tblHandle=%d", miny, maxy, #tblHandle))

  -- Then adjust all edges at top and bottom (outside/positive to the left of the edge)
  for i,v in ipairs(tblHandle) do
	  ac_objectopen(v.guid)
		
		rows = ac_objectget("iPolygon", -1)
		for row=1,rows do
		  local nextpt, nexty, newy, findy
			
			nextpt = row + 1      -- Index of next point
			if nextpt > v.contourend then
			  nextpt = 1
			end
			
			y = v.info.elemdata.y1 + ac_objectget("iPolygon", row, 2)
			nexty = v.info.elemdata.y1 + ac_objectget("iPolygon", nextpt, 2)
			newy = nil

--ac_environment("tolog", string.format("%d: y=%f nexty=%f infoElem=%s", row, y, nexty, tostring(infoElem)))

			if math.abs(y - miny) < EPS and math.abs(nexty - miny) < EPS then
				findy = ac_objectget("iPolygon", row, 2)
			  newy = findy - extendbot
			elseif math.abs(y - maxy) < EPS and math.abs(nexty - maxy) < EPS then
				findy = ac_objectget("iPolygon", row, 2)
			  newy = findy + extendtop
			end
			
			if newy then
			  -- Found horizontal edge at min y, adjust it and next
				ac_objectset("iPolygon", newy, row, 2)
				ac_objectset("iPolygon", newy, nextpt, 2)
				
				-- Then adjust as long as we have the same y in case of multiple parallel edges
				while false do
				  nextpt = nextpt + 1
			    if nextpt > v.contourend then
			      nextpt = 1
			    end
					if math.abs(findy - ac_objectget("iPolygon", nextpt, 2)) > EPS then
					  break
					end
					
  				ac_objectset("iPolygon", newy, nextpt, 2)
				end
		  end
		end
	
	  af_request("flushmc")     -- Needed to normalize the polygon
		ac_objectclose()
	end
	
	return #tblHandle
end


function Do()
  local tblSel, tblSettings, count
  local bRes,sErr

  tblSel=af_request ("getselplanks", "board")
  if tblSel==nil then
    return "Please select the boards"
  end
  
  tblSettings={}
  tblSettings[1]      ={}
  tblSettings[1].cfgonly =1
  tblSettings[1].type    =3
  tblSettings[1].prompt  ="Move top (positive extends)"
  tblSettings[1].key    ="top"
  tblSettings[1].defvalue  =0

  tblSettings[2]      ={}
  tblSettings[2].cfgonly =1
  tblSettings[2].type    =3
  tblSettings[2].prompt  ="Move bottom (positive extends)"
  tblSettings[2].key    ="bot"
  tblSettings[2].defvalue  =0

  bRes,sErr=ac_optiondlg("LDBM", "Move selected boards' top and bottom", tblSettings)
  if not bRes then
    return
  end

  count = AdjustBoards(tblSel, tblSettings[2].value, tblSettings[1].value)
  return string.format("Edited %d boards", count)
end

gsStatus=Do()
]]>
		</mctool>


		<mctool name="Element lifting drillings wall top" name_fin="Elementin nostoreiät seinä ylhäältä" name_pol="Otwory do podnoszenia elementu w ścianie od góry">
      <![CDATA[
EPS=0.0001
PI=3.141592653589793
PI180=PI/180.0


function FindFreeMc()
  local rows, row, mc
  
  rows=ac_objectget("iMc", -1)
  row=1
  while row<=rows do
    mc=ac_objectget("iMc", row, 1)
    if not mc or mc==0 then
      break
    end
    row=row+1
  end
  return row
end


-- drilly nil=to center, other=coord
function AddDrill(tblPlank, pos, drilly)
  local row

  if drilly==nil then
    drilly=tblPlank.info.height*0.5
  end
  
  row=FindFreeMc()
  ac_objectset("iMcStr", "", row, 1)
  ac_objectset("iMc", 302, row, 1)
  ac_objectset("iMc", pos, row, 2)
  ac_objectset("iMc", drilly, row, 3)
  ac_objectset("iMc", gnDrillDia, row, 4)
  ac_objectset("iMc", 0, row, 5)
  ac_objectset("iMc", 2, row, 6)
  
  for mc=7,16 do
    ac_objectset("iMc", 0, row, mc)
  end
end


-- Adds drilling to top plate
-- Returns: x,y of the vert offseted lines intersection or nil=no intersection
function AddTopDrill(vert, xoff, hor)
  local x, y
  
  x,y=ac_geo("linex", vert.info.elemdata.x1+xoff, vert.info.elemdata.y1, vert.info.elemdata.x2+xoff, vert.info.elemdata.y2, hor.info.elemdata.x1, hor.info.elemdata.y1, hor.info.elemdata.x2, hor.info.elemdata.y2)
  if not x then
    return
  end

  -- Must be close enough to both lines
  local dist1, len1, totlen1
  local dist2, len2, totlen2
          
  dist1, len1, totlen1=ac_geo ("linedist", vert.info.elemdata.x1+xoff, vert.info.elemdata.y1, vert.info.elemdata.x2+xoff, vert.info.elemdata.y2, x, y)
  dist2, len2, totlen2=ac_geo ("linedist", hor.info.elemdata.x1, hor.info.elemdata.y1, hor.info.elemdata.x2, hor.info.elemdata.y2, x, y)

  if len1<-0.100-math.abs(xoff) or len1>totlen1+0.100+math.abs(xoff) or len2<-gnDrillDia/2 or len2>totlen2+gnDrillDia/2 then
    return
  end
  
  --Add to top plate to y-coordinate center of the stud line
  local drilly,hory,verty1,verty2
  
  hory1=hor.info.elemdata.by1
  hory2=hor.info.elemdata.by2
  if hory2<hory1 then
    hory1,hory2=hory2,hory1
  end
  verty=(vert.info.elemdata.by1+vert.info.elemdata.by2)*0.5
  drilly=verty-hory1

--ac_environment("tolog", string.format("hory1=%f hory2=%f verty=%f", hory1, hory2, verty))

  ac_objectopen(hor.guid)
  AddDrill(hor, len2, drilly)
  ac_objectclose()
  
  return x,y
end


function DoDrill(tblSel)
  local tblVert, tblHor, t, infoElem, ndrills, x, y, k, v
  

  -- Build 2D map lines of the planks (assume the same element)
  tblVert={}
  tblHor={}
  for k,v in pairs(tblSel) do
      t={}
      t.guid=v
      ac_objectopen(v)
      t.info=af_request("plankinfo")
      if not t.info.ownerelemguid then
        ac_environment("tolog", string.format("Skipping plank id=%s - not part of an element", ac_objectget("#id")))
      else
        -- Part of an element, add its 2D geometry
        infoElem=af_request("plankinfo", t.info.ownerelemguid)
        t.info=af_request("plankinfo", nil, infoElem)   -- Sets elemdata
        t.info.elemdata.y1, t.info.elemdata.z1=t.info.elemdata.z1, t.info.elemdata.y1   -- Z was what we need to have as y
        t.info.elemdata.y2, t.info.elemdata.z2=t.info.elemdata.z2, t.info.elemdata.y2
--ac_environment("tolog", string.format("x1=%f y1=%f z1=%f x2=%f y2=%f z2=%f", t.info.elemdata.x1, t.info.elemdata.y1, t.info.elemdata.z1, t.info.elemdata.x2, t.info.elemdata.y2, t.info.elemdata.z2))

        if math.abs(t.info.elemdata.x2-t.info.elemdata.x1)<0.010 then
          tblVert[#tblVert+1]=t
        else
          tblHor[#tblHor+1]=t
        end
      end
      ac_objectclose()
  end
  
  -- Sort vertical studs
  table.sort(tblVert, function(p1,p2)
      return p1.info.elemdata.x1<p2.info.elemdata.x1
    end)
  
  -- Process all stud groups
  local i1, i2

  ndrills=0
  i1=1
  while i1<=#tblVert do
    -- Scan for stud group
    i2=i1+1
    while i2<=#tblVert do
      if tblVert[i2].info.elemdata.x1-tblVert[i2-1].info.elemdata.x1>gnDistTop then
        break
      end
      i2=i2+1
    end
    
    local x1, x2, i3, hor, y1stud, y2stud, y2
    
    x1=tblVert[i1].info.elemdata.x1-gnDistTop
    x2=tblVert[i2-1].info.elemdata.x2+gnDistTop
    
    -- We have i1 - i2-1 studs, find intersecting horizontal pieces
    y1stud=nil
    y2stud=nil
    for i3=1,#tblHor do
      hor=tblHor[i3]

      x,y=AddTopDrill(tblVert[i1], -gnDistTop, hor)
      if y then
        -- Save min&max y for gable walls. First adjust y to be relative to the stud and decrease distance from top
        y=tblVert[i1].info.elemdata.y2
        if tblVert[i1].info.elemdata.y1>y then
          y=tblVert[i1].info.elemdata.y1      -- Upside down
        end
        y=y-gnDistStud

        if not y1stud or y<y1stud then
          y1stud=y
        end
        if not y2stud or y>y2stud then
          y2stud=y
        end
        
        ndrills=ndrills+1
      end
    
      -- Group or not, add last stud's drilling to top
      x,y=AddTopDrill(tblVert[i2-1], gnDistTop, hor)
      if y then
        -- Save min&max y for gable walls. First adjust y to be relative to the stud and decrease distance from top
        y=tblVert[i1].info.elemdata.y2
        if tblVert[i1].info.elemdata.y1>y then
          y=tblVert[i1].info.elemdata.y1      -- Upside down
        end
        y=y-gnDistStud

        if not y1stud or y<y1stud then
          y1stud=y
        end
        if not y2stud or y>y2stud then
          y2stud=y
        end
        
        ndrills=ndrills+1
      end
    end
    
    if y1stud then
      -- Use minimum y to drill the studs
      i3=i1
      while i3<i2 do
        local dist1, len1, totlen1
      
        t=tblVert[i3]
        x,y=ac_geo("linex", t.info.elemdata.x1, t.info.elemdata.y1, t.info.elemdata.x2, t.info.elemdata.y2, -1, y1stud, 1, y1stud)
        dist1, len1, totlen1=ac_geo ("linedist", t.info.elemdata.x1, t.info.elemdata.y1, t.info.elemdata.x2, t.info.elemdata.y2, x, y)
        ac_objectopen(t.guid)
        AddDrill(t, len1)
        ac_objectclose()
        ndrills=ndrills+1

        i3=i3+1
      end
    end

    i1=i2
  end
  
  return ndrills
end


function Do()
  local tblSel, tblSettings, t, count
  local bRes,sErr

  tblSel=af_request ("getselplanks")
  if tblSel==nil then
    return "Please select planks"
  end
  
  tblSettings={}
  tblSettings[1]      ={}
  tblSettings[1].cfgonly =1
  tblSettings[1].type    =3
  tblSettings[1].prompt  ="Drill diameter"
  tblSettings[1].key    ="drilldia"
  tblSettings[1].defvalue  =0.030

  tblSettings[2]      ={}
  tblSettings[2].cfgonly =1
  tblSettings[2].type    =3
  tblSettings[2].prompt  ="Distance in top plate from stud middle"
  tblSettings[2].key    ="disttop"
  tblSettings[2].defvalue  =0.100

  tblSettings[3]      ={}
  tblSettings[3].cfgonly =1
  tblSettings[3].type    =3
  tblSettings[3].prompt  ="Distance from stud top"
  tblSettings[3].key    ="diststud"
  tblSettings[3].defvalue  =0.200

  bRes,sErr=ac_optiondlg("LDLD", "Lifting drills", tblSettings)
  if not bRes then
    return
  end
  
  gnDrillDia=tblSettings[1].value
  gnDistTop=tblSettings[2].value
  gnDistStud=tblSettings[3].value
  count=DoDrill(tblSel)
  return string.format("Added %d drills", count)
end

gsStatus=Do()
]]>
    </mctool>



    <mctool name="Element lifting drillings floor" name_fin="Elementin nostoreiät lattia" name_pol="Otwory do podnoszenia elementu w stropie">
      <![CDATA[
EPS=0.0001
PI=3.141592653589793
PI180=PI/180.0


function FindFreeMc()
  local rows, row, mc
  
  rows=ac_objectget("iMc", -1)
  row=1
  while row<=rows do
    mc=ac_objectget("iMc", row, 1)
    if not mc or mc==0 then
      break
    end
    row=row+1
  end
  return row
end


-- drilly nil=to center, other=coord
function AddDrill(side1, drillx, drilly)
  local row

  row=FindFreeMc()
  ac_objectset("iMcStr", "", row, 1)
  ac_objectset("iMc", 302, row, 1)
  ac_objectset("iMc", drillx, row, 2)
  ac_objectset("iMc", drilly, row, 3)
  ac_objectset("iMc", gnDrillDia, row, 4)
  ac_objectset("iMc", 0, row, 5)
  ac_objectset("iMc", side1, row, 6)
  
  for mc=7,16 do
    ac_objectset("iMc", 0, row, mc)
  end
end


function CalcDot3D( x1, y1, z1, x2, y2, z2 )
	return x1 * x2 + y1 * y2 + z1 * z2;
end


-- Transforms xy-coordinates from sideSource to sideTarget. Botha are plankinfo.tblSides-kind of worlds
-- Returns x,y
function TransformCoord(sideTarget, sideSource, x, y)
  local x3, y3, z3, xres, yres

  x3=sideSource.origc.x + x * sideSource.vecx.x + y * sideSource.vecy.x
  y3=sideSource.origc.y + x * sideSource.vecx.y + y * sideSource.vecy.y
  z3=sideSource.origc.z + x * sideSource.vecx.z + y * sideSource.vecy.z
  
  -- Then to target
  x3=x3-sideTarget.origc.x
  y3=y3-sideTarget.origc.y
  z3=z3-sideTarget.origc.z
  
  xres=CalcDot3D(x3, y3, z3, sideTarget.vecx.x, sideTarget.vecx.y, sideTarget.vecx.z)
  yres=CalcDot3D(x3, y3, z3, sideTarget.vecy.x, sideTarget.vecy.y, sideTarget.vecy.z)
  
--ac_environment("tolog", string.format("TransformCoord %f %f -> %f %f", x, y, xres, yres))
  return xres, yres
end


-- Adds drill to all items in selection
-- Returns: nil=ok, str=error msg
function DoDrill(clickres, count)
  local i, v, info

  if false then
    -- Dump result
    ac_environment("tolog", string.format("begc.x=%f begc.y=%f begc.z=%f", clickres.begc.x, clickres.begc.y, clickres.begc.z))
    if clickres.endc then
      ac_environment("tolog", string.format("endc.x=%f endc.y=%f endc.z=%f", clickres.endc.x, clickres.endc.y, clickres.endc.z))
    end

    for i,v in ipairs(clickres.elems) do
      ac_environment("tolog", string.format("%d: guid=%s side1=%d x1=%f y1=%f", i, v.guid, v.side1, v.x1, v.y1))
    end
  end
  
  -- First find a board and use its geometry world
  local sideWorld, tblBoards
  
  tblBoards={}
  for i,v in ipairs(clickres.elems) do
    info=af_request("plankinfo", v.guid)
    if info.masterelemguid then
      -- Switch to master
      v.guid=info.masterelemguid
      info=af_request("plankinfo", v.guid)
    end
    v.info=info
    
    if info.type==4 then
      tblBoards[#tblBoards+1]=v
      if not sideWorld then
        sideWorld=info.tblSides[v.side1]
        sideWorld.x=v.x1
        sideWorld.y=v.y1
        -- Nope, switch to masters for all: break
      end
    end
  end
  
  if not sideWorld then
    gsStatus="Please select at least one board also"
    return 0
  end
  
  -- Then convert all planks int to 2D of the selected world. Pick first plank as reference plank
  local t, tblPlanks, tblPlank1, dummy
  local w2, side

  tblPlanks={}
  for i,v in ipairs(clickres.elems) do
    info=v.info   --af_request("plankinfo", v.guid, geoWorld)
    if info.type==1 or info.type==2 then
      -- it is a plank
      t={}
      t.info=info
      t.clickres=v
      
      -- Calc dest surface's middle line as our ref line
      side=info.tblSides[v.side1]
      t.width=side.dy
      w2=t.width * 0.5

--ac_environment("tolog", string.format("side.origc.x=%f side.origc.y=%f side.origc.z=%f side.dx=%f side.dy=%f", side.origc.x, side.origc.y, side.origc.z, side.dx, side.dy))
--ac_environment("tolog", string.format("side.vecx.x=%f side.vecx.y=%f side.vecx.z=%f side.vecy.x=%f side.vecy.y=%f side.vecy.z=%f", side.vecx.x, side.vecx.y, side.vecx.z, side.vecy.x, side.vecy.y, side.vecy.z))
      t.x1,t.y1=TransformCoord(sideWorld, side, 0, w2)
      t.x2,t.y2=TransformCoord(sideWorld, side, side.dx, w2)
      
      
      t.dx=t.x2 - t.x1
      t.dy=t.y2 - t.y1
      t.len=math.sqrt(t.dx * t.dx + t.dy * t.dy)
      if t.len>0.0001 then
        t.dx=t.dx/t.len
        t.dy=t.dy/t.len
        
        if not tblPlank1 then
          t.dist=0
          tblPlank1=t
        else
          t.dist=ac_geo("linedist", tblPlank1.x1, tblPlank1.y1, tblPlank1.x2, tblPlank1.y2, t.x1, t.y1)
          
          if math.abs(CalcDot3D(t.dx, t.dy, 0, tblPlank1.dx, tblPlank1.dy, 0))<0.99 then
            ac_environment("tolog", "Non-parallel planks in selection - operation may fail")
            t=nil
          end
        end
        
        if t then
          dummy,t.distfrombeg=ac_geo("linedist", t.x1, t.y1, t.x2, t.y2, sideWorld.x, sideWorld.y)

--ac_environment("tolog", string.format("t.x1=%f, t.y1=%f, t.x2=%f, t.y2=%f, geoWorld.x=%f, geoWorld.y=%f t.distfrombeg=%f t.dist=%f", t.x1, t.y1, t.x2, t.y2, geoWorld.x, geoWorld.y, t.distfrombeg, t.dist))

          if t.distfrombeg>-gnDrillDia*0.5 and t.distfrombeg<t.len+gnDrillDia*0.5 then
            tblPlanks[#tblPlanks+1]=t
          end
        end
      end
    end
  end

  -- We have collected just planks related to current clicking position
  -- Sort planks by distance to reference to find planks touching each other
  table.sort(tblPlanks, function(p1,p2)
      return p1.dist<p2.dist
    end)

  local i2, dist, yc, side, ndrill
  
  ndrill=0
  i=1
  while i<=#tblPlanks do
    -- Add drills to planks as long as they are touching i2 one past last processed
    drillfromtop=nil
    i2=i
    while true do
      -- Add drilling to the plank, calc yc
      v=tblPlanks[i2]
      side=2
      if v.clickres.side1==2 or v.clickres.side1==4 then
        side=1
      end
      yc=v.info.tblSides[side].dy*0.5
      
      if i2~=i then
        -- Not the first one - project the drilling yc-coord to next ones from the first one TODO ******************************
      end
      
      ac_objectopen(v.info.guid)
--ac_environment("tolog", string.format("Adding plank drill to side=%d x=%f y=%f", side, v.distfrombeg, yc))
      AddDrill(side, v.distfrombeg, yc)
      ndrill=ndrill+1
      ac_objectclose()

      i2=i2+1
      if i2>#tblPlanks then
        break
      end

      dist=ac_geo("linedist", tblPlanks[i2].x1, tblPlanks[i2].y1, tblPlanks[i2].x2, tblPlanks[i2].y2, tblPlanks[i2-1].x1, tblPlanks[i2-1].y1)
      if math.abs(dist) > tblPlanks[i2].width*0.5 + tblPlanks[i2-1].width*0.5 + gnDrillDia then
        break
      end
    end
    
    -- Add drilling to all boards intersecting with the drilling, calc points on the first and last plank and extend by distance to the board
    local x1, x2, y1, y2, dx, dy, len2
    
    x1=tblPlanks[i].x1 + tblPlanks[i].dx * tblPlanks[i].distfrombeg - tblPlanks[i].dy * (tblPlanks[i].width * 0.5 + gnDistBoard)
    y1=tblPlanks[i].y1 + tblPlanks[i].dy * tblPlanks[i].distfrombeg + tblPlanks[i].dx * (tblPlanks[i].width * 0.5 + gnDistBoard)
    
    x2=tblPlanks[i2-1].x1 + tblPlanks[i2-1].dx * tblPlanks[i2-1].distfrombeg + tblPlanks[i2-1].dy * (tblPlanks[i2-1].width * 0.5 + gnDistBoard)
    y2=tblPlanks[i2-1].y1 + tblPlanks[i2-1].dy * tblPlanks[i2-1].distfrombeg - tblPlanks[i2-1].dx * (tblPlanks[i2-1].width * 0.5 + gnDistBoard)

    -- Then scan all boards and add drillings to them
    local bi, bv, xb, yb
    
    for bk,bv in ipairs(tblBoards) do
      ac_objectopen(bv.guid)
      -- Convert drill coordinate from sideWorld to current target side
      xb,yb = TransformCoord(bv.info.tblSides[bv.side1], sideWorld, x1, y1)
      AddDrill(bv.side1, xb, yb)
--ac_environment("tolog", string.format("Drill from x1=%f y1=%f to side=%d x=%f y=%f", x1, y1, bv.side1, xb, yb))
      
      xb,yb = TransformCoord(bv.info.tblSides[bv.side1], sideWorld, x2, y2)
      AddDrill(bv.side1, xb, yb)
--ac_environment("tolog", string.format("Drill from x2=%f y2=%f to side=%d x=%f y=%f", x2, y2, bv.side1, xb, yb))

      ac_objectclose()
    end

--ac_environment("tolog", string.format("Group beg=%d, last+1=%d", i, i2))

    i=i2
  end
  
  return ndrill
end


function Do()
  local tblSel, tblSettings, t, count
  local bRes,sErr

  tblSel=ac_environment("getsel")
  if tblSel==nil then
    return "Please select planks and boards"
  end
  
  tblSettings={}
  tblSettings[1]      ={}
  tblSettings[1].cfgonly =1
  tblSettings[1].type    =3
  tblSettings[1].prompt  ="Drill diameter"
  tblSettings[1].key    ="drilldia"
  tblSettings[1].defvalue  =0.030

  tblSettings[2]      ={}
  tblSettings[2].cfgonly =1
  tblSettings[2].type    =3
  tblSettings[2].prompt  ="Distance in top boards from beam sides"
  tblSettings[2].key    ="distboard"
  tblSettings[2].defvalue  =0.023

  gHelpAnchor="afdlg_floordrills"
  bRes,sErr=ac_optiondlg("LDFD", "Lifting drills for floors", tblSettings)
  if not bRes then
    return
  end
  
  gnDrillDia=tblSettings[1].value
  gnDistBoard=tblSettings[2].value
  
  count=0
  -- Does not work since drills are added after we return from here: while true do
    -- Ask user to click the lifting position
    tblSettings={}
    tblSettings.line=false
    tblSettings.prompt="Please click the lifting position, esc to cancel"
    tblSettings.elems=tblSel
    t=af_request("afclick", tblSettings)
    if t then
      gsStatus=""
      count=count + DoDrill(t)
      if gsStatus~="" then
        return gsStatus     -- Error in adding
      end
    end

  -- end
  
  return string.format("Drilled %d planks", count)
end

gsStatus=Do()
]]>
    </mctool>

    <mctool name="Support blocks with surrounding drillings">
      <![CDATA[
EPS=0.001
PI=3.141592653589793
PI180=PI/180.0

local PLANK_SIDE = {
  TOP    = 1,
  FRONT  = 2,
  BOTTOM = 3,
  BACK   = 4
}

-- Dumps given variable into string
function DumpTblInt(o, nIndent)
  local s,k,v

  if type(o) == 'table' then
    s = '{\n'
    for i = 0, nIndent do
      s = s .. '\t'
    end
    for k,v in pairs(o) do
      if type(k) ~= 'number' then k = '"'..k..'"' end
      s = s .. '['..k..'] = ' .. DumpTblInt(v, nIndent + 1) .. ',\n'
      for i = 0, nIndent do
        s = s .. '\t'
      end
    end

    if string.len(s) > 1 then
      if string.sub(s, -1) == '\t' then
        s = string.sub(s, 1, -2)
      end
    end

    s=s .. '}'
  else
    s = ""
    for i = 0, nIndent do
      s = s .. '\t'
    end
    s=tostring(o)
  end
  return s
end


function DumpTbl(o)
  ac_environment("tolog", DumpTblInt(o, 0))
end


function FindFreeMc()
  local rows, row, mc

  rows=ac_objectget("iMc", -1)
  row=1
  while row<=rows do
    mc=ac_objectget("iMc", row, 1)
    if not mc or mc==0 then
      break
    end
    row=row+1
  end
  return row
end


function TernaryIf(cond, T , F )
  if cond then return T else return F end
end


function AlmostEq(a, b)
  if a==nil and b==nil then
    return true
  elseif a==nil or b==nil then
    return false
  end

  return math.abs(a-b)<=EPS
end


function AlmostEq2D(a, b)
  return AlmostEq(a.x, b.x) and AlmostEq(a.y, b.y)
end


function Add3D(vec1, vec2)
  return {x=vec1.x+vec2.x, y=vec1.y+vec2.y, z=vec1.z+vec2.z}
end


function Scale3D(vec, length)
  return {x=vec.x*length, y=vec.y*length, z=vec.z*length}
end


function Add2D(vec1, vec2)
  return {x=vec1.x+vec2.x, y=vec1.y+vec2.y}
end


function Sub2D(vec2, vec1)
  return {x=vec2.x-vec1.x, y=vec2.y-vec1.y}
end


function Magnitude2D(vec)
  return math.sqrt(vec.x*vec.x+vec.y*vec.y)
end


function Distance2D(p1, p2)
  return Magnitude2D(Sub2D(p2, p1))
end


function Normalize2D(vec)
  local magnitude=Magnitude2D(vec)
  return {x=vec.x/magnitude, y=vec.y/magnitude}
end


function Dir2D(p1, p2) 
  return Normalize2D(Sub2D(p2, p1))
end


function Dot2D(v1, v2)
  return v1.x*v2.x+v1.y*v2.y 
end


function Dot3D(v1, v2)
  return v1.x*v2.x+v1.y*v2.y+v1.z*v2.z 
end


function Scale2D(vec, length) 
  return {x=vec.x*length, y=vec.y*length}
end


function Flip2D(vec) 
  return Scale2D(vec, -1)
end


function FlipRight2D(vec)
  return {x=vec.y, y=-vec.x}
end


function FlipLeft2D(vec)
  return {x=-vec.y, y=vec.x}
end


function GetNextIdxWrapAround(table, i)
  return (i % #table) + 1
end


function GetNextValueWrapAround(table, i)
  return table[GetNextIdxWrapAround(table, i)]
end


function LineX(lineA, lineB)
  local x, y=ac_geo(
    "linex", 
    lineA.begPt.x, 
    lineA.begPt.y, 
    lineA.endPt.x, 
    lineA.endPt.y, 
    lineB.begPt.x, 
    lineB.begPt.y, 
    lineB.endPt.x, 
    lineB.endPt.y
  )
  
  if x==nil then
    return nil
  end

  return {x=x, y=y}
end


function LineDist(point, segment)
  return ac_geo(
    "linedist", 
    segment.begPt.x, 
    segment.begPt.y,
    segment.endPt.x, 
    segment.endPt.y, 
    point.x,
    point.y
  )  
end


function IsPointOnInfLine(point, segment)
  local dx, dy, length=LineDist(point, segment)
  return math.abs(dx)<EPS
end


function AddAngledDrill(x, y, diameter, angle, side)
  local x1=x-diameter*0.5
  local x2=x+diameter*0.5
  local y1=y-diameter*0.5
  local y2=y1
  local row=FindFreeMc()

  ac_objectset("iMcStr", "",    row, 1)
  ac_objectset("iMc", 301,      row, 1)
  ac_objectset("iMc", x1,       row, 2)          
  ac_objectset("iMc", y1,       row, 3)
  ac_objectset("iMc", x2,       row, 4)
  ac_objectset("iMc", y2,       row, 5)
  ac_objectset("iMc", 50,       row, 6)  -- Depth
  ac_objectset("iMc", diameter, row, 7)
  ac_objectset("iMc", 0,        row, 8)  -- Angle around x-axis
  ac_objectset("iMc", side,     row, 9)  
  ac_objectset("iMc", angle,    row, 10)
  ac_objectset("iMc", 8,        row, 11) -- Groove type (8=Drilling)

  for mc=12,16 do
    ac_objectset("iMc", 0, row, mc)
  end
end


function AddStraightDrill(x, y, diameter, side)
  local row=FindFreeMc()
  ac_objectset("iMcStr", "",       row, 1)
  ac_objectset("iMc",    302,      row, 1)
  ac_objectset("iMc",    x,        row, 2)           
  ac_objectset("iMc",    y,        row, 3)           
  ac_objectset("iMc",    diameter, row, 4)
  ac_objectset("iMc",    0,        row, 5)
  ac_objectset("iMc",    side,     row, 6)        

  for mc=7,16 do
    ac_objectset("iMc", 0, row, mc)
  end
end


function AddDrill(x, y, diameter, angle, sideNr)
  if AlmostEq(angle, 0.0) then
    AddStraightDrill(x, y, diameter, sideNr)
  else
    AddAngledDrill(x, y, diameter, angle, sideNr)
  end
end


function GuidToPlankIndex(guid)
  for i=1, gnPlanks do
    ac_objectopen(string.format("#%d",i))
    local info=af_request("plankinfo")
    ac_objectclose()
    if info.guid==guid then
      return i
    end
  end
  return -1
end


function GetRotIndependentInfo(plank)
  local begPt={x=plank.elemdata.x1, y=plank.elemdata.y1}
  local endPt={x=plank.elemdata.x2, y=plank.elemdata.y2}
  local dir=Dir2D(begPt, endPt)
  local frontSide={
    connections={},
    parallel=nil,
    prevSide=nil,
    nextSide=nil,
    visited=false
  }

  local backSide={
    connections={},
    parallel=nil,
    prevSide=nil,
    nextSide=nil,
    visited=false
  }

  if AlmostEq(plank.elemdata.rotangle, 0) then
    local sideVec=Scale2D(FlipLeft2D(dir), plank.width*0.5)
    frontSide.sideNr=PLANK_SIDE.FRONT
    frontSide.fullSegment={
      begPt=Add2D(begPt, sideVec),
      endPt=Add2D(endPt, sideVec)
    }
    backSide.sideNr=PLANK_SIDE.BACK
    backSide.fullSegment={
      begPt=Add2D(begPt, Flip2D(sideVec)),
      endPt=Add2D(endPt, Flip2D(sideVec))
    }
  elseif AlmostEq(plank.elemdata.rotangle, -180) or AlmostEq(plank.elemdata.rotangle, 180) then
    local sideVec=Scale2D(FlipRight2D(dir), plank.width*0.5)
    frontSide.sideNr=PLANK_SIDE.BACK
    frontSide.fullSegment={
      begPt=Add2D(begPt, sideVec),
      endPt=Add2D(endPt, sideVec)
    }
    backSide.sideNr=PLANK_SIDE.FRONT
    backSide.fullSegment={
      begPt=Add2D(begPt, Flip2D(sideVec)),
      endPt=Add2D(endPt, Flip2D(sideVec))
    }
  elseif AlmostEq(plank.elemdata.rotangle, -90) then
    frontSide.sideNr=PLANK_SIDE.BOTTOM
    frontSide.fullSegment={
      begPt=begPt, 
      endPt=endPt
    }
    local sideVec=Scale2D(FlipRight2D(dir), plank.height)
    backSide.sideNr=PLANK_SIDE.TOP
    backSide.fullSegment={
      begPt=Add2D(begPt, sideVec),
      endPt=Add2D(endPt, sideVec)
    }

  elseif AlmostEq(plank.elemdata.rotangle, 90) then
    local sideVec=Scale2D(FlipLeft2D(dir), plank.height)
    frontSide.sideNr=PLANK_SIDE.TOP
    frontSide.fullSegment={
      begPt=Add2D(begPt, sideVec),
      endPt=Add2D(endPt, sideVec)
    }

    backSide.sideNr=PLANK_SIDE.BOTTOM
    backSide.fullSegment={
      begPt=begPt, 
      endPt=endPt
    }
  else 
    return nil
  end


  --Find the two edges in the polygon that has the same direction as the plank, must be frontSide and backSide.
  --Works cause polygon has clock-wise winding order.
  for i=1, #plank.elemdata.poly do
    local begPt=plank.elemdata.poly[i]
    local endPt=GetNextValueWrapAround(plank.elemdata.poly, i)
    local edgeDir=Dir2D(begPt, endPt)

    -- Same direction
    if math.abs(Dot2D(dir, edgeDir)-1.0)<EPS then 
      backSide.polySegment={begPt=begPt, endPt=endPt}
    -- Opposite direction
    elseif math.abs(Dot2D(dir, edgeDir)+1.0)<EPS then
      frontSide.polySegment={begPt=endPt, endPt=begPt}
    end
  end

  return {
    guid=plank.guid,
    dir=dir,
    z1=plank.elemdata.bz1,
    thickness=plank.elemdata.bz2-plank.elemdata.bz1,
    frontSide=frontSide,
    backSide=backSide
  }
end


function CalculateSideConnections(sourceInfo, targetSide, targetInfo)

  local dx1, dy1, length=LineDist(sourceInfo.frontSide.polySegment.begPt, targetSide.polySegment)
  local dx2, dy2, _     =LineDist(sourceInfo.backSide.polySegment.begPt, targetSide.polySegment)
  local frontBegInLineSeg=math.abs(dx1)<EPS and EPS<dy1 and dy1<length-EPS
  local frontBegOnLineSeg=frontBegInLineSeg and  -EPS<dy1 and dy1<length+EPS
  local backBegInLineSeg=math.abs(dx2)<EPS and EPS<dy2 and dy2<length-EPS
  local backBegOnLineSeg=backBegInLineSeg and  -EPS<dy2 and dy2<length+EPS
  
  local dx3, dy3, _     =LineDist(sourceInfo.frontSide.polySegment.endPt, targetSide.polySegment)
  local dx4, dy4, _     =LineDist(sourceInfo.backSide.polySegment.endPt, targetSide.polySegment)
  local frontEndInLineSeg=math.abs(dx3)<EPS and EPS<dy3 and dy3<length-EPS
  local frontEndOnLineSeg=frontEndInLineSeg and  -EPS<dy3 and dy3<length+EPS
  local backEndInLineSeg=math.abs(dx4)<EPS and EPS<dy4 and dy4<length-EPS
  local backEndOnLineSeg=backEndInLineSeg and  -EPS<dy4 and dy4<length+EPS
  
  if (frontBegInLineSeg or  backBegInLineSeg) or 
     (frontBegOnLineSeg and backBegOnLineSeg) then
    table.insert(targetSide.connections, {
      sourceInfo=sourceInfo,
      targetInfo=targetInfo,
      targetSide=targetSide,
      begSide={side=sourceInfo.frontSide, point=sourceInfo.frontSide.polySegment.begPt, onLine=frontBegOnLineSeg}, 
      endSide={side=sourceInfo.backSide, point=sourceInfo.backSide.polySegment.begPt, onLine=backBegOnLineSeg},
      normal=sourceInfo.dir
    })
  elseif (frontEndInLineSeg or  backEndInLineSeg) or 
         (frontEndOnLineSeg and backEndOnLineSeg) then    
    table.insert(targetSide.connections, {
      sourceInfo=sourceInfo,
      targetInfo=targetInfo,
      targetSide=targetSide,
      begSide={side=sourceInfo.frontSide, point=sourceInfo.frontSide.polySegment.endPt, onLine=frontEndOnLineSeg}, 
      endSide={side=sourceInfo.backSide, point=sourceInfo.backSide.polySegment.endPt, onLine=backEndOnLineSeg},
      normal=Flip2D(sourceInfo.dir)
    })
  end
end


function CalculateParallelConnections(sourceInfo, targetSide)
  if IsPointOnInfLine(sourceInfo.frontSide.polySegment.begPt, targetSide.polySegment) and 
     IsPointOnInfLine(sourceInfo.frontSide.polySegment.endPt, targetSide.polySegment) then 
    targetSide.parallel={
      sourceInfo=sourceInfo,
      side=sourceInfo.frontSide
    }
  elseif IsPointOnInfLine(sourceInfo.backSide.polySegment.begPt, targetSide.polySegment) and 
         IsPointOnInfLine(sourceInfo.backSide.polySegment.endPt, targetSide.polySegment) then 
    targetSide.parallel={
      sourceInfo=sourceInfo,
      side=sourceInfo.backSide
    }
  end
end


-- Collect planks groups seperated by their owner 
function CollectConnections(selection)
  local result={}
  for _, GUID in pairs(selection) do
    ac_objectopen(GUID)
    local plank=af_request("plankinfo")
    local elementGUID=plank.ownerelemguid
    if not elementGUID then
      ac_environment("tolog", string.format("Skipping plank id=%s - not part of an element", ac_objectget("#id")))
    else
      local plane=af_request("plankinfo", elementGUID)
      plane.vecy, plane.vecz=plane.vecz, plane.vecy
      plane.begc=Add3D(plane.begc, Scale3D(plane.vecz, -plane.width * 0.5))
      plane.endc=Add3D(plane.endc, Scale3D(plane.vecz, -plane.width * 0.5))
      local plank=af_request("plankinfo", nil, plane)

      if plank.elemdata.rotangle==nil then
        ac_environment(
          "tolog", 
          string.format("(x=%0.2f): Invalid rotation, planks' front, back, top or bottom side must face the element.", 
          plank.elemdata.x1, plank.elemdata.rotangle)
        )
      else
        local sourceInfo=GetRotIndependentInfo(plank)
        if sourceInfo==nil then
          ac_environment(
            "tolog", 
            string.format("(x=%0.2f): Invalid rotation (angle=%0.2f), planks' front, back, top or bottom side must face the element.", 
            plank.elemdata.x1, plank.elemdata.rotangle)
          )
        elseif sourceInfo.backSide.polySegment==nil or sourceInfo.frontSide.polySegment==nil then
          ac_environment("tolog", string.format("(x=%0.2f): Could not find front and back edges with the same direction as the plank.",  plank.elemdata.x1))
        else
          if result[elementGUID]==nil then
            result[elementGUID]={sourceInfo}
          else
            for _, targetInfo in pairs(result[elementGUID]) do
              -- Source end to target beg
              if AlmostEq2D(sourceInfo.frontSide.polySegment.endPt, targetInfo.frontSide.polySegment.begPt) and
                 AlmostEq2D(sourceInfo.backSide.polySegment.endPt, targetInfo.backSide.polySegment.begPt) then
                sourceInfo.frontSide.nextSide=targetInfo.frontSide
                sourceInfo.backSide.nextSide=targetInfo.backSide
                targetInfo.frontSide.prevSide=sourceInfo.frontSide
                targetInfo.backSide.prevSide=sourceInfo.backSide
              
              -- Target end to source beg
              elseif AlmostEq2D(targetInfo.frontSide.polySegment.endPt, sourceInfo.frontSide.polySegment.begPt) and
                     AlmostEq2D(targetInfo.backSide.polySegment.endPt, sourceInfo.backSide.polySegment.begPt) then
                targetInfo.frontSide.nextSide=sourceInfo.frontSide
                targetInfo.backSide.nextSide=sourceInfo.backSide
                sourceInfo.frontSide.prevSide=targetInfo.frontSide
                sourceInfo.backSide.prevSide=targetInfo.backSide
              
              -- Source end to target end  
              elseif AlmostEq2D(sourceInfo.frontSide.polySegment.endPt, targetInfo.backSide.polySegment.endPt) and
                     AlmostEq2D(sourceInfo.backSide.polySegment.endPt, targetInfo.frontSide.polySegment.endPt) then
                  sourceInfo.frontSide.nextSide=targetInfo.backSide
                  targetInfo.backSide.nextSide=sourceInfo.frontSide
                  sourceInfo.backSide.nextSide=targetInfo.frontSide
                  targetInfo.frontSide.nextSide=sourceInfo.backSide
  
              -- Target end to source end
              elseif AlmostEq2D(targetInfo.backSide.polySegment.begPt, sourceInfo.frontSide.polySegment.begPt) and
                     AlmostEq2D(targetInfo.frontSide.polySegment.begPt, sourceInfo.backSide.polySegment.begPt) then
                targetInfo.backSide.prevSide=sourceInfo.frontSide
                sourceInfo.frontSide.prevSide=targetInfo.backSide
                targetInfo.frontSide.prevSide=sourceInfo.backSide
                sourceInfo.backSide.prevSide=targetInfo.frontSide
  
              -- Connections parallel to front/back side
              elseif AlmostEq(math.abs(Dot2D(sourceInfo.dir, targetInfo.dir)), 1.0) then
                CalculateParallelConnections(sourceInfo, targetInfo.frontSide)
                CalculateParallelConnections(sourceInfo, targetInfo.backSide)
                CalculateParallelConnections(targetInfo, sourceInfo.frontSide)
                CalculateParallelConnections(targetInfo, sourceInfo.backSide)
  
              -- Beams connected to the side of another beam
              else
                CalculateSideConnections(sourceInfo, targetInfo.frontSide, targetInfo)
                CalculateSideConnections(sourceInfo, targetInfo.backSide, targetInfo)
                CalculateSideConnections(targetInfo, sourceInfo.frontSide, sourceInfo)
                CalculateSideConnections(targetInfo, sourceInfo.backSide, sourceInfo)
              end
            end
  
            table.insert(result[elementGUID], sourceInfo)
          end
        end
      end
    end
    ac_objectclose()
  end

  return result
end


function SortConnections(side)
  local dir = Dir2D(side.polySegment.begPt, side.polySegment.endPt)
  local function Comparer(connA, connB)
    local _, begDyA, _ = LineDist(connA.begSide.point, side.polySegment)
    local _, endDyA, _ = LineDist(connA.endSide.point, side.polySegment)
    if endDyA < begDyA then
      begDyA = endDyA
    end

    local _, begDyB, _ = LineDist(connB.begSide.point, side.polySegment)
    local _, endDyB, _ = LineDist(connB.endSide.point, side.polySegment)
    if endDyB < begDyB then
      begDyB = endDyB
    end

    return begDyA < begDyB
  end

  table.sort(side.connections, Comparer)

  -- Make sure begside is closest to the start of the segment 
  for _, conn in pairs(side.connections) do
    local _, begDy, _ = LineDist(conn.begSide.point, side.polySegment)
    local _, endDy, _ = LineDist(conn.endSide.point, side.polySegment)
    conn.begSide.dy = begDy
    conn.endSide.dy = endDy
    if conn.endSide.dy < conn.begSide.dy then
      conn.endSide, conn.begSide = conn.begSide, conn.endSide
    end
    
    conn.endSide.targetDir = dir
    conn.endSide.sideDir = FlipLeft2D(conn.normal)
    if Dot2D(conn.endSide.sideDir, conn.endSide.targetDir) < 0.0 then
      conn.endSide.sideDir = Flip2D(conn.endSide.sideDir)
    end

    conn.begSide.targetDir = Flip2D(dir)
    conn.begSide.sideDir = Flip2D(conn.endSide.sideDir)
  end
end

function AddTopDrill(conn, side, dist)
  local angle=0.0
  if gbUseAngledDrillings then
    local dir=FlipLeft2D(Dir2D(conn.targetSide.polySegment.begPt, conn.targetSide.polySegment.endPt))
    if Dot2D(dir, conn.normal)<0.0 then
      dir=Flip2D(dir)
    end
    angle=(math.atan2(conn.normal.y, conn.normal.x)-math.atan2(dir.y, dir.x))/PI180
  end

  local drillPt = Add2D(side.point, Scale2D(side.targetDir, dist+gnDrillDia*0.5))
  local _, dy, _=LineDist(drillPt, conn.targetSide.fullSegment)
  ac_objectopen(conn.targetInfo.guid)
  AddDrill(dy, (conn.sourceInfo.z1-conn.targetInfo.z1)+conn.sourceInfo.thickness*0.5, gnDrillDia, angle, conn.targetSide.sideNr)
  ac_objectclose()

  local nextSide=conn.targetInfo.frontSide
  if nextSide==side then
    nextSide=conn.targetInfo.backSide
  end
  local currentSide = nextSide
  while currentSide.parallel~=nil do
    local nextTargetInfo=currentSide.parallel.sourceInfo
    currentSide=currentSide.parallel.side
    local cutPt=drillPt
    if angle~=0 then
      cutPt=LineX(currentSide.polySegment, {begPt=drillPt, endPt=Add2D(drillPt, conn.normal)})
    end

    local _, dy, _=LineDist(cutPt, currentSide.fullSegment)
    ac_objectopen(nextTargetInfo.guid)
    AddDrill(dy, (conn.sourceInfo.z1-nextTargetInfo.z1)+conn.sourceInfo.thickness*0.5, gnDrillDia, angle, currentSide.sideNr)
    ac_objectclose()

    if nextTargetInfo.frontSide==currentSide then
        currentSide=nextTargetInfo.backSide
    elseif nextTargetInfo.backSide==currentSide then
        currentSide=nextTargetInfo.frontSide
    end
  end
end

 
function AddStudDrills(studGroup, studPoint)
  for _, conn in pairs(studGroup) do
    local _, dy, _=LineDist(studPoint, conn.sourceInfo.frontSide.fullSegment)
    ac_objectopen(conn.sourceInfo.guid)
    AddDrill(dy, conn.sourceInfo.thickness*0.5, gnDrillDia, 0, conn.sourceInfo.frontSide.sideNr)
    ac_objectclose()
  end

  return #studGroup
end


function CreateSupport(point, conn)
  table.insert(gtblCreate, {
    id=gSupportMaterial.id,
    guidsettings=conn.sourceInfo.guid,
    group="strapping_support",
    thickness=gSupportMaterial.thickness,
    height=gSupportMaterial.height,
    x1=point.x,
    x2=point.x,
    y1=point.y,
    y2=point.y,
    z1=conn.sourceInfo.z1,
    z2=conn.sourceInfo.z1+conn.sourceInfo.thickness,
    force=3,
    rotangle=math.atan2(conn.normal.y, -conn.normal.x)/PI180+90
  })

  -- Cutoff plank bfhind groove end 
  local overwhat=""
  if not AlmostEq(Dot2D(conn.sourceInfo.dir, conn.targetInfo.dir), 0.0) then
    if conn.targetSide.sideNr==PLANK_SIDE.FRONT then
      overwhat="overleft=\"1\""
    elseif conn.targetSide.sideNr==PLANK_SIDE.BACK then
      overwhat="overright=\"1\""
    elseif conn.targetSide.sideNr==PLANK_SIDE.TOP then
      overwhat="overbot=\"1\""
    elseif conn.targetSide.sideNr==PLANK_SIDE.BOTTOM then
      overwhat="overtop=\"1\""
    end
  end

  return string.format(
    "<groove target=\"#%d\" operator=\"#%d\">\n" ..
    "  <groove %s></groove>\n" ..
    "</groove>", gnPlanks + #gtblCreate, GuidToPlankIndex(conn.targetInfo.guid), overwhat)
end


function AddDoubleSupports(
    connA, sideA, pointA, distA,
    connB, sideB, pointB, distB, 
    studGroup, operations, supportsAdded, drillsAdded)
  local topDistA=gnDistTop
  local topDistB=gnDistTop
  local studDist=gnDistStud
  local dx=gSupportMaterial.thickness

  if gbCreateSupports then
    operations=operations..CreateSupport(Add2D(pointA, Scale2D(sideA.sideDir, gSupportMaterial.thickness*0.5)), connA)
    operations=operations..CreateSupport(Add2D(pointB, Scale2D(sideB.sideDir, gSupportMaterial.thickness*0.5)), connB)
    topDistA=distA
    topDistB=distB
    studDist=gSupportMaterial.height
    supportsAdded=supportsAdded+2
  end

  drillsAdded=drillsAdded+AddStudDrills(studGroup, Add2D(pointA, Scale2D(connA.normal, studDist+gnDrillDia*0.5)))
  AddTopDrill(connA, sideA, topDistA)
  AddTopDrill(connB, sideB, topDistB)
  drillsAdded=drillsAdded+2
  return operations, drillsAdded, supportsAdded
end


function AddSingleSupport(conn, side, studGroup, operations, drillsAdded, supportsAdded)
  local dx=gSupportMaterial.thickness
  local cos=Dot2D(side.targetDir, side.sideDir)
  if math.abs(cos)<EPS then
    cos=EPS
  end
  local h=dx/cos
  local dy=math.sqrt(h*h-dx*dx)
  local point=Add2D(side.point, Scale2D(conn.normal, -dy))
  local topDist=gnDistTop
  local studDist=gnDistStud

  if gbCreateSupports then
    operations=operations..CreateSupport(Add2D(point, Scale2D(side.sideDir, dx*0.5)), conn)
    topDist=h
    studDist=gSupportMaterial.height
  end

  drillsAdded=drillsAdded+AddStudDrills(studGroup, Add2D(point, Scale2D(conn.normal, studDist+gnDrillDia*0.5)))
  AddTopDrill(conn, side, topDist)
  drillsAdded=drillsAdded+1
  return operations, drillsAdded, supportsAdded
end


function AddSupports(studGroup, operations, drillsAdded, supportsAdded)
  local begConn=studGroup[1]
  local endConn=studGroup[#studGroup]
  local dx=gSupportMaterial.thickness

  if begConn.begSide.onLine and endConn.endSide.onLine then 
    local lowSide=begConn.begSide
    local lowConn=begConn
    local highSide=endConn.endSide
    local highConn=endConn
    local _, dy, length=LineDist(lowSide.point, highSide.side.polySegment)
    if AlmostEq(dy, 0.0) or AlmostEq(dy, length) then
      return AddDoubleSupports(
        lowConn, lowSide, lowSide.point, dx, 
        highConn, highSide, highSide.point, dx, 
        studGroup, operations, drillsAdded, supportsAdded)
    elseif dy<0.0 or length<dy then
      highSide, lowSide=lowSide, highSide
      highConn, lowConn=lowConn, highConn
    end
    local cosHigh=Dot2D(highSide.targetDir, highSide.sideDir)
    if math.abs(cosHigh)<EPS then
      cosHigh=EPS
    end

    local highDist=dx/cosHigh
    local dy=math.sqrt(highDist*highDist-dx*dx)
    local highPt=Add2D(highSide.point, Scale2D(highConn.normal, -dy))
    local lowPt=LineX(lowSide.side.polySegment, {begPt=highPt, endPt=Sub2D(highPt, highSide.sideDir)})

    local cosLow=Dot2D(lowSide.targetDir, lowSide.sideDir)
    if math.abs(cosLow)<EPS then
      cosLow=EPS
    end
    local lowDist=dx/cosLow

    return AddDoubleSupports(
        lowConn, lowSide, lowPt, lowDist, 
        highConn, highSide, highPt, highDist, 
        studGroup, operations, drillsAdded, supportsAdded)
  elseif begConn.begSide.onLine then
    return AddSingleSupport(begConn, begConn.begSide, studGroup, operations, drillsAdded, supportsAdded)
  elseif endConn.endSide.onLine then
    return AddSingleSupport(endConn, endConn.endSide, studGroup, operations, drillsAdded, supportsAdded)
  end

  return operations, supportsAdded, drillsAdded
end



-- Make sure we don't "go back the way we came" if the prev side is the same as the last side
--    
--                   direction: ------->
--     
--     (lastSide)     
--    side.prevSide     side       side.nextSide
--    <-----------  ------------>  ------------>
--  
function GetPrevSide(side, lastSide)
  if side.prevSide==lastSide then
    return side.nextSide, side
  end

  return side.prevSide, side
end


-- Make sure we don't "go back the way we came" if the next side is the same as the last side
--    
--                 direction: <-------
--                                  (lastSide)
--    side.prevSide     side       side.nextSide
--    <-----------  ------------>  <-----------
--         
function GetNextSide(side, lastSide)
  if side.nextSide==lastSide then
    side.polySegment.begPt, side.polySegment.endPt=side.polySegment.endPt, side.polySegment.begPt
    side.nextSide, side.prevSide=side.prevSide, lastSide
  end

  -- Sort by distance to beg, so that we can easily compare distances of subsequent beams
  SortConnections(side)
  return side.nextSide, side
end


function AddSupportsAlongSide(studGroup, side, maxGap, operations, drillsAdded, supportsAdded)
  side.visited=true
  if #side.connections==0 then
    return studGroup, operations, drillsAdded, supportsAdded
  elseif #studGroup==0 then
    studGroup={side.connections[1]}
  end

  -- When starting a new side check if there is enough of a gap to the first beam to 
  -- end the previous support group. 
  local firstConn=side.connections[1]
  if #studGroup>0 and side.prevSide~=nil and #side.prevSide.connections>0 then
    local lastConn=side.prevSide.connections[#side.prevSide.connections]
    
    if lastConn.endSide.onLine and firstConn.begSide.onLine and 
       Distance2D(lastConn.endSide.point, firstConn.begSide.point) > maxGap then
      operations, drillsAdded, supportsAdded=AddSupports(studGroup, operations, drillsAdded, supportsAdded)
      studGroup={firstConn}
    end
  end

  for i=1, #side.connections-1 do
    local currConn=side.connections[i]
    local nextConn=side.connections[i+1]
    table.insert(studGroup, currConn)
    if nextConn.begSide.dy-currConn.endSide.dy>maxGap then
      operations, drillsAdded, supportsAdded=AddSupports(studGroup, operations, drillsAdded, supportsAdded)
      studGroup={nextConn}
    end 
  end

  return studGroup, operations, drillsAdded, supportsAdded
end


function AddSupportsAlongSides(side, maxGap, operations, drillsAdded, supportsAdded)

  -- Rewind to the first side in the connected chain
  local prevSide, side=GetPrevSide(side, nil)
  while prevSide~=nil do
    prevSide, side=GetPrevSide(prevSide, side)
  end

  local studGroup={} -- Current group of connections with gaps < maxGap
  local nextSide, side=GetNextSide(side, nil)
  while nextSide~=nil do
    studGroup, operations, drillsAdded, supportsAdded=AddSupportsAlongSide(studGroup, side, maxGap, operations, drillsAdded, supportsAdded)
    nextSide, side=GetNextSide(nextSide, side)
  end

  -- Last side and connection
  studGroup, operations, drillsAdded, supportsAdded=AddSupportsAlongSide(studGroup, side, maxGap, operations, drillsAdded, supportsAdded)
  if #side.connections>0 and #studGroup>0 then
    table.insert(studGroup, side.connections[#side.connections])
    operations, drillsAdded, supportsAdded=AddSupports(studGroup, operations, drillsAdded, supportsAdded)
  end
  return operations, drillsAdded, supportsAdded
end


function DoSupports(selection, maxGap)

  local drillsAdded=0
  local supportsAdded=0
  for ownerGUID, group in pairs(CollectConnections(selection)) do
    af_request("elem_openparent", ownerGUID)
    af_request("elem_openlayer", ownerGUID)
    gtblCreate={}
    local operations=""
    for _, beam in pairs(group) do
      if not beam.backSide.visited then
        operations, drillsAdded, supportsAdded=AddSupportsAlongSides(beam.backSide, maxGap, operations, drillsAdded, supportsAdded)
      end

      if not beam.frontSide.visited then
        operations, drillsAdded, supportsAdded=AddSupportsAlongSides(beam.frontSide, maxGap, operations, drillsAdded, supportsAdded)
      end
    end

    gxmlOperations="<operations>" .. operations .. "</operations>"
    af_request("elem_createplanks")
    af_request("elem_closeparent", 1)
    af_request("elem_closelayer")
  end

  return drillsAdded, supportsAdded
end


function Do()
  local tblSel, tblMat, tblSorted, tblSettings, t, s, i, v, count
  local bRes, sErr, strSep

  tblMat = af_request("matlist")
  s = ""
  strSep = ""

  tblSorted = {}
  for id,v in pairs(tblMat) do
    tblSorted[v.index] = v
  end

  for i, v in ipairs(tblSorted) do
    s = string.format("%s%s\"%s:%s (%s)\"", s, strSep, i, v.name, v.id)
    strSep = ","
  end

  tblSel = af_request ("getselplanks")
  if tblSel == nil then
    return "Please select planks"
  end

  tblSettings = {}
  tblSettings[1]          = {}
  tblSettings[1].cfgonly  = 1
  tblSettings[1].type     = 3
  tblSettings[1].prompt   = "Drill diameter"
  tblSettings[1].key      = "drilldia"
  tblSettings[1].defvalue = 0.030

  tblSettings[2]          = {}
  tblSettings[2].cfgonly  = 1
  tblSettings[2].type     = 3
  tblSettings[2].prompt   = "Drill distance from stud"
  tblSettings[2].key      = "disttop"
  tblSettings[2].defvalue = 0.100

  tblSettings[3]          = {}
  tblSettings[3].cfgonly  = 1
  tblSettings[3].type     = 3
  tblSettings[3].prompt   = "Drill distance from beam"
  tblSettings[3].key      = "diststud"
  tblSettings[3].defvalue = 0.200

  tblSettings[4]          = {}
  tblSettings[4].cfgonly  = 1
  tblSettings[4].type     = 2
  tblSettings[4].prompt   = "Create supports"
  tblSettings[4].key      = "createSupports"
  tblSettings[4].defvalue = 0

  tblSettings[5]            = {}
  tblSettings[5].cfgonly    = 0
  tblSettings[5].type       = 1
  tblSettings[5].prompt     = "Support material"
  tblSettings[5].key        = "supportMaterial"
  tblSettings[5].valuelist  = s
  tblSettings[5].defvalue   = 1

  tblSettings[6]          = {}
  tblSettings[6].cfgonly  = 1
  tblSettings[6].type     = 2
  tblSettings[6].prompt   = "Use angled drillings on gable roofs"
  tblSettings[6].key      = "useangleddrillingss"
  tblSettings[6].defvalue = 1

  bRes, sErr = ac_optiondlg("LDLD", "Support blocks with surrounding drillings", tblSettings)
  if not bRes then
    return
  end

  gnDrillDia   = tblSettings[1].value
  gnDistTop    = tblSettings[2].value
  gnDistStud   = tblSettings[3].value

  if tblSettings[4].value == 1 then
    gbCreateSupports = true
  else
    gbCreateSupports = false
  end

  for k, v in pairs(tblMat) do
    if v.index == tblSettings[5].value then
      gSupportMaterial = v
    end
  end

  if tblSettings[6].value == 1 then
    gbUseAngledDrillings = true
  else
    gbUseAngledDrillings = false
  end

  local drillsAdded, supportsAdded=DoSupports(tblSel, gSupportMaterial.thickness*2)
  local info=""
  if drillsAdded > 0 then
    info = string.format("Added %d drills", drillsAdded)
    if supportsAdded > 0 then
      info = info .. string.format(", %d supports", supportsAdded)
    end
  end
  
  return info
end

gsStatus = Do()
]]>
    </mctool>
  </mctools>
</archiframe>
