<?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>
        </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>
    </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>

    <!-- 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>

    <!-- 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>
    </plankdefaults>

    <!-- To guide cnc-related operations -->
    <cnclimits gromaxdepth="0.160" nailmindistplank="0.0031" nailmindistboard="0.0031" elemgeo="1"></cnclimits>

    <dimpresets>
      <dimpreset name="Settings from dim tool" name_fin="Asetukset mittatyökalusta" name_ger="Einstellungen vom Vermessungswerkzeug">
      </dimpreset>

      <dimpreset name="C/C text to front" name_fin="C/C teksti alkuun" name_ger="C/C Text am Anfang" 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" 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" 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" 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 planks" name_fin="Näytä kapulat" openundo="0">
        <![CDATA[
ac_environment("layer", "af *", 1)
ac_environment("rebuild", 1)
]]>
      </script>
      <script name="Hide planks" name_fin="Piilota kapulat" 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

-- 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 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 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")))

  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">
    </material>

    <material id="22x100" name="22x100" thickness="0.022" height="0.100" shape="block" maxlen="99" m3factor="0.000">
    </material>

    <material id="42x42" name="42x42" thickness="0.042" height="0.042" shape="block" maxlen="99" m3factor="0.000">
    </material>

    <material id="42x73" name="42x73" thickness="0.042" height="0.073" shape="block" maxlen="6" m3factor="0.000">
    </material>

    <material id="42x98" name="42x98" thickness="0.042" height="0.098" shape="block" maxlen="6" m3factor="0.000">
    </material>

    <material id="42x123" name="42x123" thickness="0.042" height="0.123" shape="block" maxlen="6" m3factor="0.000">
    </material>

    <material id="42x148" name="42x148" thickness="0.042" height="0.148" shape="block" maxlen="6" m3factor="0.000">
    </material>

    <material id="42x173" name="42x173" thickness="0.042" height="0.173" shape="block" maxlen="6" m3factor="0.000">
    </material>

    <material id="42x198" name="42x198" thickness="0.042" height="0.198" shape="block" maxlen="6" m3factor="0.000">
    </material>

    <material id="42x220" name="42x220" thickness="0.042" height="0.220" shape="block" maxlen="10" m3factor="0.000">
    </material>

    <material id="48x40" name="48x40" thickness="0.048" height="0.040" shape="block" maxlen="6" m3factor="0.000">
    </material>

    <material id="48x48" name="48x48" thickness="0.048" height="0.048" shape="block" maxlen="6" m3factor="0.000">
    </material>

    <material id="48x73" name="48x73" thickness="0.048" height="0.073" shape="block" maxlen="6" m3factor="0.000">
    </material>

    <material id="48x98" name="48x98" thickness="0.048" height="0.098" shape="block" maxlen="6" m3factor="0.000">
    </material>

    <material id="48x123" name="48x123" thickness="0.048" height="0.123" shape="block" maxlen="6" m3factor="0.000">
    </material>

    <material id="48x148" name="48x148" thickness="0.048" height="0.148" shape="block" maxlen="6" m3factor="0.000">
    </material>

    <material id="48x173" name="48x173" thickness="0.048" height="0.173" shape="block" maxlen="6" m3factor="0.000">
    </material>

    <material id="48x198" name="48x198" thickness="0.048" height="0.198" shape="block" maxlen="6" m3factor="0.000">
    </material>

    <material id="48x220" name="48x220" thickness="0.048" height="0.220" shape="block" maxlen="10" m3factor="0.000">
    </material>

    <material id="KP 39x66" name="KP 39x66" thickness="0.039" height="0.066" shape="block" maxlen="6" m3factor="0.000">
    </material>

    <material id="KP 39x92" name="KP 39x92" thickness="0.039" height="0.092" shape="block" maxlen="6" m3factor="0.000">
    </material>

    <material id="KP 45x200" name="KP 45x200" thickness="0.045" height="0.200" shape="block" maxlen="12" m3factor="0.000">
    </material>

	<material id="LP 90x225" name="LP 90x225" thickness="0.090" height="0.225" shape="block" maxlen="99" m3factor="0.000">
    </material>

    <material id="LP 90x270" name="LP 90x270" thickness="0.090" height="0.270" shape="block" maxlen="99" m3factor="0.000">
    </material>

    <material id="LP 90x315" name="LP 90x315" thickness="0.090" height="0.315" shape="block" maxlen="99" m3factor="0.000">
    </material>

    <material id="LP 90x360" name="LP 90x360" thickness="0.090" height="0.360" shape="block" maxlen="99" m3factor="0.000">
    </material>

    <material id="LP 115x225" name="LP 115x225" thickness="0.115" height="0.225" shape="block" maxlen="99" m3factor="0.000">
    </material>

    <material id="LP 115x270" name="LP 115x270" thickness="0.115" height="0.270" shape="block" maxlen="99" m3factor="0.000">
    </material>

    <material id="LP 115x315" name="LP 115x315" thickness="0.115" height="0.315" shape="block" maxlen="99" m3factor="0.000">
    </material>

    <material id="LP 115x360" name="LP 115x360" thickness="0.115" height="0.360" shape="block" maxlen="99" m3factor="0.000">
    </material>

    <material id="LP 115x405" name="LP 115x405" thickness="0.115" height="0.405" shape="block" maxlen="99" m3factor="0.000">
    </material>

    <material id="LP 140x225" name="LP 140x225" thickness="0.140" height="0.225" shape="block" maxlen="99" m3factor="0.000">
    </material>

    <material id="LP 140x270" name="LP 140x270" thickness="0.140" height="0.270" shape="block" maxlen="99" m3factor="0.000">
    </material>

    <material id="LP 140x315" name="LP 140x315" thickness="0.140" height="0.315" shape="block" maxlen="99" m3factor="0.000">
    </material>

    <material id="LP 140x360" name="LP 140x360" thickness="0.140" height="0.360" shape="block" maxlen="99" m3factor="0.000">
    </material>

    <material id="LP 140x405" name="LP 140x405" thickness="0.140" height="0.405" shape="block" maxlen="99" m3factor="0.000">
    </material>

    <material id="KP 45x300" name="KP 45x300" thickness="0.045" height="0.300" shape="block" maxlen="6" m3factor="0.000">
    </material>
	
    <material id="50x50" name="50x50" thickness="0.050" height="0.050" shape="block" maxlen="6" m3factor="0.000">
    </material>

    <material id="50x100" name="50x100" thickness="0.050" height="0.100" shape="block" maxlen="6" m3factor="0.000">
    </material>

    <material id="20x50" name="20x50" thickness="0.020" height="0.050" shape="block" maxlen="99" m3factor="0.000">
    </material>
	
    <material id="20x70" name="20x70" thickness="0.020" height="0.070" shape="block" maxlen="99" m3factor="0.000">
    </material>

    <material id="32x100" name="32x100" thickness="0.032" height="0.100" shape="block" maxlen="6" m3factor="0.000">
    </material>

    <material id="I 300" name="I 300" thickness="0.047" height="0.300" shape="block" maxlen="6" m3factor="0.000">
      <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">
      <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">
      <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">
      <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">
      <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">
      <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">
      <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>
  </mctools>
</archiframe>
