<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://jimandi.com/SDK/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=WikiSysop</id>
	<title>SDK - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://jimandi.com/SDK/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=WikiSysop"/>
	<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php/Special:Contributions/WikiSysop"/>
	<updated>2026-10-25T11:27:10Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.39.2</generator>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=CadContour&amp;diff=1104</id>
		<title>CadContour</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=CadContour&amp;diff=1104"/>
		<updated>2024-11-18T17:59:41Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: /* Example */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=High Level Objects]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
This object is derived from CadObject and represents a single vector within the job. A CadContour holds a Contour object which contains the actual data for the vector shape. A CadContour is created from a Contour object using the CreateCadContour() method. To access the Contour data from a CadContour object, use the :GetContour() method from the base CadObject class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Properties==&lt;br /&gt;
All the properties for this object are documented in the CadObject base class&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&lt;br /&gt;
'''Note:''' This object inherits all documented methods from the CadObject base class with the following additions&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:InsertToolpathTabAtPoint(Point2D point)===&lt;br /&gt;
&lt;br /&gt;
This method inserts a toolpath tab at the point on the CadContour closest to the specified point. &lt;br /&gt;
&lt;br /&gt;
'''Returns:''' a ToolpathTab object.&lt;br /&gt;
&lt;br /&gt;
::''point (Point2D)  The point where to place the toolpath tab''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
-- VECTRIC LUA SCRIPT&lt;br /&gt;
-- Copyright 2013 Vectric Ltd.&lt;br /&gt;
&lt;br /&gt;
-- Gadgets are an entirely optional add-in to Vectric's core software products. &lt;br /&gt;
-- They are provided 'as-is', without any express or implied warranty, and you make use of them entirely at your own risk.&lt;br /&gt;
-- In no event will the author(s) or Vectric Ltd. be held liable for any damages arising from their use.&lt;br /&gt;
&lt;br /&gt;
-- Permission is granted to anyone to use this software for any purpose, &lt;br /&gt;
-- including commercial applications, and to alter it and redistribute it freely, &lt;br /&gt;
-- subject to the following restrictions:&lt;br /&gt;
&lt;br /&gt;
-- 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.&lt;br /&gt;
-- 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.&lt;br /&gt;
-- 3. This notice may not be removed or altered from any source distribution.&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;mobdebug&amp;quot;).start()&lt;br /&gt;
require &amp;quot;strict&amp;quot;&lt;br /&gt;
&lt;br /&gt;
--[[  ------------------------ main --------------------------------------------------&lt;br /&gt;
|&lt;br /&gt;
|  Entry point for script.  Adds a tab to selected contour&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function main(script_path)&lt;br /&gt;
&lt;br /&gt;
    -- Check we have a job loaded&lt;br /&gt;
    local job = VectricJob()&lt;br /&gt;
&lt;br /&gt;
    if not job.Exists then&lt;br /&gt;
       DisplayMessageBox(&amp;quot;No job open.&amp;quot;)&lt;br /&gt;
       return false&lt;br /&gt;
    end&lt;br /&gt;
		&lt;br /&gt;
	-- get selected contour&lt;br /&gt;
	local selection = job.Selection&lt;br /&gt;
  local cadcontour = selection:GetAt(selection:GetHeadPosition())&lt;br /&gt;
  &lt;br /&gt;
  -- add tab&lt;br /&gt;
  local point = Point2D(2.5,0.3)&lt;br /&gt;
  cadcontour:InsertToolpathTabAtPoint(point)&lt;br /&gt;
	&lt;br /&gt;
    return true&lt;br /&gt;
end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=High Level Objects]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=CadContour&amp;diff=1103</id>
		<title>CadContour</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=CadContour&amp;diff=1103"/>
		<updated>2024-11-18T17:58:58Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=High Level Objects]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
This object is derived from CadObject and represents a single vector within the job. A CadContour holds a Contour object which contains the actual data for the vector shape. A CadContour is created from a Contour object using the CreateCadContour() method. To access the Contour data from a CadContour object, use the :GetContour() method from the base CadObject class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Properties==&lt;br /&gt;
All the properties for this object are documented in the CadObject base class&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&lt;br /&gt;
'''Note:''' This object inherits all documented methods from the CadObject base class with the following additions&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:InsertToolpathTabAtPoint(Point2D point)===&lt;br /&gt;
&lt;br /&gt;
This method inserts a toolpath tab at the point on the CadContour closest to the specified point. &lt;br /&gt;
&lt;br /&gt;
'''Returns:''' a ToolpathTab object.&lt;br /&gt;
&lt;br /&gt;
::''point (Point2D)  The point where to place the toolpath tab''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Example ==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
-- VECTRIC LUA SCRIPT&lt;br /&gt;
-- Copyright 2013 Vectric Ltd.&lt;br /&gt;
&lt;br /&gt;
-- Gadgets are an entirely optional add-in to Vectric's core software products. &lt;br /&gt;
-- They are provided 'as-is', without any express or implied warranty, and you make use of them entirely at your own risk.&lt;br /&gt;
-- In no event will the author(s) or Vectric Ltd. be held liable for any damages arising from their use.&lt;br /&gt;
&lt;br /&gt;
-- Permission is granted to anyone to use this software for any purpose, &lt;br /&gt;
-- including commercial applications, and to alter it and redistribute it freely, &lt;br /&gt;
-- subject to the following restrictions:&lt;br /&gt;
&lt;br /&gt;
-- 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.&lt;br /&gt;
-- 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.&lt;br /&gt;
-- 3. This notice may not be removed or altered from any source distribution.&lt;br /&gt;
&lt;br /&gt;
require(&amp;quot;mobdebug&amp;quot;).start()&lt;br /&gt;
require &amp;quot;strict&amp;quot;&lt;br /&gt;
&lt;br /&gt;
--[[  ------------------------ main --------------------------------------------------&lt;br /&gt;
|&lt;br /&gt;
|  Entry point for script.  Adds a tab to selected contour&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function main(script_path)&lt;br /&gt;
&lt;br /&gt;
    -- Check we have a job loaded&lt;br /&gt;
    local job = VectricJob()&lt;br /&gt;
&lt;br /&gt;
    if not job.Exists then&lt;br /&gt;
       DisplayMessageBox(&amp;quot;No job open.&amp;quot;)&lt;br /&gt;
       return false&lt;br /&gt;
    end&lt;br /&gt;
		&lt;br /&gt;
	-- get selected contour&lt;br /&gt;
	local selection = job.Selection&lt;br /&gt;
  local cadcontour = selection:GetAt(selection:GetHeadPosition())&lt;br /&gt;
  &lt;br /&gt;
  -- add tab&lt;br /&gt;
  local point = Point2D(2.5,0.3)&lt;br /&gt;
  cadcontour:InsertToolpathTabAtPoint(point)&lt;br /&gt;
	&lt;br /&gt;
    return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=High Level Objects]]&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Example_Toolpath_Code&amp;diff=1102</id>
		<title>Example Toolpath Code</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Example_Toolpath_Code&amp;diff=1102"/>
		<updated>2024-11-16T17:47:50Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: /* CreatePocketingToolpath by Named Layer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
These are Code Examples for toolpaths.&lt;br /&gt;
&lt;br /&gt;
==Selection by Layer Name==&lt;br /&gt;
&lt;br /&gt;
===SelectVectorsOnLayer===&lt;br /&gt;
Create a selection set by layer name and object type, retunes the selection set.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function SelectVectorsOnLayer(layer, selection, select_closed, select_open, select_groups)&lt;br /&gt;
  --[[ Please Note: SelectVectorsOnLayer is provided by Vectric and can be found in the SDK and Sample Gadget files.&lt;br /&gt;
  -- | ---------------- SelectVectorsOnLayer ----------------&lt;br /&gt;
  -- |   SelectVectorsOnLayer(&amp;quot;Stringer Profile&amp;quot;, selection, true, false, false)&lt;br /&gt;
  -- |   Add all the vectors on the layer to the selection&lt;br /&gt;
  -- |     layer,            -- layer we are selecting vectors on&lt;br /&gt;
  -- |     selection         -- selection object&lt;br /&gt;
  -- |     select_closed     -- if true  select closed objects&lt;br /&gt;
  -- |     select_open       -- if true  select open objects&lt;br /&gt;
  -- |     select_groups     -- if true select grouped vectors (irrespective of open / closed state of member objects)&lt;br /&gt;
  -- |  Return Values:  true if selected one or more vectors&lt;br /&gt;
  -- |&lt;br /&gt;
  -- ====================================================]]&lt;br /&gt;
  local objects_selected = false&lt;br /&gt;
  local warning_displayed = false&lt;br /&gt;
  local pos = layer:GetHeadPosition()&lt;br /&gt;
  while pos ~= nil do&lt;br /&gt;
    local object&lt;br /&gt;
    object, pos = layer:GetNext(pos)&lt;br /&gt;
    local contour = object:GetContour()&lt;br /&gt;
    if contour == nil then&lt;br /&gt;
      if (object.ClassName == &amp;quot;vcCadObjectGroup&amp;quot;) and select_groups then&lt;br /&gt;
        selection:Add(object, true, true)&lt;br /&gt;
        objects_selected = true&lt;br /&gt;
      else&lt;br /&gt;
        if not warning_displayed then&lt;br /&gt;
          local message = &amp;quot;Object(s) without contour information found on layer - ignoring&amp;quot;&lt;br /&gt;
          if not select_groups then&lt;br /&gt;
            message = message ..  &amp;quot;\r\n\r\n&amp;quot; ..&lt;br /&gt;
            &amp;quot;If layer contains grouped vectors these must be un-grouped for this script&amp;quot;&lt;br /&gt;
          end -- if end&lt;br /&gt;
          StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Select Vectors&amp;quot;, message, &amp;quot;(7200)&amp;quot;)&lt;br /&gt;
          warning_displayed = true&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- if end&lt;br /&gt;
    else  -- contour was NOT nil, test if Open or Closed&lt;br /&gt;
      if contour.IsOpen and select_open then&lt;br /&gt;
        selection:Add(object, true, true)&lt;br /&gt;
        objects_selected = true&lt;br /&gt;
      elseif select_closed then&lt;br /&gt;
        selection:Add(object, true, true)&lt;br /&gt;
        objects_selected = true&lt;br /&gt;
      end -- if end&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- while end&lt;br /&gt;
  -- to avoid excessive redrawing etc. we added vectors to the selection in 'batch' mode&lt;br /&gt;
  -- tell selection we have now finished updating&lt;br /&gt;
  if objects_selected then&lt;br /&gt;
    selection:GroupSelectionFinished()&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return objects_selected&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Pocketing Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreatePocketingToolpath by Selection===&lt;br /&gt;
Create a Pocketing toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreatePocketingToolpath(name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
--[[ ------------ CreatePocketingToolpath ------------&lt;br /&gt;
|| =====================================================&lt;br /&gt;
| Create a Pocketing toolpath within the program for the currently selected vectors&lt;br /&gt;
| Parameters:&lt;br /&gt;
| name, -- Name for toolpath&lt;br /&gt;
| start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
| cut_depth -- cut depth for pocket toolpath&lt;br /&gt;
| tool_dia -- diameter of end mill to use&lt;br /&gt;
| tool_stepdown -- stepdown for tool&lt;br /&gt;
| tool_stepover_percent -- percentage stepover for tool&lt;br /&gt;
| tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
|| =====================================================]]&lt;br /&gt;
-- Return Values:&lt;br /&gt;
-- true if toolpath created OK else false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&amp;quot;Lua End Mill&amp;quot;,Tool.END_MILL -- BALL_NOSE, END_MILL, VBIT)&lt;br /&gt;
  tool.InMM = tool_in_mm&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * (tool_stepover_percent / 100)&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC,...&lt;br /&gt;
  tool.FeedRate = 30&lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * (tool_stepover_percent / 100) -- used for vbit only&lt;br /&gt;
-- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
  pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
  pos_data.SafeZGap = 5.0&lt;br /&gt;
-- Create object used to pass pocketing options&lt;br /&gt;
  local pocket_data = PocketParameterData()&lt;br /&gt;
-- start depth for toolpath&lt;br /&gt;
  pocket_data.StartDepth = start_depth&lt;br /&gt;
-- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  pocket_data.CutDepth = cut_depth&lt;br /&gt;
-- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION or&lt;br /&gt;
-- ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
  pocket_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
-- Allowance to leave on when machining&lt;br /&gt;
  pocket_data.Allowance = 0.0&lt;br /&gt;
-- if true use raster clearance strategy , else use offset area clearance&lt;br /&gt;
  pocket_data.DoRasterClearance = true&lt;br /&gt;
-- angle for raster if using raster clearance&lt;br /&gt;
  pocket_data.RasterAngle = 0&lt;br /&gt;
-- type of profile pass to perform PocketParameterData.PROFILE_NONE ,&lt;br /&gt;
-- PocketParameterData.PROFILE_FIRST orPocketParameterData.PROFILE_LAST&lt;br /&gt;
  pocket_data.ProfilePassType = PocketParameterData.PROFILE_LAST&lt;br /&gt;
-- if true we ramp into pockets (always zig-zag)&lt;br /&gt;
  pocket_data.DoRamping = false&lt;br /&gt;
-- if ramping, distance to ramp over&lt;br /&gt;
  pocket_data.RampDistance = 10.0&lt;br /&gt;
-- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  pocket_data.ProjectToolpath = false&lt;br /&gt;
-- Create object which can be used to automatically select geometry&lt;br /&gt;
  local geometry_selector = GeometrySelector()&lt;br /&gt;
-- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
-- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
-- if we are doing two tool pocketing define tool to use for area clearance&lt;br /&gt;
  local area_clear_tool = nill&lt;br /&gt;
-- we just create a tool twice as large for testing here&lt;br /&gt;
  area_clear_tool = Tool(&amp;quot;Lua Clearance End Mill&amp;quot;,Tool.END_MILL) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
  area_clear_tool.InMM = tool_in_mm&lt;br /&gt;
  area_clear_tool.ToolDia = tool_dia * 2&lt;br /&gt;
  area_clear_tool.Stepdown = tool_stepdown * 2&lt;br /&gt;
  area_clear_tool.Stepover = tool_dia * 2 *(tool_stepover_percent / 100)&lt;br /&gt;
  area_clear_tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC..&lt;br /&gt;
  area_clear_tool.FeedRate = 30&lt;br /&gt;
  area_clear_tool.PlungeRate = 10&lt;br /&gt;
  area_clear_tool.SpindleSpeed = 20000&lt;br /&gt;
  area_clear_tool.ToolNumber = 1&lt;br /&gt;
  area_clear_tool.VBitAngle = 90.0 -- used for vbit only&lt;br /&gt;
  area_clear_tool.ClearStepover = tool_dia*2*(tool_stepover_percent/100) -- used for vbit&lt;br /&gt;
-- Create our toolpath&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreatePocketingToolpath(name, tool, area_clear_tool, pocket_data, pos_data, &lt;br /&gt;
                                                               geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
  if toolpath_id == nill then&lt;br /&gt;
     DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
     return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===CreatePocketingToolpath by Named Layer===&lt;br /&gt;
Create a Pocketing toolpath within the program for the named layer.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreateLayerPocketingToolpath(layer_name, name, start_depth, cut_depth)&lt;br /&gt;
  local caller = &amp;quot; - &amp;quot; .. name&lt;br /&gt;
  if Milling.Pocket then&lt;br /&gt;
    local selection = Milling.job.Selection  -- clear current selection&lt;br /&gt;
          selection:Clear()&lt;br /&gt;
  -- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot;   .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
   -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(MillTool2.Name, Tool.END_MILL)    -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
          tool.InMM = MillTool2.InMM            -- tool_in_mm&lt;br /&gt;
          tool.ToolDia = MillTool2.ToolDia         -- tool_dia&lt;br /&gt;
          tool.Stepdown = MillTool2.Stepdown        -- tool_stepdown&lt;br /&gt;
          tool.Stepover = MillTool2.Stepover        -- tool_dia * (tool_stepover_percent / 100)&lt;br /&gt;
          tool.RateUnits = MillTool2.RateUnits       -- Tool.MM_SEC     -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
          tool.FeedRate = MillTool2.FeedRate        -- 30&lt;br /&gt;
          tool.PlungeRate = MillTool2.PlungeRate      -- 10&lt;br /&gt;
          tool.SpindleSpeed = MillTool2.SpindleSpeed    -- 20000&lt;br /&gt;
          tool.ToolNumber = MillTool2.ToolNumber      -- 1&lt;br /&gt;
      --  tool.VBit_Angle = MillTool.VBit_Angle        -- 90.0            -- used for vbit only&lt;br /&gt;
      --  tool.ClearStepover = MillTool.ClearStepover   --  tool_dia * (tool_stepover_percent / 100)  -- used for vbit only&lt;br /&gt;
   -- we will set home position and safe z relative to material block size&lt;br /&gt;
    local mtl_block = MaterialBlock()&lt;br /&gt;
    local mtl_box = mtl_block.MaterialBox&lt;br /&gt;
    local mtl_box_blc = mtl_box.BLC&lt;br /&gt;
   -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
          pos_data:SetHomePosition(mtl_box_blc.x, mtl_box_blc.y, mtl_box.TRC.z + (mtl_block.Thickness * 0.2) )&lt;br /&gt;
          pos_data.SafeZGap = mtl_block.Thickness * 0.1&lt;br /&gt;
   -- Create  object used to pass pocketing options&lt;br /&gt;
    local pocket_data = PocketParameterData()&lt;br /&gt;
          -- start depth for toolpath&lt;br /&gt;
          pocket_data.StartDepth = start_depth&lt;br /&gt;
          -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
          pocket_data.CutDepth = cut_depth&lt;br /&gt;
          -- direction of cut for offset clearance - ProfileParameterData.CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION &lt;br /&gt;
          -- NOTE: enum from ProfileParameterData&lt;br /&gt;
          pocket_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
          -- Allowance to leave on when machining&lt;br /&gt;
          pocket_data.Allowance = 0.0&lt;br /&gt;
          -- if true use raster clearance strategy , else use offset area clearance&lt;br /&gt;
          pocket_data.DoRasterClearance = false --true&lt;br /&gt;
          -- angle for raster if using raster clearance&lt;br /&gt;
          pocket_data.RasterAngle = 0&lt;br /&gt;
          -- type of profile pass to perform  PocketParameterData.PROFILE_NONE , PocketParameterData.PROFILE_FIRST orPocketParameterData.PROFILE_LAST&lt;br /&gt;
          pocket_data.ProfilePassType = PocketParameterData.PROFILE_LAST&lt;br /&gt;
          -- if true we ramp into pockets (always zig-zag)&lt;br /&gt;
          pocket_data.DoRamping = false&lt;br /&gt;
          --  if ramping, distance to ramp over&lt;br /&gt;
          pocket_data.RampDistance = 1.0&lt;br /&gt;
          -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
          pocket_data.ProjectToolpath = false&lt;br /&gt;
   -- Create object which can used to automatically select geometry on layers etc.&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
   -- if this is true we create 2d toolpaths previews in 2d view, if false we don't&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
   -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings =  true -- false --&lt;br /&gt;
   -- if we are doing two tool pocketing define tool to use for area clearance&lt;br /&gt;
    local area_clear_tool = nil&lt;br /&gt;
    if Milling.Clearning then&lt;br /&gt;
   -- we just create a tool twice as large for testing here&lt;br /&gt;
     area_clear_tool = Tool(MillTool3.Name, Tool.END_MILL)  -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
     area_clear_tool.InMM = MillTool3.InMM       -- tool_in_mm&lt;br /&gt;
     area_clear_tool.ToolDia = MillTool3.ToolDia    -- tool_dia * 2&lt;br /&gt;
     area_clear_tool.Stepdown = MillTool3.Stepdown   -- tool_stepdown * 2&lt;br /&gt;
     area_clear_tool.Stepover = MillTool3.Stepover   -- tool_dia * 2 *(tool_stepover_percent / 100)&lt;br /&gt;
     area_clear_tool.RateUnits = MillTool3.RateUnits  -- Tool.MM_SEC  -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
     area_clear_tool.FeedRate = MillTool3.FeedRate      -- 30&lt;br /&gt;
     area_clear_tool.PlungeRate = MillTool3.PlungeRate    -- 10&lt;br /&gt;
     area_clear_tool.SpindleSpeed = MillTool3.SpindleSpeed  -- 20000&lt;br /&gt;
     area_clear_tool.ToolNumber = MillTool3.ToolNumber    -- 1&lt;br /&gt;
    end -- if end&lt;br /&gt;
     -- area_clear_tool.VBitAngle = Carrier.MillTool3.VBit_Angle      -- 90.0 -- used for vbit only&lt;br /&gt;
     -- area_clear_tool.ClearStepover = Carrier.MillTool3.ClearStepover  -- tool_dia * 2 * (tool_stepover_percent / 100)  -- used for vbit only&lt;br /&gt;
   -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePocketingToolpath(&lt;br /&gt;
                                              name,&lt;br /&gt;
                                              tool,&lt;br /&gt;
                                              area_clear_tool,&lt;br /&gt;
                                              pocket_data,&lt;br /&gt;
                                              pos_data,&lt;br /&gt;
                                              geometry_selector,&lt;br /&gt;
                                              create_2d_previews,&lt;br /&gt;
                                              display_warnings&lt;br /&gt;
                                              )&lt;br /&gt;
    if toolpath_id  == nil  then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Milling Settings&amp;quot;, &amp;quot;Unable to create toolpath.&amp;quot;, &amp;quot;(4603)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
  end -- if end &lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Drilling Toolpath== &lt;br /&gt;
===Drilling Toolpath by Selection===&lt;br /&gt;
&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreateDrillingToolpath(name, start_depth, cut_depth, retract_gap, &lt;br /&gt;
                                          tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
--[[ ------- CreateDrillingToolpath --------------------------------------------------&lt;br /&gt;
||&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors&lt;br /&gt;
| Parameters:&lt;br /&gt;
| name, -- Name for toolpath&lt;br /&gt;
| start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
| cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
| retract_gap -- distance to retract above surface for pecks&lt;br /&gt;
| tool_dia -- diameter of drill to use&lt;br /&gt;
| tool_stepdown -- stepdown for tool&lt;br /&gt;
| tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
||&lt;br /&gt;
  Return Values:&lt;br /&gt;
|   true if toolpath created OK else false&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
-- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&amp;quot;Lua Drill&amp;quot;, Tool.THROUGH_DRILL) -- BALL_NOSE, END_MILL, VBIT, THROUGH_DRILL&lt;br /&gt;
  tool.InMM = tool_in_mm&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * 0.25&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
  tool.FeedRate = 30&lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
-- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
        pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
        pos_data.SafeZGap = 5.0&lt;br /&gt;
-- Create object used to pass profile options&lt;br /&gt;
  local drill_data = DrillParameterData()&lt;br /&gt;
-- start depth for toolpath&lt;br /&gt;
  drill_data.StartDepth = start_depth&lt;br /&gt;
-- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  drill_data.CutDepth = cut_depth&lt;br /&gt;
-- if true perform peck drilling&lt;br /&gt;
  drill_data.DoPeckDrill = retract_gap &amp;gt; 0.0&lt;br /&gt;
-- distance to retract above surface when peck drilling&lt;br /&gt;
  drill_data.PeckRetractGap = retract_gap&lt;br /&gt;
-- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  drill_data.ProjectToolpath = false&lt;br /&gt;
-- Create object which can be used to automatically select geometry&lt;br /&gt;
  local geometry_selector = GeometrySelector()&lt;br /&gt;
-- if this is true we create 2d toolpaths previews in 2d view,&lt;br /&gt;
-- if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
-- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
-- Create our toolpath&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreateDrillingToolpath(name, tool, drill_data, pos_data, geometry_selector, &lt;br /&gt;
                                                            create_2d_previews, display_warnings)&lt;br /&gt;
  if toolpath_id == nil then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
    return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Drilling Toolpath by Named Layer===&lt;br /&gt;
&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreateDrillingToolpath(layer_name, name, start_depth, cut_depth, retract_gap, &lt;br /&gt;
                                          tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
--[[ ------- CreateDrillingToolpath --------------------------------------------------&lt;br /&gt;
||&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors&lt;br /&gt;
| Parameters:&lt;br /&gt;
| name, -- Name for toolpath&lt;br /&gt;
| start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
| cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
| retract_gap -- distance to retract above surface for pecks&lt;br /&gt;
| tool_dia -- diameter of drill to use&lt;br /&gt;
| tool_stepdown -- stepdown for tool&lt;br /&gt;
| tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
||&lt;br /&gt;
  Return Values:&lt;br /&gt;
|   true if toolpath created OK else false&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
-- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot;   .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
-- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&amp;quot;Lua Drill&amp;quot;, Tool.THROUGH_DRILL) -- BALL_NOSE, END_MILL, VBIT, THROUGH_DRILL&lt;br /&gt;
  tool.InMM = tool_in_mm&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * 0.25&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
  tool.FeedRate = 30&lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
-- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
        pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
        pos_data.SafeZGap = 5.0&lt;br /&gt;
-- Create object used to pass profile options&lt;br /&gt;
  local drill_data = DrillParameterData()&lt;br /&gt;
-- start depth for toolpath&lt;br /&gt;
  drill_data.StartDepth = start_depth&lt;br /&gt;
-- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  drill_data.CutDepth = cut_depth&lt;br /&gt;
-- if true perform peck drilling&lt;br /&gt;
  drill_data.DoPeckDrill = retract_gap &amp;gt; 0.0&lt;br /&gt;
-- distance to retract above surface when peck drilling&lt;br /&gt;
  drill_data.PeckRetractGap = retract_gap&lt;br /&gt;
-- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  drill_data.ProjectToolpath = false&lt;br /&gt;
-- Create object which can be used to automatically select geometry&lt;br /&gt;
  local geometry_selector = GeometrySelector()&lt;br /&gt;
-- if this is true we create 2d toolpaths previews in 2d view,&lt;br /&gt;
-- if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
-- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
-- Create our toolpath&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreateDrillingToolpath(name, tool, drill_data, pos_data, geometry_selector, &lt;br /&gt;
                                                            create_2d_previews, display_warnings)&lt;br /&gt;
  if toolpath_id == nil then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
    return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==V-Carve Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreateVCarveToolpath by Selection===&lt;br /&gt;
Create a V-Carve toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===CreateVCarveToolpath by Layer Name===&lt;br /&gt;
Create a V-Carve toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Fluting Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreateFlutingToolpath by Selection===&lt;br /&gt;
Create a Fluting toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;  function CreateFlutingToolpath(name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
    --[[ ----------------- CreateFlutingToolpath -----------------&lt;br /&gt;
  | Create a flutting toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for toolpath&lt;br /&gt;
  | tool_dia -- diameter of tool to use&lt;br /&gt;
  | tool_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua Ball Nose&amp;quot;, Tool.BALL_NOSE) -- BALL_NOSE, END_MILL, VBit_Angle, THROUGH_DRILL&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * 0.25&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass fluting options&lt;br /&gt;
    local fluting_data = FlutingParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    fluting_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    fluting_data.CutDepth = cut_depth&lt;br /&gt;
    -- type of fluting FULL_LENGTH, RAMP_START or RAMP_START_END&lt;br /&gt;
    fluting_data.FluteType = FlutingParameterData.RAMP_START_END&lt;br /&gt;
    -- type of ramping RAMP_LINEAR, RAMP_SMOOTH&lt;br /&gt;
    fluting_data.RampType = FlutingParameterData.RAMP_LINEAR&lt;br /&gt;
    -- if true use ratio field for controling ramp length else absolute length value&lt;br /&gt;
    fluting_data.UseRampRatio = false&lt;br /&gt;
    -- length of ramp as ratio of flute length(range 0 - 1.0)&lt;br /&gt;
    -- (for start and end - ratio is of half length)&lt;br /&gt;
    fluting_data.RampRatio = 0.2&lt;br /&gt;
    -- length to ramp over - if UseRampRatio == false&lt;br /&gt;
    fluting_data.RampLength = 15&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    fluting_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateFlutingToolpath(name, tool, fluting_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    else&lt;br /&gt;
      return true&lt;br /&gt;
    end -- if end &lt;br /&gt;
&lt;br /&gt;
    end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===CreateFlutingToolpath by Layer Name===&lt;br /&gt;
Create a Fluting toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Profile Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreateProfileToolpath by Selection===&lt;br /&gt;
Create a Profile toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===CreateProfileToolpath by Layer Name===&lt;br /&gt;
Create a Profile toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function CreateProfileToolpath(layer_name, name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
   -- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot;   .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua End Mill&amp;quot;, Tool.END_MILL) -- BALL_NOSE, END_MILL, VBit&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * 0.25&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC ...&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local profile_data = ProfileParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    profile_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    profile_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut - ProfileParameterData.&lt;br /&gt;
    -- CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION&lt;br /&gt;
    profile_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- side we machine on - ProfileParameterData.&lt;br /&gt;
    -- PROFILE_OUTSIDE, ProfileParameterData.PROFILE_INSIDE or&lt;br /&gt;
    -- ProfileParameterData.PROFILE_ON&lt;br /&gt;
    profile_data.ProfileSide = ProfileParameterData.PROFILE_OUTSIDE&lt;br /&gt;
    -- Allowance to leave on when machining&lt;br /&gt;
    profile_data.Allowance = 0.0&lt;br /&gt;
    -- true to preserve start point positions, false to reorder start&lt;br /&gt;
    -- points to minimise toolpath length&lt;br /&gt;
    profile_data.KeepStartPoints = false&lt;br /&gt;
    -- true if want to create 'square' external corners on toolpath&lt;br /&gt;
    profile_data.CreateSquareCorners = false&lt;br /&gt;
    -- true to perform corner sharpening on internal corners (only with v-bits)&lt;br /&gt;
    profile_data.CornerSharpen = false&lt;br /&gt;
    -- true to use tabs (position of tabs must already have been defined on vectors)&lt;br /&gt;
    profile_data.UseTabs = false&lt;br /&gt;
    -- length for tabs if being used&lt;br /&gt;
    profile_data.TabLength = 5.0&lt;br /&gt;
    -- Thickness for tabs if being used&lt;br /&gt;
    profile_data.TabThickness = 1.0&lt;br /&gt;
    -- if true then create 3d tabs else 2d tabs&lt;br /&gt;
    profile_data.Use3dTabs = true&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    profile_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object used to control ramping&lt;br /&gt;
    local ramping_data = RampingData()&lt;br /&gt;
    -- if true we do ramping into toolpath&lt;br /&gt;
    ramping_data.DoRamping = false&lt;br /&gt;
    -- type of ramping to perform RampingData.RAMP_LINEAR , RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
    -- or RampingData.RAMP_SPIRAL&lt;br /&gt;
    ramping_data.RampType = RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
    -- how ramp is contrained - either by angle or distance RampingData.CONSTRAIN_DISTANCE&lt;br /&gt;
    -- or RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
    ramping_data.RampConstraint = RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
    -- if we are constraining ramp by distance, distance to ramp over&lt;br /&gt;
    ramping_data.RampDistance = 100.0&lt;br /&gt;
    -- if we are contraining ramp by angle , angle to ramp in at (in degrees)&lt;br /&gt;
    ramping_data.RampAngle = 25.0&lt;br /&gt;
    -- if we are contraining ramp by angle, max distance to travel before 'zig zaging'&lt;br /&gt;
    -- if zig zaging&lt;br /&gt;
    ramping_data.RampMaxAngleDist = 15&lt;br /&gt;
    -- if true we restrict our ramping to lead in section of toolpath&lt;br /&gt;
    ramping_data.RampOnLeadIn = false&lt;br /&gt;
    -- Create object used to control lead in/out&lt;br /&gt;
    local lead_in_out_data = LeadInOutData()&lt;br /&gt;
    -- if true we create lead ins on profiles (not for profile on)&lt;br /&gt;
    lead_in_out_data.DoLeadIn = false&lt;br /&gt;
    -- if true we create lead outs on profiles (not for profile on)&lt;br /&gt;
    lead_in_out_data.DoLeadOut = false&lt;br /&gt;
    -- type of leads to create LeadInOutData.LINEAR_LEAD or LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
    lead_in_out_data.LeadType = LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
    -- length of lead to create&lt;br /&gt;
    lead_in_out_data.LeadLength = 10.0&lt;br /&gt;
    -- Angle for linear leads&lt;br /&gt;
    lead_in_out_data.LinearLeadAngle = 45&lt;br /&gt;
    -- Radius for circular arc leads&lt;br /&gt;
    lead_in_out_data.CirularLeadRadius = 5.0&lt;br /&gt;
    -- distance to 'overcut' (travel past start point) when profiling&lt;br /&gt;
    lead_in_out_data.OvercutDistance = 0.0&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateProfilingToolpath(name, tool, profile_data, ramping_data, lead_in_out_data, pos_data, geometry_selector, create_2d_previews, display_warnings )&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Prism Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreatePrismToolpath by Selection===&lt;br /&gt;
Create a Prism toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;  function CreatePrismToolpath(name, start_depth, cut_depth, vbit_angle, vbit_dia, vbit_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
  --[[ ------------------- CreatePrismToolpath -------------------&lt;br /&gt;
  |&lt;br /&gt;
  | Create a prism toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
  | vbit_angle -- angle of vbit to use&lt;br /&gt;
  | vbit_dia -- diameter of VBit to use&lt;br /&gt;
  | vbit_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_stepover_percent - percentage stepover for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua VBit&amp;quot;, Tool.VBIT ) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = vbit_dia&lt;br /&gt;
    tool.Stepdown = vbit_stepdown&lt;br /&gt;
    tool.Stepover = vbit_dia * (tool_stepover_percent / 100)&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = vbit_dia * (tool_stepover_percent / 100) * 2 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local prism_data = PrismCarveParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    prism_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    prism_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- or ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
    prism_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- calculate the minimum cut depth to fully form the bevel on the current&lt;br /&gt;
    -- selection with the current tool&lt;br /&gt;
    local min_bevel_depth = prism_data:CalculateMinimumBevelDepth(tool, true)&lt;br /&gt;
    if min_bevel_depth &amp;gt; cut_depth then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;A prism will not be fully formed with a depth of &amp;quot; .. cut_depth .. &amp;quot;\r\n&amp;quot; ..&lt;br /&gt;
                        &amp;quot;A depth of &amp;quot; .. min_bevel_depth .. &amp;quot; is required to fully form the prism&amp;quot;&lt;br /&gt;
                        )&lt;br /&gt;
    end -- if end&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePrismCarvingToolpath(name, tool, prism_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===CreatePrismToolpath by Layer Name===&lt;br /&gt;
Create a Prism toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function CreatePrismToolpath(layer_name, name, start_depth, cut_depth, vbit_angle, vbit_dia, vbit_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
  --[[ ------------------- CreatePrismToolpath -------------------&lt;br /&gt;
  |&lt;br /&gt;
  | Create a prism toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
  | vbit_angle -- angle of vbit to use&lt;br /&gt;
  | vbit_dia -- diameter of VBit to use&lt;br /&gt;
  | vbit_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_stepover_percent - percentage stepover for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
   -- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot; .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua VBit&amp;quot;, Tool.VBIT ) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = vbit_dia&lt;br /&gt;
    tool.Stepdown = vbit_stepdown&lt;br /&gt;
    tool.Stepover = vbit_dia * (tool_stepover_percent / 100)&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = vbit_dia * (tool_stepover_percent / 100) * 2 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local prism_data = PrismCarveParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    prism_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    prism_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
    prism_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- calculate the minimum cut depth to fully form the bevel on the current&lt;br /&gt;
    -- selection with the current tool&lt;br /&gt;
    local min_bevel_depth = prism_data:CalculateMinimumBevelDepth(tool, true)&lt;br /&gt;
    if min_bevel_depth &amp;gt; cut_depth then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;A prism will not be fully formed with a depth of &amp;quot; .. cut_depth .. &amp;quot;\r\n&amp;quot; ..&lt;br /&gt;
                        &amp;quot;A depth of &amp;quot; .. min_bevel_depth .. &amp;quot; is required to fully form the prism&amp;quot;)&lt;br /&gt;
    end -- if end&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePrismCarvingToolpath(name, tool, prism_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Example_Toolpath_Code&amp;diff=1101</id>
		<title>Example Toolpath Code</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Example_Toolpath_Code&amp;diff=1101"/>
		<updated>2024-11-16T17:46:41Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: /* Drilling Toolpath */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
These are Code Examples for toolpaths.&lt;br /&gt;
&lt;br /&gt;
==Selection by Layer Name==&lt;br /&gt;
&lt;br /&gt;
===SelectVectorsOnLayer===&lt;br /&gt;
Create a selection set by layer name and object type, retunes the selection set.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function SelectVectorsOnLayer(layer, selection, select_closed, select_open, select_groups)&lt;br /&gt;
  --[[ Please Note: SelectVectorsOnLayer is provided by Vectric and can be found in the SDK and Sample Gadget files.&lt;br /&gt;
  -- | ---------------- SelectVectorsOnLayer ----------------&lt;br /&gt;
  -- |   SelectVectorsOnLayer(&amp;quot;Stringer Profile&amp;quot;, selection, true, false, false)&lt;br /&gt;
  -- |   Add all the vectors on the layer to the selection&lt;br /&gt;
  -- |     layer,            -- layer we are selecting vectors on&lt;br /&gt;
  -- |     selection         -- selection object&lt;br /&gt;
  -- |     select_closed     -- if true  select closed objects&lt;br /&gt;
  -- |     select_open       -- if true  select open objects&lt;br /&gt;
  -- |     select_groups     -- if true select grouped vectors (irrespective of open / closed state of member objects)&lt;br /&gt;
  -- |  Return Values:  true if selected one or more vectors&lt;br /&gt;
  -- |&lt;br /&gt;
  -- ====================================================]]&lt;br /&gt;
  local objects_selected = false&lt;br /&gt;
  local warning_displayed = false&lt;br /&gt;
  local pos = layer:GetHeadPosition()&lt;br /&gt;
  while pos ~= nil do&lt;br /&gt;
    local object&lt;br /&gt;
    object, pos = layer:GetNext(pos)&lt;br /&gt;
    local contour = object:GetContour()&lt;br /&gt;
    if contour == nil then&lt;br /&gt;
      if (object.ClassName == &amp;quot;vcCadObjectGroup&amp;quot;) and select_groups then&lt;br /&gt;
        selection:Add(object, true, true)&lt;br /&gt;
        objects_selected = true&lt;br /&gt;
      else&lt;br /&gt;
        if not warning_displayed then&lt;br /&gt;
          local message = &amp;quot;Object(s) without contour information found on layer - ignoring&amp;quot;&lt;br /&gt;
          if not select_groups then&lt;br /&gt;
            message = message ..  &amp;quot;\r\n\r\n&amp;quot; ..&lt;br /&gt;
            &amp;quot;If layer contains grouped vectors these must be un-grouped for this script&amp;quot;&lt;br /&gt;
          end -- if end&lt;br /&gt;
          StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Select Vectors&amp;quot;, message, &amp;quot;(7200)&amp;quot;)&lt;br /&gt;
          warning_displayed = true&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- if end&lt;br /&gt;
    else  -- contour was NOT nil, test if Open or Closed&lt;br /&gt;
      if contour.IsOpen and select_open then&lt;br /&gt;
        selection:Add(object, true, true)&lt;br /&gt;
        objects_selected = true&lt;br /&gt;
      elseif select_closed then&lt;br /&gt;
        selection:Add(object, true, true)&lt;br /&gt;
        objects_selected = true&lt;br /&gt;
      end -- if end&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- while end&lt;br /&gt;
  -- to avoid excessive redrawing etc. we added vectors to the selection in 'batch' mode&lt;br /&gt;
  -- tell selection we have now finished updating&lt;br /&gt;
  if objects_selected then&lt;br /&gt;
    selection:GroupSelectionFinished()&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return objects_selected&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Pocketing Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreatePocketingToolpath by Selection===&lt;br /&gt;
Create a Pocketing toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreatePocketingToolpath(name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
--[[ ------------ CreatePocketingToolpath ------------&lt;br /&gt;
|| =====================================================&lt;br /&gt;
| Create a Pocketing toolpath within the program for the currently selected vectors&lt;br /&gt;
| Parameters:&lt;br /&gt;
| name, -- Name for toolpath&lt;br /&gt;
| start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
| cut_depth -- cut depth for pocket toolpath&lt;br /&gt;
| tool_dia -- diameter of end mill to use&lt;br /&gt;
| tool_stepdown -- stepdown for tool&lt;br /&gt;
| tool_stepover_percent -- percentage stepover for tool&lt;br /&gt;
| tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
|| =====================================================]]&lt;br /&gt;
-- Return Values:&lt;br /&gt;
-- true if toolpath created OK else false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&amp;quot;Lua End Mill&amp;quot;,Tool.END_MILL -- BALL_NOSE, END_MILL, VBIT)&lt;br /&gt;
  tool.InMM = tool_in_mm&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * (tool_stepover_percent / 100)&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC,...&lt;br /&gt;
  tool.FeedRate = 30&lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * (tool_stepover_percent / 100) -- used for vbit only&lt;br /&gt;
-- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
  pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
  pos_data.SafeZGap = 5.0&lt;br /&gt;
-- Create object used to pass pocketing options&lt;br /&gt;
  local pocket_data = PocketParameterData()&lt;br /&gt;
-- start depth for toolpath&lt;br /&gt;
  pocket_data.StartDepth = start_depth&lt;br /&gt;
-- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  pocket_data.CutDepth = cut_depth&lt;br /&gt;
-- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION or&lt;br /&gt;
-- ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
  pocket_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
-- Allowance to leave on when machining&lt;br /&gt;
  pocket_data.Allowance = 0.0&lt;br /&gt;
-- if true use raster clearance strategy , else use offset area clearance&lt;br /&gt;
  pocket_data.DoRasterClearance = true&lt;br /&gt;
-- angle for raster if using raster clearance&lt;br /&gt;
  pocket_data.RasterAngle = 0&lt;br /&gt;
-- type of profile pass to perform PocketParameterData.PROFILE_NONE ,&lt;br /&gt;
-- PocketParameterData.PROFILE_FIRST orPocketParameterData.PROFILE_LAST&lt;br /&gt;
  pocket_data.ProfilePassType = PocketParameterData.PROFILE_LAST&lt;br /&gt;
-- if true we ramp into pockets (always zig-zag)&lt;br /&gt;
  pocket_data.DoRamping = false&lt;br /&gt;
-- if ramping, distance to ramp over&lt;br /&gt;
  pocket_data.RampDistance = 10.0&lt;br /&gt;
-- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  pocket_data.ProjectToolpath = false&lt;br /&gt;
-- Create object which can be used to automatically select geometry&lt;br /&gt;
  local geometry_selector = GeometrySelector()&lt;br /&gt;
-- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
-- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
-- if we are doing two tool pocketing define tool to use for area clearance&lt;br /&gt;
  local area_clear_tool = nill&lt;br /&gt;
-- we just create a tool twice as large for testing here&lt;br /&gt;
  area_clear_tool = Tool(&amp;quot;Lua Clearance End Mill&amp;quot;,Tool.END_MILL) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
  area_clear_tool.InMM = tool_in_mm&lt;br /&gt;
  area_clear_tool.ToolDia = tool_dia * 2&lt;br /&gt;
  area_clear_tool.Stepdown = tool_stepdown * 2&lt;br /&gt;
  area_clear_tool.Stepover = tool_dia * 2 *(tool_stepover_percent / 100)&lt;br /&gt;
  area_clear_tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC..&lt;br /&gt;
  area_clear_tool.FeedRate = 30&lt;br /&gt;
  area_clear_tool.PlungeRate = 10&lt;br /&gt;
  area_clear_tool.SpindleSpeed = 20000&lt;br /&gt;
  area_clear_tool.ToolNumber = 1&lt;br /&gt;
  area_clear_tool.VBitAngle = 90.0 -- used for vbit only&lt;br /&gt;
  area_clear_tool.ClearStepover = tool_dia*2*(tool_stepover_percent/100) -- used for vbit&lt;br /&gt;
-- Create our toolpath&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreatePocketingToolpath(name, tool, area_clear_tool, pocket_data, pos_data, &lt;br /&gt;
                                                               geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
  if toolpath_id == nill then&lt;br /&gt;
     DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
     return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===CreatePocketingToolpath by Named Layer===&lt;br /&gt;
Create a Pocketing toolpath within the program for the named layer.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreateLayerPocketingToolpath(layer_name, name, start_depth, cut_depth)&lt;br /&gt;
  local caller = &amp;quot; - &amp;quot; .. name&lt;br /&gt;
  if Milling.Pocket then&lt;br /&gt;
    local selection = Milling.job.Selection  -- clear current selection&lt;br /&gt;
          selection:Clear()&lt;br /&gt;
  -- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot;   .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
   -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(MillTool2.Name, Tool.END_MILL)    -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
          tool.InMM = MillTool2.InMM            -- tool_in_mm&lt;br /&gt;
          tool.ToolDia = MillTool2.ToolDia         -- tool_dia&lt;br /&gt;
          tool.Stepdown = MillTool2.Stepdown        -- tool_stepdown&lt;br /&gt;
          tool.Stepover = MillTool2.Stepover        -- tool_dia * (tool_stepover_percent / 100)&lt;br /&gt;
          tool.RateUnits = MillTool2.RateUnits       -- Tool.MM_SEC     -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
          tool.FeedRate = MillTool2.FeedRate        -- 30&lt;br /&gt;
          tool.PlungeRate = MillTool2.PlungeRate      -- 10&lt;br /&gt;
          tool.SpindleSpeed = MillTool2.SpindleSpeed    -- 20000&lt;br /&gt;
          tool.ToolNumber = MillTool2.ToolNumber      -- 1&lt;br /&gt;
      --  tool.VBit_Angle = MillTool.VBit_Angle        -- 90.0            -- used for vbit only&lt;br /&gt;
      --  tool.ClearStepover = MillTool.ClearStepover   --  tool_dia * (tool_stepover_percent / 100)  -- used for vbit only&lt;br /&gt;
   -- we will set home position and safe z relative to material block size&lt;br /&gt;
    local mtl_block = MaterialBlock()&lt;br /&gt;
    local mtl_box = mtl_block.MaterialBox&lt;br /&gt;
    local mtl_box_blc = mtl_box.BLC&lt;br /&gt;
   -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
          pos_data:SetHomePosition(mtl_box_blc.x, mtl_box_blc.y, mtl_box.TRC.z + (mtl_block.Thickness * 0.2) )&lt;br /&gt;
          pos_data.SafeZGap = mtl_block.Thickness * 0.1&lt;br /&gt;
   -- Create  object used to pass pocketing options&lt;br /&gt;
    local pocket_data = PocketParameterData()&lt;br /&gt;
          -- start depth for toolpath&lt;br /&gt;
          pocket_data.StartDepth = start_depth&lt;br /&gt;
          -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
          pocket_data.CutDepth = cut_depth&lt;br /&gt;
          -- direction of cut for offset clearance - ProfileParameterData.CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION &lt;br /&gt;
          -- NOTE: enum from ProfileParameterData&lt;br /&gt;
          pocket_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
          -- Allowance to leave on when machining&lt;br /&gt;
          pocket_data.Allowance = 0.0&lt;br /&gt;
          -- if true use raster clearance strategy , else use offset area clearance&lt;br /&gt;
          pocket_data.DoRasterClearance = false --true&lt;br /&gt;
          -- angle for raster if using raster clearance&lt;br /&gt;
          pocket_data.RasterAngle = 0&lt;br /&gt;
          -- type of profile pass to perform  PocketParameterData.PROFILE_NONE , PocketParameterData.PROFILE_FIRST orPocketParameterData.PROFILE_LAST&lt;br /&gt;
          pocket_data.ProfilePassType = PocketParameterData.PROFILE_LAST&lt;br /&gt;
          -- if true we ramp into pockets (always zig-zag)&lt;br /&gt;
          pocket_data.DoRamping = false&lt;br /&gt;
          --  if ramping, distance to ramp over&lt;br /&gt;
          pocket_data.RampDistance = 1.0&lt;br /&gt;
          -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
          pocket_data.ProjectToolpath = false&lt;br /&gt;
   -- Create object which can used to automatically select geometry on layers etc.&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
   -- if this is true we create 2d toolpaths previews in 2d view, if false we don't&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
   -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings =  true -- false --&lt;br /&gt;
   -- if we are doing two tool pocketing define tool to use for area clearance&lt;br /&gt;
    local area_clear_tool = nil&lt;br /&gt;
    if Milling.Clearning then&lt;br /&gt;
   -- we just create a tool twice as large for testing here&lt;br /&gt;
     area_clear_tool = Tool(MillTool3.Name, Tool.END_MILL)  -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
     area_clear_tool.InMM = MillTool3.InMM       -- tool_in_mm&lt;br /&gt;
     area_clear_tool.ToolDia = MillTool3.ToolDia    -- tool_dia * 2&lt;br /&gt;
     area_clear_tool.Stepdown = MillTool3.Stepdown   -- tool_stepdown * 2&lt;br /&gt;
     area_clear_tool.Stepover = MillTool3.Stepover   -- tool_dia * 2 *(tool_stepover_percent / 100)&lt;br /&gt;
     area_clear_tool.RateUnits = MillTool3.RateUnits  -- Tool.MM_SEC  -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
     area_clear_tool.FeedRate = MillTool3.FeedRate      -- 30&lt;br /&gt;
     area_clear_tool.PlungeRate = MillTool3.PlungeRate    -- 10&lt;br /&gt;
     area_clear_tool.SpindleSpeed = MillTool3.SpindleSpeed  -- 20000&lt;br /&gt;
     area_clear_tool.ToolNumber = MillTool3.ToolNumber    -- 1&lt;br /&gt;
    end -- if end&lt;br /&gt;
     -- area_clear_tool.VBit_Angle = Carrier.MillTool3.VBit_Angle      -- 90.0 -- used for vbit only&lt;br /&gt;
     -- area_clear_tool.ClearStepover = Carrier.MillTool3.ClearStepover  -- tool_dia * 2 * (tool_stepover_percent / 100)  -- used for vbit only&lt;br /&gt;
   -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePocketingToolpath(&lt;br /&gt;
                                              name,&lt;br /&gt;
                                              tool,&lt;br /&gt;
                                              area_clear_tool,&lt;br /&gt;
                                              pocket_data,&lt;br /&gt;
                                              pos_data,&lt;br /&gt;
                                              geometry_selector,&lt;br /&gt;
                                              create_2d_previews,&lt;br /&gt;
                                              display_warnings&lt;br /&gt;
                                              )&lt;br /&gt;
    if toolpath_id  == nil  then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Milling Settings&amp;quot;, &amp;quot;Unable to create toolpath.&amp;quot;, &amp;quot;(4603)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
  end -- if end &lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Drilling Toolpath== &lt;br /&gt;
===Drilling Toolpath by Selection===&lt;br /&gt;
&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreateDrillingToolpath(name, start_depth, cut_depth, retract_gap, &lt;br /&gt;
                                          tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
--[[ ------- CreateDrillingToolpath --------------------------------------------------&lt;br /&gt;
||&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors&lt;br /&gt;
| Parameters:&lt;br /&gt;
| name, -- Name for toolpath&lt;br /&gt;
| start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
| cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
| retract_gap -- distance to retract above surface for pecks&lt;br /&gt;
| tool_dia -- diameter of drill to use&lt;br /&gt;
| tool_stepdown -- stepdown for tool&lt;br /&gt;
| tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
||&lt;br /&gt;
  Return Values:&lt;br /&gt;
|   true if toolpath created OK else false&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
-- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&amp;quot;Lua Drill&amp;quot;, Tool.THROUGH_DRILL) -- BALL_NOSE, END_MILL, VBIT, THROUGH_DRILL&lt;br /&gt;
  tool.InMM = tool_in_mm&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * 0.25&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
  tool.FeedRate = 30&lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
-- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
        pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
        pos_data.SafeZGap = 5.0&lt;br /&gt;
-- Create object used to pass profile options&lt;br /&gt;
  local drill_data = DrillParameterData()&lt;br /&gt;
-- start depth for toolpath&lt;br /&gt;
  drill_data.StartDepth = start_depth&lt;br /&gt;
-- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  drill_data.CutDepth = cut_depth&lt;br /&gt;
-- if true perform peck drilling&lt;br /&gt;
  drill_data.DoPeckDrill = retract_gap &amp;gt; 0.0&lt;br /&gt;
-- distance to retract above surface when peck drilling&lt;br /&gt;
  drill_data.PeckRetractGap = retract_gap&lt;br /&gt;
-- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  drill_data.ProjectToolpath = false&lt;br /&gt;
-- Create object which can be used to automatically select geometry&lt;br /&gt;
  local geometry_selector = GeometrySelector()&lt;br /&gt;
-- if this is true we create 2d toolpaths previews in 2d view,&lt;br /&gt;
-- if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
-- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
-- Create our toolpath&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreateDrillingToolpath(name, tool, drill_data, pos_data, geometry_selector, &lt;br /&gt;
                                                            create_2d_previews, display_warnings)&lt;br /&gt;
  if toolpath_id == nil then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
    return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Drilling Toolpath by Named Layer===&lt;br /&gt;
&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreateDrillingToolpath(layer_name, name, start_depth, cut_depth, retract_gap, &lt;br /&gt;
                                          tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
--[[ ------- CreateDrillingToolpath --------------------------------------------------&lt;br /&gt;
||&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors&lt;br /&gt;
| Parameters:&lt;br /&gt;
| name, -- Name for toolpath&lt;br /&gt;
| start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
| cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
| retract_gap -- distance to retract above surface for pecks&lt;br /&gt;
| tool_dia -- diameter of drill to use&lt;br /&gt;
| tool_stepdown -- stepdown for tool&lt;br /&gt;
| tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
||&lt;br /&gt;
  Return Values:&lt;br /&gt;
|   true if toolpath created OK else false&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
-- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot;   .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
-- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&amp;quot;Lua Drill&amp;quot;, Tool.THROUGH_DRILL) -- BALL_NOSE, END_MILL, VBIT, THROUGH_DRILL&lt;br /&gt;
  tool.InMM = tool_in_mm&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * 0.25&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
  tool.FeedRate = 30&lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
-- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
        pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
        pos_data.SafeZGap = 5.0&lt;br /&gt;
-- Create object used to pass profile options&lt;br /&gt;
  local drill_data = DrillParameterData()&lt;br /&gt;
-- start depth for toolpath&lt;br /&gt;
  drill_data.StartDepth = start_depth&lt;br /&gt;
-- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  drill_data.CutDepth = cut_depth&lt;br /&gt;
-- if true perform peck drilling&lt;br /&gt;
  drill_data.DoPeckDrill = retract_gap &amp;gt; 0.0&lt;br /&gt;
-- distance to retract above surface when peck drilling&lt;br /&gt;
  drill_data.PeckRetractGap = retract_gap&lt;br /&gt;
-- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  drill_data.ProjectToolpath = false&lt;br /&gt;
-- Create object which can be used to automatically select geometry&lt;br /&gt;
  local geometry_selector = GeometrySelector()&lt;br /&gt;
-- if this is true we create 2d toolpaths previews in 2d view,&lt;br /&gt;
-- if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
-- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
-- Create our toolpath&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreateDrillingToolpath(name, tool, drill_data, pos_data, geometry_selector, &lt;br /&gt;
                                                            create_2d_previews, display_warnings)&lt;br /&gt;
  if toolpath_id == nil then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
    return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==V-Carve Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreateVCarveToolpath by Selection===&lt;br /&gt;
Create a V-Carve toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===CreateVCarveToolpath by Layer Name===&lt;br /&gt;
Create a V-Carve toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Fluting Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreateFlutingToolpath by Selection===&lt;br /&gt;
Create a Fluting toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;  function CreateFlutingToolpath(name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
    --[[ ----------------- CreateFlutingToolpath -----------------&lt;br /&gt;
  | Create a flutting toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for toolpath&lt;br /&gt;
  | tool_dia -- diameter of tool to use&lt;br /&gt;
  | tool_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua Ball Nose&amp;quot;, Tool.BALL_NOSE) -- BALL_NOSE, END_MILL, VBit_Angle, THROUGH_DRILL&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * 0.25&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass fluting options&lt;br /&gt;
    local fluting_data = FlutingParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    fluting_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    fluting_data.CutDepth = cut_depth&lt;br /&gt;
    -- type of fluting FULL_LENGTH, RAMP_START or RAMP_START_END&lt;br /&gt;
    fluting_data.FluteType = FlutingParameterData.RAMP_START_END&lt;br /&gt;
    -- type of ramping RAMP_LINEAR, RAMP_SMOOTH&lt;br /&gt;
    fluting_data.RampType = FlutingParameterData.RAMP_LINEAR&lt;br /&gt;
    -- if true use ratio field for controling ramp length else absolute length value&lt;br /&gt;
    fluting_data.UseRampRatio = false&lt;br /&gt;
    -- length of ramp as ratio of flute length(range 0 - 1.0)&lt;br /&gt;
    -- (for start and end - ratio is of half length)&lt;br /&gt;
    fluting_data.RampRatio = 0.2&lt;br /&gt;
    -- length to ramp over - if UseRampRatio == false&lt;br /&gt;
    fluting_data.RampLength = 15&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    fluting_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateFlutingToolpath(name, tool, fluting_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    else&lt;br /&gt;
      return true&lt;br /&gt;
    end -- if end &lt;br /&gt;
&lt;br /&gt;
    end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===CreateFlutingToolpath by Layer Name===&lt;br /&gt;
Create a Fluting toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Profile Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreateProfileToolpath by Selection===&lt;br /&gt;
Create a Profile toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===CreateProfileToolpath by Layer Name===&lt;br /&gt;
Create a Profile toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function CreateProfileToolpath(layer_name, name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
   -- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot;   .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua End Mill&amp;quot;, Tool.END_MILL) -- BALL_NOSE, END_MILL, VBit&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * 0.25&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC ...&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local profile_data = ProfileParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    profile_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    profile_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut - ProfileParameterData.&lt;br /&gt;
    -- CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION&lt;br /&gt;
    profile_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- side we machine on - ProfileParameterData.&lt;br /&gt;
    -- PROFILE_OUTSIDE, ProfileParameterData.PROFILE_INSIDE or&lt;br /&gt;
    -- ProfileParameterData.PROFILE_ON&lt;br /&gt;
    profile_data.ProfileSide = ProfileParameterData.PROFILE_OUTSIDE&lt;br /&gt;
    -- Allowance to leave on when machining&lt;br /&gt;
    profile_data.Allowance = 0.0&lt;br /&gt;
    -- true to preserve start point positions, false to reorder start&lt;br /&gt;
    -- points to minimise toolpath length&lt;br /&gt;
    profile_data.KeepStartPoints = false&lt;br /&gt;
    -- true if want to create 'square' external corners on toolpath&lt;br /&gt;
    profile_data.CreateSquareCorners = false&lt;br /&gt;
    -- true to perform corner sharpening on internal corners (only with v-bits)&lt;br /&gt;
    profile_data.CornerSharpen = false&lt;br /&gt;
    -- true to use tabs (position of tabs must already have been defined on vectors)&lt;br /&gt;
    profile_data.UseTabs = false&lt;br /&gt;
    -- length for tabs if being used&lt;br /&gt;
    profile_data.TabLength = 5.0&lt;br /&gt;
    -- Thickness for tabs if being used&lt;br /&gt;
    profile_data.TabThickness = 1.0&lt;br /&gt;
    -- if true then create 3d tabs else 2d tabs&lt;br /&gt;
    profile_data.Use3dTabs = true&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    profile_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object used to control ramping&lt;br /&gt;
    local ramping_data = RampingData()&lt;br /&gt;
    -- if true we do ramping into toolpath&lt;br /&gt;
    ramping_data.DoRamping = false&lt;br /&gt;
    -- type of ramping to perform RampingData.RAMP_LINEAR , RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
    -- or RampingData.RAMP_SPIRAL&lt;br /&gt;
    ramping_data.RampType = RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
    -- how ramp is contrained - either by angle or distance RampingData.CONSTRAIN_DISTANCE&lt;br /&gt;
    -- or RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
    ramping_data.RampConstraint = RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
    -- if we are constraining ramp by distance, distance to ramp over&lt;br /&gt;
    ramping_data.RampDistance = 100.0&lt;br /&gt;
    -- if we are contraining ramp by angle , angle to ramp in at (in degrees)&lt;br /&gt;
    ramping_data.RampAngle = 25.0&lt;br /&gt;
    -- if we are contraining ramp by angle, max distance to travel before 'zig zaging'&lt;br /&gt;
    -- if zig zaging&lt;br /&gt;
    ramping_data.RampMaxAngleDist = 15&lt;br /&gt;
    -- if true we restrict our ramping to lead in section of toolpath&lt;br /&gt;
    ramping_data.RampOnLeadIn = false&lt;br /&gt;
    -- Create object used to control lead in/out&lt;br /&gt;
    local lead_in_out_data = LeadInOutData()&lt;br /&gt;
    -- if true we create lead ins on profiles (not for profile on)&lt;br /&gt;
    lead_in_out_data.DoLeadIn = false&lt;br /&gt;
    -- if true we create lead outs on profiles (not for profile on)&lt;br /&gt;
    lead_in_out_data.DoLeadOut = false&lt;br /&gt;
    -- type of leads to create LeadInOutData.LINEAR_LEAD or LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
    lead_in_out_data.LeadType = LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
    -- length of lead to create&lt;br /&gt;
    lead_in_out_data.LeadLength = 10.0&lt;br /&gt;
    -- Angle for linear leads&lt;br /&gt;
    lead_in_out_data.LinearLeadAngle = 45&lt;br /&gt;
    -- Radius for circular arc leads&lt;br /&gt;
    lead_in_out_data.CirularLeadRadius = 5.0&lt;br /&gt;
    -- distance to 'overcut' (travel past start point) when profiling&lt;br /&gt;
    lead_in_out_data.OvercutDistance = 0.0&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateProfilingToolpath(name, tool, profile_data, ramping_data, lead_in_out_data, pos_data, geometry_selector, create_2d_previews, display_warnings )&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Prism Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreatePrismToolpath by Selection===&lt;br /&gt;
Create a Prism toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;  function CreatePrismToolpath(name, start_depth, cut_depth, vbit_angle, vbit_dia, vbit_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
  --[[ ------------------- CreatePrismToolpath -------------------&lt;br /&gt;
  |&lt;br /&gt;
  | Create a prism toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
  | vbit_angle -- angle of vbit to use&lt;br /&gt;
  | vbit_dia -- diameter of VBit to use&lt;br /&gt;
  | vbit_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_stepover_percent - percentage stepover for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua VBit&amp;quot;, Tool.VBIT ) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = vbit_dia&lt;br /&gt;
    tool.Stepdown = vbit_stepdown&lt;br /&gt;
    tool.Stepover = vbit_dia * (tool_stepover_percent / 100)&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = vbit_dia * (tool_stepover_percent / 100) * 2 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local prism_data = PrismCarveParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    prism_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    prism_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- or ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
    prism_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- calculate the minimum cut depth to fully form the bevel on the current&lt;br /&gt;
    -- selection with the current tool&lt;br /&gt;
    local min_bevel_depth = prism_data:CalculateMinimumBevelDepth(tool, true)&lt;br /&gt;
    if min_bevel_depth &amp;gt; cut_depth then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;A prism will not be fully formed with a depth of &amp;quot; .. cut_depth .. &amp;quot;\r\n&amp;quot; ..&lt;br /&gt;
                        &amp;quot;A depth of &amp;quot; .. min_bevel_depth .. &amp;quot; is required to fully form the prism&amp;quot;&lt;br /&gt;
                        )&lt;br /&gt;
    end -- if end&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePrismCarvingToolpath(name, tool, prism_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===CreatePrismToolpath by Layer Name===&lt;br /&gt;
Create a Prism toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function CreatePrismToolpath(layer_name, name, start_depth, cut_depth, vbit_angle, vbit_dia, vbit_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
  --[[ ------------------- CreatePrismToolpath -------------------&lt;br /&gt;
  |&lt;br /&gt;
  | Create a prism toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
  | vbit_angle -- angle of vbit to use&lt;br /&gt;
  | vbit_dia -- diameter of VBit to use&lt;br /&gt;
  | vbit_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_stepover_percent - percentage stepover for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
   -- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot; .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua VBit&amp;quot;, Tool.VBIT ) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = vbit_dia&lt;br /&gt;
    tool.Stepdown = vbit_stepdown&lt;br /&gt;
    tool.Stepover = vbit_dia * (tool_stepover_percent / 100)&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = vbit_dia * (tool_stepover_percent / 100) * 2 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local prism_data = PrismCarveParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    prism_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    prism_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
    prism_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- calculate the minimum cut depth to fully form the bevel on the current&lt;br /&gt;
    -- selection with the current tool&lt;br /&gt;
    local min_bevel_depth = prism_data:CalculateMinimumBevelDepth(tool, true)&lt;br /&gt;
    if min_bevel_depth &amp;gt; cut_depth then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;A prism will not be fully formed with a depth of &amp;quot; .. cut_depth .. &amp;quot;\r\n&amp;quot; ..&lt;br /&gt;
                        &amp;quot;A depth of &amp;quot; .. min_bevel_depth .. &amp;quot; is required to fully form the prism&amp;quot;)&lt;br /&gt;
    end -- if end&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePrismCarvingToolpath(name, tool, prism_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Example_Toolpath_Code&amp;diff=1100</id>
		<title>Example Toolpath Code</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Example_Toolpath_Code&amp;diff=1100"/>
		<updated>2024-11-16T17:32:46Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: /* CreatePocketingToolpath by Selection */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
These are Code Examples for toolpaths.&lt;br /&gt;
&lt;br /&gt;
==Selection by Layer Name==&lt;br /&gt;
&lt;br /&gt;
===SelectVectorsOnLayer===&lt;br /&gt;
Create a selection set by layer name and object type, retunes the selection set.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function SelectVectorsOnLayer(layer, selection, select_closed, select_open, select_groups)&lt;br /&gt;
  --[[ Please Note: SelectVectorsOnLayer is provided by Vectric and can be found in the SDK and Sample Gadget files.&lt;br /&gt;
  -- | ---------------- SelectVectorsOnLayer ----------------&lt;br /&gt;
  -- |   SelectVectorsOnLayer(&amp;quot;Stringer Profile&amp;quot;, selection, true, false, false)&lt;br /&gt;
  -- |   Add all the vectors on the layer to the selection&lt;br /&gt;
  -- |     layer,            -- layer we are selecting vectors on&lt;br /&gt;
  -- |     selection         -- selection object&lt;br /&gt;
  -- |     select_closed     -- if true  select closed objects&lt;br /&gt;
  -- |     select_open       -- if true  select open objects&lt;br /&gt;
  -- |     select_groups     -- if true select grouped vectors (irrespective of open / closed state of member objects)&lt;br /&gt;
  -- |  Return Values:  true if selected one or more vectors&lt;br /&gt;
  -- |&lt;br /&gt;
  -- ====================================================]]&lt;br /&gt;
  local objects_selected = false&lt;br /&gt;
  local warning_displayed = false&lt;br /&gt;
  local pos = layer:GetHeadPosition()&lt;br /&gt;
  while pos ~= nil do&lt;br /&gt;
    local object&lt;br /&gt;
    object, pos = layer:GetNext(pos)&lt;br /&gt;
    local contour = object:GetContour()&lt;br /&gt;
    if contour == nil then&lt;br /&gt;
      if (object.ClassName == &amp;quot;vcCadObjectGroup&amp;quot;) and select_groups then&lt;br /&gt;
        selection:Add(object, true, true)&lt;br /&gt;
        objects_selected = true&lt;br /&gt;
      else&lt;br /&gt;
        if not warning_displayed then&lt;br /&gt;
          local message = &amp;quot;Object(s) without contour information found on layer - ignoring&amp;quot;&lt;br /&gt;
          if not select_groups then&lt;br /&gt;
            message = message ..  &amp;quot;\r\n\r\n&amp;quot; ..&lt;br /&gt;
            &amp;quot;If layer contains grouped vectors these must be un-grouped for this script&amp;quot;&lt;br /&gt;
          end -- if end&lt;br /&gt;
          StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Select Vectors&amp;quot;, message, &amp;quot;(7200)&amp;quot;)&lt;br /&gt;
          warning_displayed = true&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- if end&lt;br /&gt;
    else  -- contour was NOT nil, test if Open or Closed&lt;br /&gt;
      if contour.IsOpen and select_open then&lt;br /&gt;
        selection:Add(object, true, true)&lt;br /&gt;
        objects_selected = true&lt;br /&gt;
      elseif select_closed then&lt;br /&gt;
        selection:Add(object, true, true)&lt;br /&gt;
        objects_selected = true&lt;br /&gt;
      end -- if end&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- while end&lt;br /&gt;
  -- to avoid excessive redrawing etc. we added vectors to the selection in 'batch' mode&lt;br /&gt;
  -- tell selection we have now finished updating&lt;br /&gt;
  if objects_selected then&lt;br /&gt;
    selection:GroupSelectionFinished()&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return objects_selected&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Pocketing Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreatePocketingToolpath by Selection===&lt;br /&gt;
Create a Pocketing toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreatePocketingToolpath(name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
--[[ ------------ CreatePocketingToolpath ------------&lt;br /&gt;
|| =====================================================&lt;br /&gt;
| Create a Pocketing toolpath within the program for the currently selected vectors&lt;br /&gt;
| Parameters:&lt;br /&gt;
| name, -- Name for toolpath&lt;br /&gt;
| start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
| cut_depth -- cut depth for pocket toolpath&lt;br /&gt;
| tool_dia -- diameter of end mill to use&lt;br /&gt;
| tool_stepdown -- stepdown for tool&lt;br /&gt;
| tool_stepover_percent -- percentage stepover for tool&lt;br /&gt;
| tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
|| =====================================================]]&lt;br /&gt;
-- Return Values:&lt;br /&gt;
-- true if toolpath created OK else false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&amp;quot;Lua End Mill&amp;quot;,Tool.END_MILL -- BALL_NOSE, END_MILL, VBIT)&lt;br /&gt;
  tool.InMM = tool_in_mm&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * (tool_stepover_percent / 100)&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC,...&lt;br /&gt;
  tool.FeedRate = 30&lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * (tool_stepover_percent / 100) -- used for vbit only&lt;br /&gt;
-- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
  pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
  pos_data.SafeZGap = 5.0&lt;br /&gt;
-- Create object used to pass pocketing options&lt;br /&gt;
  local pocket_data = PocketParameterData()&lt;br /&gt;
-- start depth for toolpath&lt;br /&gt;
  pocket_data.StartDepth = start_depth&lt;br /&gt;
-- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  pocket_data.CutDepth = cut_depth&lt;br /&gt;
-- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION or&lt;br /&gt;
-- ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
  pocket_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
-- Allowance to leave on when machining&lt;br /&gt;
  pocket_data.Allowance = 0.0&lt;br /&gt;
-- if true use raster clearance strategy , else use offset area clearance&lt;br /&gt;
  pocket_data.DoRasterClearance = true&lt;br /&gt;
-- angle for raster if using raster clearance&lt;br /&gt;
  pocket_data.RasterAngle = 0&lt;br /&gt;
-- type of profile pass to perform PocketParameterData.PROFILE_NONE ,&lt;br /&gt;
-- PocketParameterData.PROFILE_FIRST orPocketParameterData.PROFILE_LAST&lt;br /&gt;
  pocket_data.ProfilePassType = PocketParameterData.PROFILE_LAST&lt;br /&gt;
-- if true we ramp into pockets (always zig-zag)&lt;br /&gt;
  pocket_data.DoRamping = false&lt;br /&gt;
-- if ramping, distance to ramp over&lt;br /&gt;
  pocket_data.RampDistance = 10.0&lt;br /&gt;
-- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  pocket_data.ProjectToolpath = false&lt;br /&gt;
-- Create object which can be used to automatically select geometry&lt;br /&gt;
  local geometry_selector = GeometrySelector()&lt;br /&gt;
-- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
-- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
-- if we are doing two tool pocketing define tool to use for area clearance&lt;br /&gt;
  local area_clear_tool = nill&lt;br /&gt;
-- we just create a tool twice as large for testing here&lt;br /&gt;
  area_clear_tool = Tool(&amp;quot;Lua Clearance End Mill&amp;quot;,Tool.END_MILL) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
  area_clear_tool.InMM = tool_in_mm&lt;br /&gt;
  area_clear_tool.ToolDia = tool_dia * 2&lt;br /&gt;
  area_clear_tool.Stepdown = tool_stepdown * 2&lt;br /&gt;
  area_clear_tool.Stepover = tool_dia * 2 *(tool_stepover_percent / 100)&lt;br /&gt;
  area_clear_tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC..&lt;br /&gt;
  area_clear_tool.FeedRate = 30&lt;br /&gt;
  area_clear_tool.PlungeRate = 10&lt;br /&gt;
  area_clear_tool.SpindleSpeed = 20000&lt;br /&gt;
  area_clear_tool.ToolNumber = 1&lt;br /&gt;
  area_clear_tool.VBitAngle = 90.0 -- used for vbit only&lt;br /&gt;
  area_clear_tool.ClearStepover = tool_dia*2*(tool_stepover_percent/100) -- used for vbit&lt;br /&gt;
-- Create our toolpath&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreatePocketingToolpath(name, tool, area_clear_tool, pocket_data, pos_data, &lt;br /&gt;
                                                               geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
  if toolpath_id == nill then&lt;br /&gt;
     DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
     return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===CreatePocketingToolpath by Named Layer===&lt;br /&gt;
Create a Pocketing toolpath within the program for the named layer.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreateLayerPocketingToolpath(layer_name, name, start_depth, cut_depth)&lt;br /&gt;
  local caller = &amp;quot; - &amp;quot; .. name&lt;br /&gt;
  if Milling.Pocket then&lt;br /&gt;
    local selection = Milling.job.Selection  -- clear current selection&lt;br /&gt;
          selection:Clear()&lt;br /&gt;
  -- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot;   .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
   -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(MillTool2.Name, Tool.END_MILL)    -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
          tool.InMM = MillTool2.InMM            -- tool_in_mm&lt;br /&gt;
          tool.ToolDia = MillTool2.ToolDia         -- tool_dia&lt;br /&gt;
          tool.Stepdown = MillTool2.Stepdown        -- tool_stepdown&lt;br /&gt;
          tool.Stepover = MillTool2.Stepover        -- tool_dia * (tool_stepover_percent / 100)&lt;br /&gt;
          tool.RateUnits = MillTool2.RateUnits       -- Tool.MM_SEC     -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
          tool.FeedRate = MillTool2.FeedRate        -- 30&lt;br /&gt;
          tool.PlungeRate = MillTool2.PlungeRate      -- 10&lt;br /&gt;
          tool.SpindleSpeed = MillTool2.SpindleSpeed    -- 20000&lt;br /&gt;
          tool.ToolNumber = MillTool2.ToolNumber      -- 1&lt;br /&gt;
      --  tool.VBit_Angle = MillTool.VBit_Angle        -- 90.0            -- used for vbit only&lt;br /&gt;
      --  tool.ClearStepover = MillTool.ClearStepover   --  tool_dia * (tool_stepover_percent / 100)  -- used for vbit only&lt;br /&gt;
   -- we will set home position and safe z relative to material block size&lt;br /&gt;
    local mtl_block = MaterialBlock()&lt;br /&gt;
    local mtl_box = mtl_block.MaterialBox&lt;br /&gt;
    local mtl_box_blc = mtl_box.BLC&lt;br /&gt;
   -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
          pos_data:SetHomePosition(mtl_box_blc.x, mtl_box_blc.y, mtl_box.TRC.z + (mtl_block.Thickness * 0.2) )&lt;br /&gt;
          pos_data.SafeZGap = mtl_block.Thickness * 0.1&lt;br /&gt;
   -- Create  object used to pass pocketing options&lt;br /&gt;
    local pocket_data = PocketParameterData()&lt;br /&gt;
          -- start depth for toolpath&lt;br /&gt;
          pocket_data.StartDepth = start_depth&lt;br /&gt;
          -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
          pocket_data.CutDepth = cut_depth&lt;br /&gt;
          -- direction of cut for offset clearance - ProfileParameterData.CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION &lt;br /&gt;
          -- NOTE: enum from ProfileParameterData&lt;br /&gt;
          pocket_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
          -- Allowance to leave on when machining&lt;br /&gt;
          pocket_data.Allowance = 0.0&lt;br /&gt;
          -- if true use raster clearance strategy , else use offset area clearance&lt;br /&gt;
          pocket_data.DoRasterClearance = false --true&lt;br /&gt;
          -- angle for raster if using raster clearance&lt;br /&gt;
          pocket_data.RasterAngle = 0&lt;br /&gt;
          -- type of profile pass to perform  PocketParameterData.PROFILE_NONE , PocketParameterData.PROFILE_FIRST orPocketParameterData.PROFILE_LAST&lt;br /&gt;
          pocket_data.ProfilePassType = PocketParameterData.PROFILE_LAST&lt;br /&gt;
          -- if true we ramp into pockets (always zig-zag)&lt;br /&gt;
          pocket_data.DoRamping = false&lt;br /&gt;
          --  if ramping, distance to ramp over&lt;br /&gt;
          pocket_data.RampDistance = 1.0&lt;br /&gt;
          -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
          pocket_data.ProjectToolpath = false&lt;br /&gt;
   -- Create object which can used to automatically select geometry on layers etc.&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
   -- if this is true we create 2d toolpaths previews in 2d view, if false we don't&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
   -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings =  true -- false --&lt;br /&gt;
   -- if we are doing two tool pocketing define tool to use for area clearance&lt;br /&gt;
    local area_clear_tool = nil&lt;br /&gt;
    if Milling.Clearning then&lt;br /&gt;
   -- we just create a tool twice as large for testing here&lt;br /&gt;
     area_clear_tool = Tool(MillTool3.Name, Tool.END_MILL)  -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
     area_clear_tool.InMM = MillTool3.InMM       -- tool_in_mm&lt;br /&gt;
     area_clear_tool.ToolDia = MillTool3.ToolDia    -- tool_dia * 2&lt;br /&gt;
     area_clear_tool.Stepdown = MillTool3.Stepdown   -- tool_stepdown * 2&lt;br /&gt;
     area_clear_tool.Stepover = MillTool3.Stepover   -- tool_dia * 2 *(tool_stepover_percent / 100)&lt;br /&gt;
     area_clear_tool.RateUnits = MillTool3.RateUnits  -- Tool.MM_SEC  -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
     area_clear_tool.FeedRate = MillTool3.FeedRate      -- 30&lt;br /&gt;
     area_clear_tool.PlungeRate = MillTool3.PlungeRate    -- 10&lt;br /&gt;
     area_clear_tool.SpindleSpeed = MillTool3.SpindleSpeed  -- 20000&lt;br /&gt;
     area_clear_tool.ToolNumber = MillTool3.ToolNumber    -- 1&lt;br /&gt;
    end -- if end&lt;br /&gt;
     -- area_clear_tool.VBit_Angle = Carrier.MillTool3.VBit_Angle      -- 90.0 -- used for vbit only&lt;br /&gt;
     -- area_clear_tool.ClearStepover = Carrier.MillTool3.ClearStepover  -- tool_dia * 2 * (tool_stepover_percent / 100)  -- used for vbit only&lt;br /&gt;
   -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePocketingToolpath(&lt;br /&gt;
                                              name,&lt;br /&gt;
                                              tool,&lt;br /&gt;
                                              area_clear_tool,&lt;br /&gt;
                                              pocket_data,&lt;br /&gt;
                                              pos_data,&lt;br /&gt;
                                              geometry_selector,&lt;br /&gt;
                                              create_2d_previews,&lt;br /&gt;
                                              display_warnings&lt;br /&gt;
                                              )&lt;br /&gt;
    if toolpath_id  == nil  then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Milling Settings&amp;quot;, &amp;quot;Unable to create toolpath.&amp;quot;, &amp;quot;(4603)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
  end -- if end &lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Drilling Toolpath== &lt;br /&gt;
===Drilling Toolpath by Selection===&lt;br /&gt;
&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreateDrillingToolpath(name, start_depth, cut_depth, retract_gap, &lt;br /&gt;
                                          tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
--[[ ------- CreateDrillingToolpath --------------------------------------------------&lt;br /&gt;
||&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors&lt;br /&gt;
| Parameters:&lt;br /&gt;
| name, -- Name for toolpath&lt;br /&gt;
| start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
| cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
| retract_gap -- distance to retract above surface for pecks&lt;br /&gt;
| tool_dia -- diameter of drill to use&lt;br /&gt;
| tool_stepdown -- stepdown for tool&lt;br /&gt;
| tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
||&lt;br /&gt;
  Return Values:&lt;br /&gt;
|   true if toolpath created OK else false&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
-- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&amp;quot;Lua Drill&amp;quot;, Tool.THROUGH_DRILL) -- BALL_NOSE, END_MILL, VBIT, THROUGH_DRILL&lt;br /&gt;
  tool.InMM = tool_in_mm&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * 0.25&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
  tool.FeedRate = 30&lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBitAngle = 90.0 -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
-- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
        pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
        pos_data.SafeZGap = 5.0&lt;br /&gt;
-- Create object used to pass profile options&lt;br /&gt;
  local drill_data = DrillParameterData()&lt;br /&gt;
-- start depth for toolpath&lt;br /&gt;
  drill_data.StartDepth = start_depth&lt;br /&gt;
-- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  drill_data.CutDepth = cut_depth&lt;br /&gt;
-- if true perform peck drilling&lt;br /&gt;
  drill_data.DoPeckDrill = retract_gap &amp;gt; 0.0&lt;br /&gt;
-- distance to retract above surface when peck drilling&lt;br /&gt;
  drill_data.PeckRetractGap = retract_gap&lt;br /&gt;
-- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  drill_data.ProjectToolpath = false&lt;br /&gt;
-- Create object which can be used to automatically select geometry&lt;br /&gt;
  local geometry_selector = GeometrySelector()&lt;br /&gt;
-- if this is true we create 2d toolpaths previews in 2d view,&lt;br /&gt;
-- if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
-- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
-- Create our toolpath&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreateDrillingToolpath(name, tool, drill_data, pos_data, geometry_selector, &lt;br /&gt;
                                                            create_2d_previews, display_warnings)&lt;br /&gt;
  if toolpath_id == nil then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
    return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Drilling Toolpath by Named Layer===&lt;br /&gt;
&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreateDrillingToolpath(layer_name, name, start_depth, cut_depth, retract_gap, &lt;br /&gt;
                                          tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
--[[ ------- CreateDrillingToolpath --------------------------------------------------&lt;br /&gt;
||&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors&lt;br /&gt;
| Parameters:&lt;br /&gt;
| name, -- Name for toolpath&lt;br /&gt;
| start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
| cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
| retract_gap -- distance to retract above surface for pecks&lt;br /&gt;
| tool_dia -- diameter of drill to use&lt;br /&gt;
| tool_stepdown -- stepdown for tool&lt;br /&gt;
| tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
||&lt;br /&gt;
  Return Values:&lt;br /&gt;
|   true if toolpath created OK else false&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
-- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot;   .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
-- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&amp;quot;Lua Drill&amp;quot;, Tool.THROUGH_DRILL) -- BALL_NOSE, END_MILL, VBIT, THROUGH_DRILL&lt;br /&gt;
  tool.InMM = tool_in_mm&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * 0.25&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
  tool.FeedRate = 30&lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
-- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
        pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
        pos_data.SafeZGap = 5.0&lt;br /&gt;
-- Create object used to pass profile options&lt;br /&gt;
  local drill_data = DrillParameterData()&lt;br /&gt;
-- start depth for toolpath&lt;br /&gt;
  drill_data.StartDepth = start_depth&lt;br /&gt;
-- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  drill_data.CutDepth = cut_depth&lt;br /&gt;
-- if true perform peck drilling&lt;br /&gt;
  drill_data.DoPeckDrill = retract_gap &amp;gt; 0.0&lt;br /&gt;
-- distance to retract above surface when peck drilling&lt;br /&gt;
  drill_data.PeckRetractGap = retract_gap&lt;br /&gt;
-- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  drill_data.ProjectToolpath = false&lt;br /&gt;
-- Create object which can be used to automatically select geometry&lt;br /&gt;
  local geometry_selector = GeometrySelector()&lt;br /&gt;
-- if this is true we create 2d toolpaths previews in 2d view,&lt;br /&gt;
-- if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
-- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
-- Create our toolpath&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreateDrillingToolpath(name, tool, drill_data, pos_data, geometry_selector, &lt;br /&gt;
                                                            create_2d_previews, display_warnings)&lt;br /&gt;
  if toolpath_id == nil then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
    return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==V-Carve Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreateVCarveToolpath by Selection===&lt;br /&gt;
Create a V-Carve toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===CreateVCarveToolpath by Layer Name===&lt;br /&gt;
Create a V-Carve toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Fluting Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreateFlutingToolpath by Selection===&lt;br /&gt;
Create a Fluting toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;  function CreateFlutingToolpath(name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
    --[[ ----------------- CreateFlutingToolpath -----------------&lt;br /&gt;
  | Create a flutting toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for toolpath&lt;br /&gt;
  | tool_dia -- diameter of tool to use&lt;br /&gt;
  | tool_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua Ball Nose&amp;quot;, Tool.BALL_NOSE) -- BALL_NOSE, END_MILL, VBit_Angle, THROUGH_DRILL&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * 0.25&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass fluting options&lt;br /&gt;
    local fluting_data = FlutingParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    fluting_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    fluting_data.CutDepth = cut_depth&lt;br /&gt;
    -- type of fluting FULL_LENGTH, RAMP_START or RAMP_START_END&lt;br /&gt;
    fluting_data.FluteType = FlutingParameterData.RAMP_START_END&lt;br /&gt;
    -- type of ramping RAMP_LINEAR, RAMP_SMOOTH&lt;br /&gt;
    fluting_data.RampType = FlutingParameterData.RAMP_LINEAR&lt;br /&gt;
    -- if true use ratio field for controling ramp length else absolute length value&lt;br /&gt;
    fluting_data.UseRampRatio = false&lt;br /&gt;
    -- length of ramp as ratio of flute length(range 0 - 1.0)&lt;br /&gt;
    -- (for start and end - ratio is of half length)&lt;br /&gt;
    fluting_data.RampRatio = 0.2&lt;br /&gt;
    -- length to ramp over - if UseRampRatio == false&lt;br /&gt;
    fluting_data.RampLength = 15&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    fluting_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateFlutingToolpath(name, tool, fluting_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    else&lt;br /&gt;
      return true&lt;br /&gt;
    end -- if end &lt;br /&gt;
&lt;br /&gt;
    end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===CreateFlutingToolpath by Layer Name===&lt;br /&gt;
Create a Fluting toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Profile Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreateProfileToolpath by Selection===&lt;br /&gt;
Create a Profile toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===CreateProfileToolpath by Layer Name===&lt;br /&gt;
Create a Profile toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function CreateProfileToolpath(layer_name, name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
   -- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot;   .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua End Mill&amp;quot;, Tool.END_MILL) -- BALL_NOSE, END_MILL, VBit&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * 0.25&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC ...&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local profile_data = ProfileParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    profile_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    profile_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut - ProfileParameterData.&lt;br /&gt;
    -- CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION&lt;br /&gt;
    profile_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- side we machine on - ProfileParameterData.&lt;br /&gt;
    -- PROFILE_OUTSIDE, ProfileParameterData.PROFILE_INSIDE or&lt;br /&gt;
    -- ProfileParameterData.PROFILE_ON&lt;br /&gt;
    profile_data.ProfileSide = ProfileParameterData.PROFILE_OUTSIDE&lt;br /&gt;
    -- Allowance to leave on when machining&lt;br /&gt;
    profile_data.Allowance = 0.0&lt;br /&gt;
    -- true to preserve start point positions, false to reorder start&lt;br /&gt;
    -- points to minimise toolpath length&lt;br /&gt;
    profile_data.KeepStartPoints = false&lt;br /&gt;
    -- true if want to create 'square' external corners on toolpath&lt;br /&gt;
    profile_data.CreateSquareCorners = false&lt;br /&gt;
    -- true to perform corner sharpening on internal corners (only with v-bits)&lt;br /&gt;
    profile_data.CornerSharpen = false&lt;br /&gt;
    -- true to use tabs (position of tabs must already have been defined on vectors)&lt;br /&gt;
    profile_data.UseTabs = false&lt;br /&gt;
    -- length for tabs if being used&lt;br /&gt;
    profile_data.TabLength = 5.0&lt;br /&gt;
    -- Thickness for tabs if being used&lt;br /&gt;
    profile_data.TabThickness = 1.0&lt;br /&gt;
    -- if true then create 3d tabs else 2d tabs&lt;br /&gt;
    profile_data.Use3dTabs = true&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    profile_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object used to control ramping&lt;br /&gt;
    local ramping_data = RampingData()&lt;br /&gt;
    -- if true we do ramping into toolpath&lt;br /&gt;
    ramping_data.DoRamping = false&lt;br /&gt;
    -- type of ramping to perform RampingData.RAMP_LINEAR , RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
    -- or RampingData.RAMP_SPIRAL&lt;br /&gt;
    ramping_data.RampType = RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
    -- how ramp is contrained - either by angle or distance RampingData.CONSTRAIN_DISTANCE&lt;br /&gt;
    -- or RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
    ramping_data.RampConstraint = RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
    -- if we are constraining ramp by distance, distance to ramp over&lt;br /&gt;
    ramping_data.RampDistance = 100.0&lt;br /&gt;
    -- if we are contraining ramp by angle , angle to ramp in at (in degrees)&lt;br /&gt;
    ramping_data.RampAngle = 25.0&lt;br /&gt;
    -- if we are contraining ramp by angle, max distance to travel before 'zig zaging'&lt;br /&gt;
    -- if zig zaging&lt;br /&gt;
    ramping_data.RampMaxAngleDist = 15&lt;br /&gt;
    -- if true we restrict our ramping to lead in section of toolpath&lt;br /&gt;
    ramping_data.RampOnLeadIn = false&lt;br /&gt;
    -- Create object used to control lead in/out&lt;br /&gt;
    local lead_in_out_data = LeadInOutData()&lt;br /&gt;
    -- if true we create lead ins on profiles (not for profile on)&lt;br /&gt;
    lead_in_out_data.DoLeadIn = false&lt;br /&gt;
    -- if true we create lead outs on profiles (not for profile on)&lt;br /&gt;
    lead_in_out_data.DoLeadOut = false&lt;br /&gt;
    -- type of leads to create LeadInOutData.LINEAR_LEAD or LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
    lead_in_out_data.LeadType = LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
    -- length of lead to create&lt;br /&gt;
    lead_in_out_data.LeadLength = 10.0&lt;br /&gt;
    -- Angle for linear leads&lt;br /&gt;
    lead_in_out_data.LinearLeadAngle = 45&lt;br /&gt;
    -- Radius for circular arc leads&lt;br /&gt;
    lead_in_out_data.CirularLeadRadius = 5.0&lt;br /&gt;
    -- distance to 'overcut' (travel past start point) when profiling&lt;br /&gt;
    lead_in_out_data.OvercutDistance = 0.0&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateProfilingToolpath(name, tool, profile_data, ramping_data, lead_in_out_data, pos_data, geometry_selector, create_2d_previews, display_warnings )&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Prism Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreatePrismToolpath by Selection===&lt;br /&gt;
Create a Prism toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;  function CreatePrismToolpath(name, start_depth, cut_depth, vbit_angle, vbit_dia, vbit_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
  --[[ ------------------- CreatePrismToolpath -------------------&lt;br /&gt;
  |&lt;br /&gt;
  | Create a prism toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
  | vbit_angle -- angle of vbit to use&lt;br /&gt;
  | vbit_dia -- diameter of VBit to use&lt;br /&gt;
  | vbit_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_stepover_percent - percentage stepover for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua VBit&amp;quot;, Tool.VBIT ) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = vbit_dia&lt;br /&gt;
    tool.Stepdown = vbit_stepdown&lt;br /&gt;
    tool.Stepover = vbit_dia * (tool_stepover_percent / 100)&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = vbit_dia * (tool_stepover_percent / 100) * 2 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local prism_data = PrismCarveParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    prism_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    prism_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- or ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
    prism_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- calculate the minimum cut depth to fully form the bevel on the current&lt;br /&gt;
    -- selection with the current tool&lt;br /&gt;
    local min_bevel_depth = prism_data:CalculateMinimumBevelDepth(tool, true)&lt;br /&gt;
    if min_bevel_depth &amp;gt; cut_depth then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;A prism will not be fully formed with a depth of &amp;quot; .. cut_depth .. &amp;quot;\r\n&amp;quot; ..&lt;br /&gt;
                        &amp;quot;A depth of &amp;quot; .. min_bevel_depth .. &amp;quot; is required to fully form the prism&amp;quot;&lt;br /&gt;
                        )&lt;br /&gt;
    end -- if end&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePrismCarvingToolpath(name, tool, prism_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===CreatePrismToolpath by Layer Name===&lt;br /&gt;
Create a Prism toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function CreatePrismToolpath(layer_name, name, start_depth, cut_depth, vbit_angle, vbit_dia, vbit_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
  --[[ ------------------- CreatePrismToolpath -------------------&lt;br /&gt;
  |&lt;br /&gt;
  | Create a prism toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
  | vbit_angle -- angle of vbit to use&lt;br /&gt;
  | vbit_dia -- diameter of VBit to use&lt;br /&gt;
  | vbit_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_stepover_percent - percentage stepover for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
   -- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot; .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua VBit&amp;quot;, Tool.VBIT ) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = vbit_dia&lt;br /&gt;
    tool.Stepdown = vbit_stepdown&lt;br /&gt;
    tool.Stepover = vbit_dia * (tool_stepover_percent / 100)&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = vbit_dia * (tool_stepover_percent / 100) * 2 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local prism_data = PrismCarveParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    prism_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    prism_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
    prism_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- calculate the minimum cut depth to fully form the bevel on the current&lt;br /&gt;
    -- selection with the current tool&lt;br /&gt;
    local min_bevel_depth = prism_data:CalculateMinimumBevelDepth(tool, true)&lt;br /&gt;
    if min_bevel_depth &amp;gt; cut_depth then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;A prism will not be fully formed with a depth of &amp;quot; .. cut_depth .. &amp;quot;\r\n&amp;quot; ..&lt;br /&gt;
                        &amp;quot;A depth of &amp;quot; .. min_bevel_depth .. &amp;quot; is required to fully form the prism&amp;quot;)&lt;br /&gt;
    end -- if end&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePrismCarvingToolpath(name, tool, prism_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Example_Toolpath_Code&amp;diff=1099</id>
		<title>Example Toolpath Code</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Example_Toolpath_Code&amp;diff=1099"/>
		<updated>2024-11-16T17:31:20Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: /* Drilling Toolpath by Named Layer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
These are Code Examples for toolpaths.&lt;br /&gt;
&lt;br /&gt;
==Selection by Layer Name==&lt;br /&gt;
&lt;br /&gt;
===SelectVectorsOnLayer===&lt;br /&gt;
Create a selection set by layer name and object type, retunes the selection set.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function SelectVectorsOnLayer(layer, selection, select_closed, select_open, select_groups)&lt;br /&gt;
  --[[ Please Note: SelectVectorsOnLayer is provided by Vectric and can be found in the SDK and Sample Gadget files.&lt;br /&gt;
  -- | ---------------- SelectVectorsOnLayer ----------------&lt;br /&gt;
  -- |   SelectVectorsOnLayer(&amp;quot;Stringer Profile&amp;quot;, selection, true, false, false)&lt;br /&gt;
  -- |   Add all the vectors on the layer to the selection&lt;br /&gt;
  -- |     layer,            -- layer we are selecting vectors on&lt;br /&gt;
  -- |     selection         -- selection object&lt;br /&gt;
  -- |     select_closed     -- if true  select closed objects&lt;br /&gt;
  -- |     select_open       -- if true  select open objects&lt;br /&gt;
  -- |     select_groups     -- if true select grouped vectors (irrespective of open / closed state of member objects)&lt;br /&gt;
  -- |  Return Values:  true if selected one or more vectors&lt;br /&gt;
  -- |&lt;br /&gt;
  -- ====================================================]]&lt;br /&gt;
  local objects_selected = false&lt;br /&gt;
  local warning_displayed = false&lt;br /&gt;
  local pos = layer:GetHeadPosition()&lt;br /&gt;
  while pos ~= nil do&lt;br /&gt;
    local object&lt;br /&gt;
    object, pos = layer:GetNext(pos)&lt;br /&gt;
    local contour = object:GetContour()&lt;br /&gt;
    if contour == nil then&lt;br /&gt;
      if (object.ClassName == &amp;quot;vcCadObjectGroup&amp;quot;) and select_groups then&lt;br /&gt;
        selection:Add(object, true, true)&lt;br /&gt;
        objects_selected = true&lt;br /&gt;
      else&lt;br /&gt;
        if not warning_displayed then&lt;br /&gt;
          local message = &amp;quot;Object(s) without contour information found on layer - ignoring&amp;quot;&lt;br /&gt;
          if not select_groups then&lt;br /&gt;
            message = message ..  &amp;quot;\r\n\r\n&amp;quot; ..&lt;br /&gt;
            &amp;quot;If layer contains grouped vectors these must be un-grouped for this script&amp;quot;&lt;br /&gt;
          end -- if end&lt;br /&gt;
          StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Select Vectors&amp;quot;, message, &amp;quot;(7200)&amp;quot;)&lt;br /&gt;
          warning_displayed = true&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- if end&lt;br /&gt;
    else  -- contour was NOT nil, test if Open or Closed&lt;br /&gt;
      if contour.IsOpen and select_open then&lt;br /&gt;
        selection:Add(object, true, true)&lt;br /&gt;
        objects_selected = true&lt;br /&gt;
      elseif select_closed then&lt;br /&gt;
        selection:Add(object, true, true)&lt;br /&gt;
        objects_selected = true&lt;br /&gt;
      end -- if end&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- while end&lt;br /&gt;
  -- to avoid excessive redrawing etc. we added vectors to the selection in 'batch' mode&lt;br /&gt;
  -- tell selection we have now finished updating&lt;br /&gt;
  if objects_selected then&lt;br /&gt;
    selection:GroupSelectionFinished()&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return objects_selected&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Pocketing Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreatePocketingToolpath by Selection===&lt;br /&gt;
Create a Pocketing toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreatePocketingToolpath(name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
--[[ ------------ CreatePocketingToolpath ------------&lt;br /&gt;
|| =====================================================&lt;br /&gt;
| Create a Pocketing toolpath within the program for the currently selected vectors&lt;br /&gt;
| Parameters:&lt;br /&gt;
| name, -- Name for toolpath&lt;br /&gt;
| start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
| cut_depth -- cut depth for pocket toolpath&lt;br /&gt;
| tool_dia -- diameter of end mill to use&lt;br /&gt;
| tool_stepdown -- stepdown for tool&lt;br /&gt;
| tool_stepover_percent -- percentage stepover for tool&lt;br /&gt;
| tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
|| =====================================================]]&lt;br /&gt;
-- Return Values:&lt;br /&gt;
-- true if toolpath created OK else false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&amp;quot;Lua End Mill&amp;quot;,Tool.END_MILL -- BALL_NOSE, END_MILL, VBIT)&lt;br /&gt;
  tool.InMM = tool_in_mm&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * (tool_stepover_percent / 100)&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC,...&lt;br /&gt;
  tool.FeedRate = 30&lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBitAngle = 90.0 -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * (tool_stepover_percent / 100) -- used for vbit only&lt;br /&gt;
-- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
  pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
  pos_data.SafeZGap = 5.0&lt;br /&gt;
-- Create object used to pass pocketing options&lt;br /&gt;
  local pocket_data = PocketParameterData()&lt;br /&gt;
-- start depth for toolpath&lt;br /&gt;
  pocket_data.StartDepth = start_depth&lt;br /&gt;
-- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  pocket_data.CutDepth = cut_depth&lt;br /&gt;
-- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION or&lt;br /&gt;
-- ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
  pocket_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
-- Allowance to leave on when machining&lt;br /&gt;
  pocket_data.Allowance = 0.0&lt;br /&gt;
-- if true use raster clearance strategy , else use offset area clearance&lt;br /&gt;
  pocket_data.DoRasterClearance = true&lt;br /&gt;
-- angle for raster if using raster clearance&lt;br /&gt;
  pocket_data.RasterAngle = 0&lt;br /&gt;
-- type of profile pass to perform PocketParameterData.PROFILE_NONE ,&lt;br /&gt;
-- PocketParameterData.PROFILE_FIRST orPocketParameterData.PROFILE_LAST&lt;br /&gt;
  pocket_data.ProfilePassType = PocketParameterData.PROFILE_LAST&lt;br /&gt;
-- if true we ramp into pockets (always zig-zag)&lt;br /&gt;
  pocket_data.DoRamping = false&lt;br /&gt;
-- if ramping, distance to ramp over&lt;br /&gt;
  pocket_data.RampDistance = 10.0&lt;br /&gt;
-- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  pocket_data.ProjectToolpath = false&lt;br /&gt;
-- Create object which can be used to automatically select geometry&lt;br /&gt;
  local geometry_selector = GeometrySelector()&lt;br /&gt;
-- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
-- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
-- if we are doing two tool pocketing define tool to use for area clearance&lt;br /&gt;
  local area_clear_tool = nill&lt;br /&gt;
-- we just create a tool twice as large for testing here&lt;br /&gt;
  area_clear_tool = Tool(&amp;quot;Lua Clearance End Mill&amp;quot;,Tool.END_MILL) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
  area_clear_tool.InMM = tool_in_mm&lt;br /&gt;
  area_clear_tool.ToolDia = tool_dia * 2&lt;br /&gt;
  area_clear_tool.Stepdown = tool_stepdown * 2&lt;br /&gt;
  area_clear_tool.Stepover = tool_dia * 2 *(tool_stepover_percent / 100)&lt;br /&gt;
  area_clear_tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC..&lt;br /&gt;
  area_clear_tool.FeedRate = 30&lt;br /&gt;
  area_clear_tool.PlungeRate = 10&lt;br /&gt;
  area_clear_tool.SpindleSpeed = 20000&lt;br /&gt;
  area_clear_tool.ToolNumber = 1&lt;br /&gt;
  area_clear_tool.VBitAngle = 90.0 -- used for vbit only&lt;br /&gt;
  area_clear_tool.ClearStepover = tool_dia*2*(tool_stepover_percent/100) -- used for vbit&lt;br /&gt;
-- Create our toolpath&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreatePocketingToolpath(name, tool, area_clear_tool, pocket_data, pos_data, &lt;br /&gt;
                                                               geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
  if toolpath_id == nill then&lt;br /&gt;
     DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
     return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===CreatePocketingToolpath by Named Layer===&lt;br /&gt;
Create a Pocketing toolpath within the program for the named layer.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreateLayerPocketingToolpath(layer_name, name, start_depth, cut_depth)&lt;br /&gt;
  local caller = &amp;quot; - &amp;quot; .. name&lt;br /&gt;
  if Milling.Pocket then&lt;br /&gt;
    local selection = Milling.job.Selection  -- clear current selection&lt;br /&gt;
          selection:Clear()&lt;br /&gt;
  -- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot;   .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
   -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(MillTool2.Name, Tool.END_MILL)    -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
          tool.InMM = MillTool2.InMM            -- tool_in_mm&lt;br /&gt;
          tool.ToolDia = MillTool2.ToolDia         -- tool_dia&lt;br /&gt;
          tool.Stepdown = MillTool2.Stepdown        -- tool_stepdown&lt;br /&gt;
          tool.Stepover = MillTool2.Stepover        -- tool_dia * (tool_stepover_percent / 100)&lt;br /&gt;
          tool.RateUnits = MillTool2.RateUnits       -- Tool.MM_SEC     -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
          tool.FeedRate = MillTool2.FeedRate        -- 30&lt;br /&gt;
          tool.PlungeRate = MillTool2.PlungeRate      -- 10&lt;br /&gt;
          tool.SpindleSpeed = MillTool2.SpindleSpeed    -- 20000&lt;br /&gt;
          tool.ToolNumber = MillTool2.ToolNumber      -- 1&lt;br /&gt;
      --  tool.VBit_Angle = MillTool.VBit_Angle        -- 90.0            -- used for vbit only&lt;br /&gt;
      --  tool.ClearStepover = MillTool.ClearStepover   --  tool_dia * (tool_stepover_percent / 100)  -- used for vbit only&lt;br /&gt;
   -- we will set home position and safe z relative to material block size&lt;br /&gt;
    local mtl_block = MaterialBlock()&lt;br /&gt;
    local mtl_box = mtl_block.MaterialBox&lt;br /&gt;
    local mtl_box_blc = mtl_box.BLC&lt;br /&gt;
   -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
          pos_data:SetHomePosition(mtl_box_blc.x, mtl_box_blc.y, mtl_box.TRC.z + (mtl_block.Thickness * 0.2) )&lt;br /&gt;
          pos_data.SafeZGap = mtl_block.Thickness * 0.1&lt;br /&gt;
   -- Create  object used to pass pocketing options&lt;br /&gt;
    local pocket_data = PocketParameterData()&lt;br /&gt;
          -- start depth for toolpath&lt;br /&gt;
          pocket_data.StartDepth = start_depth&lt;br /&gt;
          -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
          pocket_data.CutDepth = cut_depth&lt;br /&gt;
          -- direction of cut for offset clearance - ProfileParameterData.CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION &lt;br /&gt;
          -- NOTE: enum from ProfileParameterData&lt;br /&gt;
          pocket_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
          -- Allowance to leave on when machining&lt;br /&gt;
          pocket_data.Allowance = 0.0&lt;br /&gt;
          -- if true use raster clearance strategy , else use offset area clearance&lt;br /&gt;
          pocket_data.DoRasterClearance = false --true&lt;br /&gt;
          -- angle for raster if using raster clearance&lt;br /&gt;
          pocket_data.RasterAngle = 0&lt;br /&gt;
          -- type of profile pass to perform  PocketParameterData.PROFILE_NONE , PocketParameterData.PROFILE_FIRST orPocketParameterData.PROFILE_LAST&lt;br /&gt;
          pocket_data.ProfilePassType = PocketParameterData.PROFILE_LAST&lt;br /&gt;
          -- if true we ramp into pockets (always zig-zag)&lt;br /&gt;
          pocket_data.DoRamping = false&lt;br /&gt;
          --  if ramping, distance to ramp over&lt;br /&gt;
          pocket_data.RampDistance = 1.0&lt;br /&gt;
          -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
          pocket_data.ProjectToolpath = false&lt;br /&gt;
   -- Create object which can used to automatically select geometry on layers etc.&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
   -- if this is true we create 2d toolpaths previews in 2d view, if false we don't&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
   -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings =  true -- false --&lt;br /&gt;
   -- if we are doing two tool pocketing define tool to use for area clearance&lt;br /&gt;
    local area_clear_tool = nil&lt;br /&gt;
    if Milling.Clearning then&lt;br /&gt;
   -- we just create a tool twice as large for testing here&lt;br /&gt;
     area_clear_tool = Tool(MillTool3.Name, Tool.END_MILL)  -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
     area_clear_tool.InMM = MillTool3.InMM       -- tool_in_mm&lt;br /&gt;
     area_clear_tool.ToolDia = MillTool3.ToolDia    -- tool_dia * 2&lt;br /&gt;
     area_clear_tool.Stepdown = MillTool3.Stepdown   -- tool_stepdown * 2&lt;br /&gt;
     area_clear_tool.Stepover = MillTool3.Stepover   -- tool_dia * 2 *(tool_stepover_percent / 100)&lt;br /&gt;
     area_clear_tool.RateUnits = MillTool3.RateUnits  -- Tool.MM_SEC  -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
     area_clear_tool.FeedRate = MillTool3.FeedRate      -- 30&lt;br /&gt;
     area_clear_tool.PlungeRate = MillTool3.PlungeRate    -- 10&lt;br /&gt;
     area_clear_tool.SpindleSpeed = MillTool3.SpindleSpeed  -- 20000&lt;br /&gt;
     area_clear_tool.ToolNumber = MillTool3.ToolNumber    -- 1&lt;br /&gt;
    end -- if end&lt;br /&gt;
     -- area_clear_tool.VBit_Angle = Carrier.MillTool3.VBit_Angle      -- 90.0 -- used for vbit only&lt;br /&gt;
     -- area_clear_tool.ClearStepover = Carrier.MillTool3.ClearStepover  -- tool_dia * 2 * (tool_stepover_percent / 100)  -- used for vbit only&lt;br /&gt;
   -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePocketingToolpath(&lt;br /&gt;
                                              name,&lt;br /&gt;
                                              tool,&lt;br /&gt;
                                              area_clear_tool,&lt;br /&gt;
                                              pocket_data,&lt;br /&gt;
                                              pos_data,&lt;br /&gt;
                                              geometry_selector,&lt;br /&gt;
                                              create_2d_previews,&lt;br /&gt;
                                              display_warnings&lt;br /&gt;
                                              )&lt;br /&gt;
    if toolpath_id  == nil  then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Milling Settings&amp;quot;, &amp;quot;Unable to create toolpath.&amp;quot;, &amp;quot;(4603)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
  end -- if end &lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Drilling Toolpath== &lt;br /&gt;
===Drilling Toolpath by Selection===&lt;br /&gt;
&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreateDrillingToolpath(name, start_depth, cut_depth, retract_gap, &lt;br /&gt;
                                          tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
--[[ ------- CreateDrillingToolpath --------------------------------------------------&lt;br /&gt;
||&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors&lt;br /&gt;
| Parameters:&lt;br /&gt;
| name, -- Name for toolpath&lt;br /&gt;
| start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
| cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
| retract_gap -- distance to retract above surface for pecks&lt;br /&gt;
| tool_dia -- diameter of drill to use&lt;br /&gt;
| tool_stepdown -- stepdown for tool&lt;br /&gt;
| tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
||&lt;br /&gt;
  Return Values:&lt;br /&gt;
|   true if toolpath created OK else false&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
-- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&amp;quot;Lua Drill&amp;quot;, Tool.THROUGH_DRILL) -- BALL_NOSE, END_MILL, VBIT, THROUGH_DRILL&lt;br /&gt;
  tool.InMM = tool_in_mm&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * 0.25&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
  tool.FeedRate = 30&lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBitAngle = 90.0 -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
-- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
        pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
        pos_data.SafeZGap = 5.0&lt;br /&gt;
-- Create object used to pass profile options&lt;br /&gt;
  local drill_data = DrillParameterData()&lt;br /&gt;
-- start depth for toolpath&lt;br /&gt;
  drill_data.StartDepth = start_depth&lt;br /&gt;
-- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  drill_data.CutDepth = cut_depth&lt;br /&gt;
-- if true perform peck drilling&lt;br /&gt;
  drill_data.DoPeckDrill = retract_gap &amp;gt; 0.0&lt;br /&gt;
-- distance to retract above surface when peck drilling&lt;br /&gt;
  drill_data.PeckRetractGap = retract_gap&lt;br /&gt;
-- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  drill_data.ProjectToolpath = false&lt;br /&gt;
-- Create object which can be used to automatically select geometry&lt;br /&gt;
  local geometry_selector = GeometrySelector()&lt;br /&gt;
-- if this is true we create 2d toolpaths previews in 2d view,&lt;br /&gt;
-- if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
-- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
-- Create our toolpath&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreateDrillingToolpath(name, tool, drill_data, pos_data, geometry_selector, &lt;br /&gt;
                                                            create_2d_previews, display_warnings)&lt;br /&gt;
  if toolpath_id == nil then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
    return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Drilling Toolpath by Named Layer===&lt;br /&gt;
&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreateDrillingToolpath(layer_name, name, start_depth, cut_depth, retract_gap, &lt;br /&gt;
                                          tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
--[[ ------- CreateDrillingToolpath --------------------------------------------------&lt;br /&gt;
||&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors&lt;br /&gt;
| Parameters:&lt;br /&gt;
| name, -- Name for toolpath&lt;br /&gt;
| start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
| cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
| retract_gap -- distance to retract above surface for pecks&lt;br /&gt;
| tool_dia -- diameter of drill to use&lt;br /&gt;
| tool_stepdown -- stepdown for tool&lt;br /&gt;
| tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
||&lt;br /&gt;
  Return Values:&lt;br /&gt;
|   true if toolpath created OK else false&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
-- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot;   .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
-- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&amp;quot;Lua Drill&amp;quot;, Tool.THROUGH_DRILL) -- BALL_NOSE, END_MILL, VBIT, THROUGH_DRILL&lt;br /&gt;
  tool.InMM = tool_in_mm&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * 0.25&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
  tool.FeedRate = 30&lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
-- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
        pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
        pos_data.SafeZGap = 5.0&lt;br /&gt;
-- Create object used to pass profile options&lt;br /&gt;
  local drill_data = DrillParameterData()&lt;br /&gt;
-- start depth for toolpath&lt;br /&gt;
  drill_data.StartDepth = start_depth&lt;br /&gt;
-- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  drill_data.CutDepth = cut_depth&lt;br /&gt;
-- if true perform peck drilling&lt;br /&gt;
  drill_data.DoPeckDrill = retract_gap &amp;gt; 0.0&lt;br /&gt;
-- distance to retract above surface when peck drilling&lt;br /&gt;
  drill_data.PeckRetractGap = retract_gap&lt;br /&gt;
-- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  drill_data.ProjectToolpath = false&lt;br /&gt;
-- Create object which can be used to automatically select geometry&lt;br /&gt;
  local geometry_selector = GeometrySelector()&lt;br /&gt;
-- if this is true we create 2d toolpaths previews in 2d view,&lt;br /&gt;
-- if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
-- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
-- Create our toolpath&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreateDrillingToolpath(name, tool, drill_data, pos_data, geometry_selector, &lt;br /&gt;
                                                            create_2d_previews, display_warnings)&lt;br /&gt;
  if toolpath_id == nil then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
    return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==V-Carve Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreateVCarveToolpath by Selection===&lt;br /&gt;
Create a V-Carve toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===CreateVCarveToolpath by Layer Name===&lt;br /&gt;
Create a V-Carve toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Fluting Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreateFlutingToolpath by Selection===&lt;br /&gt;
Create a Fluting toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;  function CreateFlutingToolpath(name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
    --[[ ----------------- CreateFlutingToolpath -----------------&lt;br /&gt;
  | Create a flutting toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for toolpath&lt;br /&gt;
  | tool_dia -- diameter of tool to use&lt;br /&gt;
  | tool_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua Ball Nose&amp;quot;, Tool.BALL_NOSE) -- BALL_NOSE, END_MILL, VBit_Angle, THROUGH_DRILL&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * 0.25&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass fluting options&lt;br /&gt;
    local fluting_data = FlutingParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    fluting_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    fluting_data.CutDepth = cut_depth&lt;br /&gt;
    -- type of fluting FULL_LENGTH, RAMP_START or RAMP_START_END&lt;br /&gt;
    fluting_data.FluteType = FlutingParameterData.RAMP_START_END&lt;br /&gt;
    -- type of ramping RAMP_LINEAR, RAMP_SMOOTH&lt;br /&gt;
    fluting_data.RampType = FlutingParameterData.RAMP_LINEAR&lt;br /&gt;
    -- if true use ratio field for controling ramp length else absolute length value&lt;br /&gt;
    fluting_data.UseRampRatio = false&lt;br /&gt;
    -- length of ramp as ratio of flute length(range 0 - 1.0)&lt;br /&gt;
    -- (for start and end - ratio is of half length)&lt;br /&gt;
    fluting_data.RampRatio = 0.2&lt;br /&gt;
    -- length to ramp over - if UseRampRatio == false&lt;br /&gt;
    fluting_data.RampLength = 15&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    fluting_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateFlutingToolpath(name, tool, fluting_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    else&lt;br /&gt;
      return true&lt;br /&gt;
    end -- if end &lt;br /&gt;
&lt;br /&gt;
    end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===CreateFlutingToolpath by Layer Name===&lt;br /&gt;
Create a Fluting toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Profile Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreateProfileToolpath by Selection===&lt;br /&gt;
Create a Profile toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===CreateProfileToolpath by Layer Name===&lt;br /&gt;
Create a Profile toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function CreateProfileToolpath(layer_name, name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
   -- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot;   .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua End Mill&amp;quot;, Tool.END_MILL) -- BALL_NOSE, END_MILL, VBit&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * 0.25&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC ...&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local profile_data = ProfileParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    profile_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    profile_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut - ProfileParameterData.&lt;br /&gt;
    -- CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION&lt;br /&gt;
    profile_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- side we machine on - ProfileParameterData.&lt;br /&gt;
    -- PROFILE_OUTSIDE, ProfileParameterData.PROFILE_INSIDE or&lt;br /&gt;
    -- ProfileParameterData.PROFILE_ON&lt;br /&gt;
    profile_data.ProfileSide = ProfileParameterData.PROFILE_OUTSIDE&lt;br /&gt;
    -- Allowance to leave on when machining&lt;br /&gt;
    profile_data.Allowance = 0.0&lt;br /&gt;
    -- true to preserve start point positions, false to reorder start&lt;br /&gt;
    -- points to minimise toolpath length&lt;br /&gt;
    profile_data.KeepStartPoints = false&lt;br /&gt;
    -- true if want to create 'square' external corners on toolpath&lt;br /&gt;
    profile_data.CreateSquareCorners = false&lt;br /&gt;
    -- true to perform corner sharpening on internal corners (only with v-bits)&lt;br /&gt;
    profile_data.CornerSharpen = false&lt;br /&gt;
    -- true to use tabs (position of tabs must already have been defined on vectors)&lt;br /&gt;
    profile_data.UseTabs = false&lt;br /&gt;
    -- length for tabs if being used&lt;br /&gt;
    profile_data.TabLength = 5.0&lt;br /&gt;
    -- Thickness for tabs if being used&lt;br /&gt;
    profile_data.TabThickness = 1.0&lt;br /&gt;
    -- if true then create 3d tabs else 2d tabs&lt;br /&gt;
    profile_data.Use3dTabs = true&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    profile_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object used to control ramping&lt;br /&gt;
    local ramping_data = RampingData()&lt;br /&gt;
    -- if true we do ramping into toolpath&lt;br /&gt;
    ramping_data.DoRamping = false&lt;br /&gt;
    -- type of ramping to perform RampingData.RAMP_LINEAR , RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
    -- or RampingData.RAMP_SPIRAL&lt;br /&gt;
    ramping_data.RampType = RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
    -- how ramp is contrained - either by angle or distance RampingData.CONSTRAIN_DISTANCE&lt;br /&gt;
    -- or RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
    ramping_data.RampConstraint = RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
    -- if we are constraining ramp by distance, distance to ramp over&lt;br /&gt;
    ramping_data.RampDistance = 100.0&lt;br /&gt;
    -- if we are contraining ramp by angle , angle to ramp in at (in degrees)&lt;br /&gt;
    ramping_data.RampAngle = 25.0&lt;br /&gt;
    -- if we are contraining ramp by angle, max distance to travel before 'zig zaging'&lt;br /&gt;
    -- if zig zaging&lt;br /&gt;
    ramping_data.RampMaxAngleDist = 15&lt;br /&gt;
    -- if true we restrict our ramping to lead in section of toolpath&lt;br /&gt;
    ramping_data.RampOnLeadIn = false&lt;br /&gt;
    -- Create object used to control lead in/out&lt;br /&gt;
    local lead_in_out_data = LeadInOutData()&lt;br /&gt;
    -- if true we create lead ins on profiles (not for profile on)&lt;br /&gt;
    lead_in_out_data.DoLeadIn = false&lt;br /&gt;
    -- if true we create lead outs on profiles (not for profile on)&lt;br /&gt;
    lead_in_out_data.DoLeadOut = false&lt;br /&gt;
    -- type of leads to create LeadInOutData.LINEAR_LEAD or LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
    lead_in_out_data.LeadType = LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
    -- length of lead to create&lt;br /&gt;
    lead_in_out_data.LeadLength = 10.0&lt;br /&gt;
    -- Angle for linear leads&lt;br /&gt;
    lead_in_out_data.LinearLeadAngle = 45&lt;br /&gt;
    -- Radius for circular arc leads&lt;br /&gt;
    lead_in_out_data.CirularLeadRadius = 5.0&lt;br /&gt;
    -- distance to 'overcut' (travel past start point) when profiling&lt;br /&gt;
    lead_in_out_data.OvercutDistance = 0.0&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateProfilingToolpath(name, tool, profile_data, ramping_data, lead_in_out_data, pos_data, geometry_selector, create_2d_previews, display_warnings )&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Prism Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreatePrismToolpath by Selection===&lt;br /&gt;
Create a Prism toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;  function CreatePrismToolpath(name, start_depth, cut_depth, vbit_angle, vbit_dia, vbit_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
  --[[ ------------------- CreatePrismToolpath -------------------&lt;br /&gt;
  |&lt;br /&gt;
  | Create a prism toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
  | vbit_angle -- angle of vbit to use&lt;br /&gt;
  | vbit_dia -- diameter of VBit to use&lt;br /&gt;
  | vbit_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_stepover_percent - percentage stepover for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua VBit&amp;quot;, Tool.VBIT ) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = vbit_dia&lt;br /&gt;
    tool.Stepdown = vbit_stepdown&lt;br /&gt;
    tool.Stepover = vbit_dia * (tool_stepover_percent / 100)&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = vbit_dia * (tool_stepover_percent / 100) * 2 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local prism_data = PrismCarveParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    prism_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    prism_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- or ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
    prism_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- calculate the minimum cut depth to fully form the bevel on the current&lt;br /&gt;
    -- selection with the current tool&lt;br /&gt;
    local min_bevel_depth = prism_data:CalculateMinimumBevelDepth(tool, true)&lt;br /&gt;
    if min_bevel_depth &amp;gt; cut_depth then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;A prism will not be fully formed with a depth of &amp;quot; .. cut_depth .. &amp;quot;\r\n&amp;quot; ..&lt;br /&gt;
                        &amp;quot;A depth of &amp;quot; .. min_bevel_depth .. &amp;quot; is required to fully form the prism&amp;quot;&lt;br /&gt;
                        )&lt;br /&gt;
    end -- if end&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePrismCarvingToolpath(name, tool, prism_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===CreatePrismToolpath by Layer Name===&lt;br /&gt;
Create a Prism toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function CreatePrismToolpath(layer_name, name, start_depth, cut_depth, vbit_angle, vbit_dia, vbit_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
  --[[ ------------------- CreatePrismToolpath -------------------&lt;br /&gt;
  |&lt;br /&gt;
  | Create a prism toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
  | vbit_angle -- angle of vbit to use&lt;br /&gt;
  | vbit_dia -- diameter of VBit to use&lt;br /&gt;
  | vbit_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_stepover_percent - percentage stepover for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
   -- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot; .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua VBit&amp;quot;, Tool.VBIT ) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = vbit_dia&lt;br /&gt;
    tool.Stepdown = vbit_stepdown&lt;br /&gt;
    tool.Stepover = vbit_dia * (tool_stepover_percent / 100)&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = vbit_dia * (tool_stepover_percent / 100) * 2 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local prism_data = PrismCarveParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    prism_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    prism_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
    prism_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- calculate the minimum cut depth to fully form the bevel on the current&lt;br /&gt;
    -- selection with the current tool&lt;br /&gt;
    local min_bevel_depth = prism_data:CalculateMinimumBevelDepth(tool, true)&lt;br /&gt;
    if min_bevel_depth &amp;gt; cut_depth then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;A prism will not be fully formed with a depth of &amp;quot; .. cut_depth .. &amp;quot;\r\n&amp;quot; ..&lt;br /&gt;
                        &amp;quot;A depth of &amp;quot; .. min_bevel_depth .. &amp;quot; is required to fully form the prism&amp;quot;)&lt;br /&gt;
    end -- if end&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePrismCarvingToolpath(name, tool, prism_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=ToolpathManager&amp;diff=1098</id>
		<title>ToolpathManager</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=ToolpathManager&amp;diff=1098"/>
		<updated>2024-11-16T17:24:29Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: /* Example Code: CreateLayerProfileToolpath */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
The ToolpathManager object is used to handle all the toolpaths within the program. Like the&lt;br /&gt;
MaterialBlock object there is one instance within the program which is accessed by any ToolpathManager object. For the initial release, the ToolpathManager is only used to create new toolpaths, load templates and recalculate all toolpaths, for future releases Vectric may offer more access to existing toolpaths depending on demand.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Constructor==&lt;br /&gt;
&lt;br /&gt;
===ToolpathManager===&lt;br /&gt;
 '''Returns:''' a new object which refers to the single toolpath manager within the program.&lt;br /&gt;
&lt;br /&gt;
'''For Example:'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;local toolpath_mgr = ToolpathManager() &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Properties==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.Count=== &lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (integer) the number of toolpaths&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.IsEmpty=== &lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (bool) true if there are no toolpaths&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.NumVisibleToolpaths=== &lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (integer) the number of visible toolpaths&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:AddExternalToolpath( ExternalToolpath toolpath)===&lt;br /&gt;
[[File:Top.jpg|right|30px|link=ToolpathManager]]&lt;br /&gt;
Adds the passed toolpath to the list of toolpaths in the job. &lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (bool) true if the toolpath was added OK, else false. See the documentation for ExternalToolpath for information on how to create the actual toolpath itself.&lt;br /&gt;
&lt;br /&gt;
::''toolpath (ExternalToolpath) toolpath created in a lua script which is added to job''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:CreateProfilingToolpath(String name,Tool tool,ProfileParameterData profile_data,RampingData ramping_data,LeadInOutData lead_data,ToolpathPosData pos_data,GeometrySelector geometry_selector,bool create_2d_preview,bool interactive)&lt;br /&gt;
Creates a profiling toolpath for the currently selected vectors. &lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' the UUID for the toolpath created.&lt;br /&gt;
&lt;br /&gt;
::''name(string) Name for the toolpath to be created''&lt;br /&gt;
::''tool (Tool) Tool to use for the toolpath''&lt;br /&gt;
::''profile_data (ProfileParameterData) Settings for profiling depth, inside or outside etc''&lt;br /&gt;
::''ramping_data (RampingData) Settings for ramping lead_data (LeadInOutData) Settings for lead in or out pos_data (ToolpathPosData) Settings for home position, safe z etc''&lt;br /&gt;
::''geometry_selector (GeometrySelector) Can be used to automatically select vectors on layers etc''&lt;br /&gt;
::''create_2d_preview(bool) If true create preview vectors in 2d view interactive(bool) If true display warnings etc to user''&lt;br /&gt;
&lt;br /&gt;
====Example Code: CreateLayerProfileToolpath====&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;from Profile_Vectors_On_Layer.lua&lt;br /&gt;
--[[  ---------------- CreateLayerProfileToolpath ----------------  &lt;br /&gt;
|&lt;br /&gt;
|   Create an outside Profile toolpath within the program for vectors on the passed layer&lt;br /&gt;
|  Parameters:&lt;br /&gt;
|     job               -- Job we are working with&lt;br /&gt;
|     layer_name        -- Name of layer we will profile vectors for&lt;br /&gt;
|     name              -- Name for toolpath&lt;br /&gt;
|     start_depth       -- Start depth for toolpath below surface of material&lt;br /&gt;
|     cut_depth         -- cut depth for profile toolpath&lt;br /&gt;
|     tool_dia          -- diameter of end mill to use&lt;br /&gt;
|     tool_stepdown     -- stepdown for tool&lt;br /&gt;
|     tool_in_mm        -- true if tool size and stepdown are in mm&lt;br /&gt;
|&lt;br /&gt;
|  Return Values:&lt;br /&gt;
|     true if toolpath created OK else false&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function CreateLayerProfileToolpath( job, layer_name, name , start_depth, cut_depth, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   -- clear current selection&lt;br /&gt;
   local selection = job.Selection&lt;br /&gt;
   selection:Clear()&lt;br /&gt;
   &lt;br /&gt;
   -- get layer&lt;br /&gt;
   local layer = job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
   &lt;br /&gt;
   if layer == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;No layer found with name = &amp;quot; .. &amp;quot;\&amp;quot;&amp;quot; ..  layer_name .. &amp;quot;\&amp;quot;&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
   end&lt;br /&gt;
&lt;br /&gt;
   &lt;br /&gt;
   -- select all closed vectors on the layer&lt;br /&gt;
   if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;No closed vectors found on layer &amp;quot; .. &amp;quot;\&amp;quot;&amp;quot; .. layer_name .. &amp;quot;\&amp;quot;&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
   end&lt;br /&gt;
   &lt;br /&gt;
   -- Create tool we will use to machine vectors&lt;br /&gt;
   local tool = Tool(&lt;br /&gt;
                    &amp;quot;Lua End Mill&amp;quot;, &lt;br /&gt;
                    Tool.END_MILL       -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
                    )&lt;br /&gt;
                     &lt;br /&gt;
   tool.InMM = tool_in_mm&lt;br /&gt;
   tool.ToolDia = tool_dia&lt;br /&gt;
   tool.Stepdown = tool_stepdown&lt;br /&gt;
   tool.Stepover = tool_dia * 0.25&lt;br /&gt;
   tool.Rate_Units = Tool.MM_SEC  -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
   tool.Feed_Rate = 30&lt;br /&gt;
   tool.Plunge_Rate = 10&lt;br /&gt;
   tool.Spindle_Speed = 20000&lt;br /&gt;
   tool.Tool_Number = 1&lt;br /&gt;
   tool.VBit_Angle = 90.0                -- used for vbit only&lt;br /&gt;
   tool.ClearStepover = tool_dia * 0.5  -- used for vbit only&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
   -- we will set home position and safe z relative to material block size  &lt;br /&gt;
   local mtl_block = MaterialBlock()  &lt;br /&gt;
   local mtl_box = mtl_block.MaterialBox&lt;br /&gt;
   local mtl_box_blc = mtl_box.BLC&lt;br /&gt;
  &lt;br /&gt;
   -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
   local pos_data = ToolpathPosData()&lt;br /&gt;
   pos_data:SetHomePosition(mtl_box_blc.x, mtl_box_blc.y, mtl_box.TRC.z + (mtl_block.Thickness * 0.2) )&lt;br /&gt;
   pos_data.SafeZGap = mtl_block.Thickness * 0.1&lt;br /&gt;
  &lt;br /&gt;
  &lt;br /&gt;
   -- Create  object used to pass profile options&lt;br /&gt;
   local profile_data = ProfileParameterData()&lt;br /&gt;
      -- start depth for toolpath&lt;br /&gt;
      profile_data.StartDepth = start_depth&lt;br /&gt;
      &lt;br /&gt;
      -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
      profile_data.CutDepth = cut_depth&lt;br /&gt;
      &lt;br /&gt;
      -- direction of cut - ProfileParameterData.CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION&lt;br /&gt;
      profile_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
      &lt;br /&gt;
      -- side we machine on - ProfileParameterData.PROFILE_OUTSIDE,  ProfileParameterData.PROFILE_INSIDE or ProfileParameterData.PROFILE_ON&lt;br /&gt;
      profile_data.ProfileSide = ProfileParameterData.PROFILE_OUTSIDE&lt;br /&gt;
      &lt;br /&gt;
      -- Allowance to leave on when machining&lt;br /&gt;
      profile_data.Allowance = 0.0&lt;br /&gt;
   &lt;br /&gt;
      -- true to preserve start point positions, false to reorder start points to minimise toolpath length   &lt;br /&gt;
      profile_data.KeepStartPoints = false&lt;br /&gt;
      &lt;br /&gt;
      -- true if want to create 'square' external corners on toolpath&lt;br /&gt;
      profile_data.CreateSquareCorners = false&lt;br /&gt;
      &lt;br /&gt;
      -- true to perform corner sharpening on internal corners (only with v-bits)&lt;br /&gt;
      profile_data.CornerSharpen = false&lt;br /&gt;
      &lt;br /&gt;
      -- true to use tabs (position of tabs must already have been defined on vectors)&lt;br /&gt;
      profile_data.UseTabs = false&lt;br /&gt;
      -- length for tabs if being used&lt;br /&gt;
      profile_data.TabLength = 5.0&lt;br /&gt;
      -- Thickness for tabs if being used&lt;br /&gt;
      profile_data.TabThickness = 1.0&lt;br /&gt;
      -- if true then create 3d tabs else 2d tabs&lt;br /&gt;
      profile_data.Use3dTabs  = true&lt;br /&gt;
      &lt;br /&gt;
      -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
      profile_data.ProjectToolpath = false&lt;br /&gt;
      &lt;br /&gt;
   -- Create object used to control ramping&lt;br /&gt;
   local ramping_data = RampingData()&lt;br /&gt;
      -- if true we do ramping into toolpath&lt;br /&gt;
      ramping_data.DoRamping = false&lt;br /&gt;
      -- type of ramping to perform RampingData.RAMP_LINEAR , RampingData.RAMP_ZIG_ZAG or RampingData.RAMP_SPIRAL&lt;br /&gt;
      ramping_data.RampType = RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
      -- how ramp is contrained - either by angle or distance RampingData.CONSTRAIN_DISTANCE or RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
      ramping_data.RampConstraint = RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
      -- if we are constraining ramp by distance, distance to ramp over&lt;br /&gt;
      ramping_data.RampDistance = 100.0&lt;br /&gt;
      -- if we are contraining ramp by angle , angle to ramp in at (in degrees)&lt;br /&gt;
      ramping_data.RampAngle = 25.0&lt;br /&gt;
      -- if we are contraining ramp by angle, max distance to travel before 'zig zaging' if zig zaging&lt;br /&gt;
      ramping_data.RampMaxAngleDist = 15&lt;br /&gt;
      -- if true we restrict our ramping to lead in section of toolpath&lt;br /&gt;
      ramping_data.RampOnLeadIn = false&lt;br /&gt;
      &lt;br /&gt;
   &lt;br /&gt;
   -- Create object used to control lead in/out&lt;br /&gt;
   local lead_in_out_data = LeadInOutData()&lt;br /&gt;
      -- if true we create lead ins on profiles (not for profile on) &lt;br /&gt;
      lead_in_out_data.DoLeadIn = false&lt;br /&gt;
      -- if true we create lead outs on profiles (not for profile on) &lt;br /&gt;
      lead_in_out_data.DoLeadOut = false&lt;br /&gt;
      -- type of leads to create LeadInOutData.LINEAR_LEAD or LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
      lead_in_out_data.LeadType = LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
      -- length of lead to create&lt;br /&gt;
      lead_in_out_data.LeadLength = 10.0&lt;br /&gt;
      -- Angle for linear leads&lt;br /&gt;
      lead_in_out_data.LinearLeadAngle = 45&lt;br /&gt;
      -- Radius for circular arc leads&lt;br /&gt;
      lead_in_out_data.CirularLeadRadius = 5.0&lt;br /&gt;
      -- distance to 'overcut' (travel past start point) when profiling&lt;br /&gt;
      lead_in_out_data.OvercutDistance = 0.0&lt;br /&gt;
&lt;br /&gt;
   -- Create object which can used to automatically select geometry on layers etc&lt;br /&gt;
   local geometry_selector = GeometrySelector() &lt;br /&gt;
   &lt;br /&gt;
   -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
   local create_2d_previews = true&lt;br /&gt;
   &lt;br /&gt;
   -- if this is true we will display errors and warning to the user&lt;br /&gt;
   local display_warnings = true&lt;br /&gt;
   &lt;br /&gt;
   -- Create our toolpath&lt;br /&gt;
&lt;br /&gt;
   local toolpath_manager = ToolpathManager()&lt;br /&gt;
 &lt;br /&gt;
   local toolpath_id = toolpath_manager:CreateProfilingToolpath(&lt;br /&gt;
                                              name,&lt;br /&gt;
                                              tool,&lt;br /&gt;
                                              profile_data,&lt;br /&gt;
                                              ramping_data,&lt;br /&gt;
                                              lead_in_out_data,&lt;br /&gt;
                                              pos_data,&lt;br /&gt;
											  geometry_selector,&lt;br /&gt;
                                              create_2d_previews,&lt;br /&gt;
                                              display_warnings&lt;br /&gt;
                                              )&lt;br /&gt;
   &lt;br /&gt;
   if toolpath_id  == nil  then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
   end                                                    &lt;br /&gt;
&lt;br /&gt;
   return true  &lt;br /&gt;
&lt;br /&gt;
end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===CreatePocketingToolpath()===&lt;br /&gt;
[[File:Top.jpg|right|30px|link=ToolpathManager]]&lt;br /&gt;
'''Usage:''' CreatePocketingToolpath(&lt;br /&gt;
:::::String name,&lt;br /&gt;
:::::Tool tool,&lt;br /&gt;
:::::Tool area_clear_tool,&lt;br /&gt;
:::::PocketParameterData pocket_data,&lt;br /&gt;
:::::ToolpathPosData pos_data,&lt;br /&gt;
:::::GeometrySelector geometry_selector,&lt;br /&gt;
:::::bool create_2d_preview,&lt;br /&gt;
:::::bool  interactive&lt;br /&gt;
:::::)&lt;br /&gt;
Creates a pocketing toolpath for the currently selected vectors. Return the UUID for the toolpath created.&lt;br /&gt;
&lt;br /&gt;
::''name(string) Name for the toolpath to be created ''&lt;br /&gt;
::''tool (Tool) Tool to use for the toolpath. Note: must not be nil ''&lt;br /&gt;
::''area_clear_tool (Tool) Optional tool for area clearance can be nil ''&lt;br /&gt;
::''pocket_data (PocketParameterData) Setting for pocketing depth, style etc ''&lt;br /&gt;
::''pos_data(ToolpathPosData) Settings for home position, safe z etc''&lt;br /&gt;
::''geometry_selector (GeometrySelector) Can be used to automatically select vectors on layers etc ''&lt;br /&gt;
::''create_2d_preview(bool) If true create preview vectors in 2d view ''&lt;br /&gt;
::''interactive(bool) If true display warnings etc to user''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Example Code: CreatePocketingToolpath====&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;from Create_Pocketing_Toolpath.lua&lt;br /&gt;
 -- VECTRIC LUA SCRIPT&lt;br /&gt;
 require &amp;quot;strict&amp;quot;&lt;br /&gt;
 --[[  -------------- CreatePocketingToolpath --------------------------------------------------  &lt;br /&gt;
|&lt;br /&gt;
|   Create a Pocketing toolpath within the program for the currently selected vectors&lt;br /&gt;
|  Parameters:&lt;br /&gt;
|     name,                 -- Name for toolpath&lt;br /&gt;
|     start_depth           -- Start depth for toolpath below surface of material&lt;br /&gt;
|     cut_depth             -- cut depth for pocket toolpath&lt;br /&gt;
|     tool_dia              -- diameter of end mill to use&lt;br /&gt;
|     tool_stepdown         -- stepdown for tool&lt;br /&gt;
|     tool_stepover_percent -- percentage stepover for tool&lt;br /&gt;
|     tool_in_mm            -- true if tool size and stepdown are in mm&lt;br /&gt;
|&lt;br /&gt;
|  Return Values:&lt;br /&gt;
|     true if toolpath created OK else false&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function CreatePocketingToolpath( name , start_depth, cut_depth, tool_dia, tool_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
&lt;br /&gt;
   -- Create tool we will use to machine vectors&lt;br /&gt;
   local tool = Tool(&lt;br /&gt;
                    &amp;quot;Lua End Mill&amp;quot;, &lt;br /&gt;
                    Tool.END_MILL       -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
                    )&lt;br /&gt;
                     &lt;br /&gt;
   tool.InMM = tool_in_mm&lt;br /&gt;
   tool.ToolDia = tool_dia&lt;br /&gt;
   tool.Stepdown = tool_stepdown&lt;br /&gt;
   tool.Stepover = tool_dia * (tool_stepover_percent / 100)&lt;br /&gt;
   tool.RateUnits = Tool.MM_SEC  -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
   tool.FeedRate = 30&lt;br /&gt;
   tool.PlungeRate = 10&lt;br /&gt;
   tool.SpindleSpeed = 20000&lt;br /&gt;
   tool.ToolNumber = 1&lt;br /&gt;
   tool.VBitAngle = 90.0                -- used for vbit only&lt;br /&gt;
   tool.ClearStepover = tool_dia * (tool_stepover_percent / 100)  -- used for vbit only&lt;br /&gt;
  &lt;br /&gt;
   -- we will set home position and safe z relative to material block size  &lt;br /&gt;
   local mtl_block = MaterialBlock()  &lt;br /&gt;
   local mtl_box = mtl_block.MaterialBox&lt;br /&gt;
   local mtl_box_blc = mtl_box.BLC&lt;br /&gt;
  &lt;br /&gt;
   -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
   local pos_data = ToolpathPosData()&lt;br /&gt;
   pos_data:SetHomePosition(mtl_box_blc.x, mtl_box_blc.y, mtl_box.TRC.z + (mtl_block.Thickness * 0.2) )&lt;br /&gt;
   pos_data.SafeZGap = mtl_block.Thickness * 0.1&lt;br /&gt;
  &lt;br /&gt;
   -- Create  object used to pass pocketing options&lt;br /&gt;
   local pocket_data = PocketParameterData()&lt;br /&gt;
      -- start depth for toolpath&lt;br /&gt;
      pocket_data.StartDepth = start_depth&lt;br /&gt;
      &lt;br /&gt;
      -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
      pocket_data.CutDepth = cut_depth&lt;br /&gt;
      &lt;br /&gt;
      -- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
      pocket_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
      &lt;br /&gt;
      -- Allowance to leave on when machining&lt;br /&gt;
      pocket_data.Allowance = 0.0&lt;br /&gt;
      &lt;br /&gt;
      -- if true use raster clearance strategy , else use offset area clearance&lt;br /&gt;
      pocket_data.DoRasterClearance = true&lt;br /&gt;
      -- angle for raster if using raster clearance&lt;br /&gt;
      pocket_data.RasterAngle = 0&lt;br /&gt;
      -- type of profile pass to perform  PocketParameterData.PROFILE_NONE , PocketParameterData.PROFILE_FIRST orPocketParameterData.PROFILE_LAST&lt;br /&gt;
      pocket_data.ProfilePassType = PocketParameterData.PROFILE_LAST&lt;br /&gt;
      &lt;br /&gt;
      -- if true we ramp into pockets (always zig-zag)&lt;br /&gt;
      pocket_data.DoRamping = false&lt;br /&gt;
      --  if ramping, distance to ramp over&lt;br /&gt;
      pocket_data.RampDistance = 10.0&lt;br /&gt;
      &lt;br /&gt;
      -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
      pocket_data.ProjectToolpath = false&lt;br /&gt;
&lt;br /&gt;
   -- Create object which can used to automatically select geometry on layers etc&lt;br /&gt;
  local geometry_selector = GeometrySelector() &lt;br /&gt;
        &lt;br /&gt;
   -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
   local create_2d_previews = true&lt;br /&gt;
   &lt;br /&gt;
   -- if this is true we will display errors and warning to the user&lt;br /&gt;
   local display_warnings = true&lt;br /&gt;
   &lt;br /&gt;
   -- if we are doing two tool pocketing define tool to use for area clearance&lt;br /&gt;
   local area_clear_tool = nil&lt;br /&gt;
   &lt;br /&gt;
   -- we just create a tool twice as large for testing here&lt;br /&gt;
   area_clear_tool = Tool(&lt;br /&gt;
                          &amp;quot;Lua Clearance End Mill&amp;quot;, &lt;br /&gt;
                          Tool.END_MILL       -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
                          )&lt;br /&gt;
                     &lt;br /&gt;
   area_clear_tool.InMM = tool_in_mm&lt;br /&gt;
   area_clear_tool.ToolDia = tool_dia * 2&lt;br /&gt;
   area_clear_tool.Stepdown = tool_stepdown * 2&lt;br /&gt;
   area_clear_tool.Stepover = tool_dia * 2 *(tool_stepover_percent / 100)&lt;br /&gt;
   area_clear_tool.RateUnits = Tool.MM_SEC  -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
   area_clear_tool.FeedRate = 30&lt;br /&gt;
   area_clear_tool.PlungeRate = 10&lt;br /&gt;
   area_clear_tool.SpindleSpeed = 20000&lt;br /&gt;
   area_clear_tool.ToolNumber = 1&lt;br /&gt;
   area_clear_tool.VBitAngle = 90.0                -- used for vbit only&lt;br /&gt;
   area_clear_tool.ClearStepover = tool_dia * 2 * (tool_stepover_percent / 100)  -- used for vbit only&lt;br /&gt;
   &lt;br /&gt;
   -- Create our toolpath&lt;br /&gt;
&lt;br /&gt;
   local toolpath_manager = ToolpathManager()&lt;br /&gt;
 &lt;br /&gt;
   local toolpath_id = toolpath_manager:CreatePocketingToolpath(&lt;br /&gt;
                                              name,&lt;br /&gt;
                                              tool,&lt;br /&gt;
                                              area_clear_tool,&lt;br /&gt;
                                              pocket_data,&lt;br /&gt;
                                              pos_data,&lt;br /&gt;
                                              geometry_selector,&lt;br /&gt;
                                              create_2d_previews,&lt;br /&gt;
                                              display_warnings&lt;br /&gt;
                                              )&lt;br /&gt;
   &lt;br /&gt;
   if toolpath_id  == nil  then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
   end                                                    &lt;br /&gt;
&lt;br /&gt;
   return true  &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[  ----------- main --------------------------------------------------  &lt;br /&gt;
|&lt;br /&gt;
|  Entry point for script&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function main()&lt;br /&gt;
&lt;br /&gt;
    -- Check we have a job loaded&lt;br /&gt;
    local job = VectricJob()&lt;br /&gt;
 &lt;br /&gt;
    if not job.Exists then&lt;br /&gt;
       DisplayMessageBox(&amp;quot;No job loaded&amp;quot;)&lt;br /&gt;
       return false;  &lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
   local selection = job.Selection&lt;br /&gt;
   if selection.IsEmpty  then&lt;br /&gt;
       MessageBox(&amp;quot;Please select one or more closed vectors to pocket&amp;quot;)&lt;br /&gt;
       return false  &lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
	local mtl_block = MaterialBlock()&lt;br /&gt;
	&lt;br /&gt;
    local start_depth = 0.0&lt;br /&gt;
    local cut_depth = mtl_block.Thickness * 0.25&lt;br /&gt;
    local tool_dia = 12.0&lt;br /&gt;
    local tool_stepdown = 2.5&lt;br /&gt;
    local tool_stepover_percent = 50.0&lt;br /&gt;
    local tool_in_mm = true&lt;br /&gt;
    &lt;br /&gt;
    local success = CreatePocketingToolpath( &lt;br /&gt;
                                           &amp;quot;Lua Pocketing Toolpath&amp;quot;, &lt;br /&gt;
                                           start_depth, &lt;br /&gt;
                                           cut_depth, &lt;br /&gt;
                                           tool_dia, &lt;br /&gt;
                                           tool_stepdown, &lt;br /&gt;
                                           tool_stepover_percent,&lt;br /&gt;
                                           tool_in_mm &lt;br /&gt;
                                           )&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    return success;&lt;br /&gt;
end     &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===:CreateDrillingToolpath===&lt;br /&gt;
[[File:Top.jpg|right|30px|link=ToolpathManager]]&lt;br /&gt;
'''Usage:''' :CreateDrillingToolpath(&lt;br /&gt;
:::::String name,&lt;br /&gt;
:::::Tool tool,&lt;br /&gt;
:::::DrillParameterData drilling_data,&lt;br /&gt;
:::::ToolpathPosData pos_data,&lt;br /&gt;
:::::GeometrySelectorgeometry_selector,&lt;br /&gt;
:::::bool create_2d_preview, &lt;br /&gt;
:::::bool  interactive)&lt;br /&gt;
Creates a drilling toolpath for the currently selected vectors. &lt;br /&gt;
&lt;br /&gt;
'''Returns:''' the UUID for the toolpath created.&lt;br /&gt;
::''name(string) Name for the toolpath to be created&lt;br /&gt;
::''tool(Tool) Tool to use for the toolpath &lt;br /&gt;
::''drill_data DrillParameterData Setting for drilling depth, peck etc &lt;br /&gt;
::''pos_data(ToolpathPosData) Settings for home position, safe z etc&lt;br /&gt;
::''geometry_selector(GeometrySelector) Can be used to automatically select vectors on layers etc &lt;br /&gt;
::''create_2d_preview(bool) If true create preview vectors in 2d view &lt;br /&gt;
::''interactive(bool) If true display warnings etc to user&lt;br /&gt;
&lt;br /&gt;
====Example Code: CreateDrillingToolpath====&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;from Create_Drilling_Toolpath.lua&lt;br /&gt;
&lt;br /&gt;
 -- VECTRIC LUA SCRIPT &lt;br /&gt;
 require &amp;quot;strict&amp;quot;&lt;br /&gt;
function CreateDrillingToolpath( name , start_depth, cut_depth, retract_gap, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
&lt;br /&gt;
   -- Create tool we will use to machine vectors&lt;br /&gt;
   local tool = Tool(&lt;br /&gt;
                    &amp;quot;Lua Drill&amp;quot;, &lt;br /&gt;
                    Tool.THROUGH_DRILL       -- BALL_NOSE, END_MILL, VBIT, THROUGH_DRILL&lt;br /&gt;
                    )&lt;br /&gt;
                     &lt;br /&gt;
   tool.InMM = tool_in_mm&lt;br /&gt;
   tool.ToolDia = tool_dia&lt;br /&gt;
   tool.Stepdown = tool_stepdown&lt;br /&gt;
   tool.Stepover = tool_dia * 0.25&lt;br /&gt;
   tool.RateUnits = Tool.MM_SEC  -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
   tool.FeedRate = 30&lt;br /&gt;
   tool.PlungeRate = 10&lt;br /&gt;
   tool.SpindleSpeed = 20000&lt;br /&gt;
   tool.ToolNumber = 1&lt;br /&gt;
   tool.VBitAngle = 90.0                -- used for vbit only&lt;br /&gt;
   tool.ClearStepover = tool_dia * 0.5  -- used for vbit only&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  -- we will set home position and safe z relative to material block size  &lt;br /&gt;
   local mtl_block = MaterialBlock()  &lt;br /&gt;
   local mtl_box = mtl_block.MaterialBox&lt;br /&gt;
   local mtl_box_blc = mtl_box.BLC&lt;br /&gt;
  &lt;br /&gt;
   -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
   local pos_data = ToolpathPosData()&lt;br /&gt;
   pos_data:SetHomePosition(mtl_box_blc.x, mtl_box_blc.y, mtl_box.TRC.z + (mtl_block.Thickness * 0.2) )&lt;br /&gt;
   pos_data.SafeZGap = mtl_block.Thickness * 0.1&lt;br /&gt;
  &lt;br /&gt;
   -- Create  object used to pass drilling options&lt;br /&gt;
   local drill_data = DrillParameterData()&lt;br /&gt;
      -- start depth for toolpath&lt;br /&gt;
      drill_data.StartDepth = start_depth&lt;br /&gt;
      &lt;br /&gt;
      -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
      drill_data.CutDepth = cut_depth&lt;br /&gt;
      &lt;br /&gt;
      -- if true perform peck drilling&lt;br /&gt;
      drill_data.DoPeckDrill = retract_gap &amp;gt; 0.0&lt;br /&gt;
      &lt;br /&gt;
      -- distance to retract above surface when peck drilling&lt;br /&gt;
      drill_data.PeckRetractGap = retract_gap&lt;br /&gt;
      &lt;br /&gt;
      -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
      drill_data.ProjectToolpath = false&lt;br /&gt;
      &lt;br /&gt;
   -- Create object which can used to automatically select geometry on layers etc&lt;br /&gt;
   local geometry_selector = GeometrySelector() &lt;br /&gt;
   &lt;br /&gt;
   -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
   local create_2d_previews = true&lt;br /&gt;
   &lt;br /&gt;
   -- if this is true we will display errors and warning to the user&lt;br /&gt;
   local display_warnings = true&lt;br /&gt;
   &lt;br /&gt;
   -- Create our toolpath&lt;br /&gt;
&lt;br /&gt;
   local toolpath_manager = ToolpathManager()&lt;br /&gt;
 &lt;br /&gt;
   local toolpath_id = toolpath_manager:CreateDrillingToolpath(&lt;br /&gt;
                                              name,&lt;br /&gt;
                                              tool,&lt;br /&gt;
                                              drill_data,&lt;br /&gt;
                                              pos_data,&lt;br /&gt;
											  geometry_selector,&lt;br /&gt;
                                              create_2d_previews,&lt;br /&gt;
                                              display_warnings&lt;br /&gt;
                                              )&lt;br /&gt;
   &lt;br /&gt;
   if toolpath_id  == nil  then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
   end                                                    &lt;br /&gt;
&lt;br /&gt;
   return true  &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[  ----------------- main ----------------- &lt;br /&gt;
|&lt;br /&gt;
|  Entry point for script&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function main()&lt;br /&gt;
&lt;br /&gt;
    -- Check we have a job loaded&lt;br /&gt;
    local job = VectricJob()&lt;br /&gt;
 &lt;br /&gt;
    if not job.Exists then&lt;br /&gt;
       DisplayMessageBox(&amp;quot;No job loaded&amp;quot;)&lt;br /&gt;
       return false;  &lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
   local selection = job.Selection&lt;br /&gt;
   if selection.IsEmpty  then&lt;br /&gt;
       MessageBox(&amp;quot;Please select one or more vectors to drill&amp;quot;)&lt;br /&gt;
       return false  &lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
	local mtl_block = MaterialBlock()&lt;br /&gt;
	&lt;br /&gt;
    local start_depth = 0.0&lt;br /&gt;
    local cut_depth = mtl_block.Thickness&lt;br /&gt;
    local tool_dia = 3.0&lt;br /&gt;
    local retract_gap = 1.0&lt;br /&gt;
    local tool_stepdown = 1.0&lt;br /&gt;
    local tool_in_mm = true&lt;br /&gt;
    &lt;br /&gt;
    local success = CreateDrillingToolpath( &lt;br /&gt;
                                          &amp;quot;Lua Drilling Toolpath&amp;quot;, &lt;br /&gt;
                                          start_depth, &lt;br /&gt;
                                          cut_depth, &lt;br /&gt;
                                          retract_gap,&lt;br /&gt;
                                          tool_dia, &lt;br /&gt;
                                          tool_stepdown, &lt;br /&gt;
                                          tool_in_mm &lt;br /&gt;
                                          )&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    return success;&lt;br /&gt;
end    &lt;br /&gt;
&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===:CreateVCarvingToolpath()===&lt;br /&gt;
[[File:Top.jpg|right|30px|link=ToolpathManager]]&lt;br /&gt;
'''Usage: ''':CreateVCarvingToolpath(&lt;br /&gt;
:::::String name,&lt;br /&gt;
:::::Tool tool,&lt;br /&gt;
:::::Tool area_clear_tool,&lt;br /&gt;
:::::VCarveParameterData vcarve_data,&lt;br /&gt;
:::::PocketParameterData pocket_data,&lt;br /&gt;
:::::ToolpathPosData pos_data,&lt;br /&gt;
:::::GeometrySelector geometry_selector, &lt;br /&gt;
:::::bool create_2d_preview,&lt;br /&gt;
:::::bool  interactive)&lt;br /&gt;
Creates a vcarving toolpath for the currently selected vectors. &lt;br /&gt;
&lt;br /&gt;
'''Returns:''' the UUID for the toolpath created.&lt;br /&gt;
::''name(string) Name for the toolpath to be created ''&lt;br /&gt;
::''tool (Tool) Tool to use for the toolpath Note: must not be nil ''&lt;br /&gt;
::''area_clear_tool(Tool) Optional tool for area clearance can be nil ''&lt;br /&gt;
::''vcarve_data(VCarveParameterData) Settings for vcarving''&lt;br /&gt;
::''pocket_data(PocketParameterData) Setting for pocketing depth, style etc ''&lt;br /&gt;
::''pos_data(ToolpathPosData) Settings for home position, safe z etc''&lt;br /&gt;
::''geometry_selector(GeometrySelector) Can be used to automatically select vectors on layers etc ''&lt;br /&gt;
::''create_2d_preview(bool) If true create preview vectors in 2d view ''&lt;br /&gt;
::''interactive(bool) If true display warnings etc to user''&lt;br /&gt;
&lt;br /&gt;
====Example Code: CreateVCarvingToolpath====&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;from Create_VCarving_Toolpath.lua&lt;br /&gt;
 -- VECTRIC LUA SCRIPT&lt;br /&gt;
 require &amp;quot;strict&amp;quot;&lt;br /&gt;
--[[  ------------- CreateVCarvingToolpath --------------------------------------------------  &lt;br /&gt;
|&lt;br /&gt;
|   Create a VCarving toolpath within the program for the currently selected vectors&lt;br /&gt;
|  Parameters:&lt;br /&gt;
|    name,                 -- name for toolpath&lt;br /&gt;
|    start_depth           -- start depth for toolpath below surface of material&lt;br /&gt;
|    flat_depth            -- flat depth - if 0.0 assume not doing flat bottom&lt;br /&gt;
|    vbit_angle            -- angle of vbit to use&lt;br /&gt;
|    vbit_dia              -- diameter of VBit  to use&lt;br /&gt;
|    vbit_stepdown         -- stepdown for tool&lt;br /&gt;
|    tool_stepover_percent -- percentage stepover for tool&lt;br /&gt;
|    tool_in_mm            -- true if tool size and stepdown are in mm&lt;br /&gt;
|&lt;br /&gt;
|  Return Values:&lt;br /&gt;
|     true if toolpath created OK else false&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function CreateVCarvingToolpath( name , start_depth, flat_depth, vbit_angle, vbit_dia, vbit_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
&lt;br /&gt;
   -- Create tool we will use to machine vectors&lt;br /&gt;
   local tool = Tool(&lt;br /&gt;
                    &amp;quot;Lua VBit&amp;quot;, &lt;br /&gt;
                    Tool.VBIT       -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
                    )&lt;br /&gt;
                     &lt;br /&gt;
   tool.InMM = tool_in_mm&lt;br /&gt;
   tool.ToolDia = vbit_dia&lt;br /&gt;
   tool.Stepdown = vbit_stepdown&lt;br /&gt;
   tool.Stepover = vbit_dia * (tool_stepover_percent / 100)&lt;br /&gt;
   tool.RateUnits = Tool.MM_SEC  -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
   tool.FeedRate = 30&lt;br /&gt;
   tool.PlungeRate = 10&lt;br /&gt;
   tool.SpindleSpeed = 20000&lt;br /&gt;
   tool.ToolNumber = 1&lt;br /&gt;
   tool.VBitAngle = 90.0                -- used for vbit only&lt;br /&gt;
   tool.ClearStepover = vbit_dia * (tool_stepover_percent / 100) * 2  -- used for vbit only&lt;br /&gt;
  &lt;br /&gt;
   -- we will set home position and safe z relative to material block size  &lt;br /&gt;
   local mtl_block = MaterialBlock()  &lt;br /&gt;
   local mtl_box = mtl_block.MaterialBox&lt;br /&gt;
   local mtl_box_blc = mtl_box.BLC&lt;br /&gt;
  &lt;br /&gt;
   -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
   local pos_data = ToolpathPosData()&lt;br /&gt;
   pos_data:SetHomePosition(mtl_box_blc.x, mtl_box_blc.y, mtl_box.TRC.z + (mtl_block.Thickness * 0.2) )&lt;br /&gt;
   pos_data.SafeZGap = mtl_block.Thickness * 0.1&lt;br /&gt;
&lt;br /&gt;
   -- Create  object used to pass vcarving options&lt;br /&gt;
   local vcarve_data = VCarveParameterData()&lt;br /&gt;
      -- start depth for toolpath&lt;br /&gt;
      vcarve_data.StartDepth = start_depth&lt;br /&gt;
      &lt;br /&gt;
      -- flag indicating if we are creating a flat bottomed toolpath&lt;br /&gt;
      vcarve_data.DoFlatBottom = flat_depth &amp;gt; 0.0&lt;br /&gt;
      &lt;br /&gt;
      -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
      vcarve_data.FlatDepth = flat_depth&lt;br /&gt;
      &lt;br /&gt;
      -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
      vcarve_data.ProjectToolpath = false&lt;br /&gt;
&lt;br /&gt;
      -- set flag indicating we are using flat tool&lt;br /&gt;
	  vcarve_data.UseAreaClearTool = true&lt;br /&gt;
      &lt;br /&gt;
   -- Create  object used to pass pocketing options - used for area clearance only&lt;br /&gt;
   local pocket_data = PocketParameterData()&lt;br /&gt;
      -- start depth for toolpath&lt;br /&gt;
      pocket_data.StartDepth = start_depth&lt;br /&gt;
      &lt;br /&gt;
      -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
      pocket_data.CutDepth = flat_depth&lt;br /&gt;
      &lt;br /&gt;
      -- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
      pocket_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
      &lt;br /&gt;
      -- if true use raster clearance strategy , else use offset area clearance&lt;br /&gt;
      pocket_data.DoRasterClearance = false&lt;br /&gt;
      -- angle for raster if using raster clearance&lt;br /&gt;
      pocket_data.RasterAngle = 0&lt;br /&gt;
      -- type of profile pass to perform  PocketParameterData.PROFILE_NONE , PocketParameterData.PROFILE_FIRST orPocketParameterData.PROFILE_LAST&lt;br /&gt;
      pocket_data.ProfilePassType = PocketParameterData.PROFILE_LAST&lt;br /&gt;
      &lt;br /&gt;
   -- Create object which can used to automatically select geometry on layers etc&lt;br /&gt;
   local geometry_selector = GeometrySelector() &lt;br /&gt;
   &lt;br /&gt;
   -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
   local create_2d_previews = true&lt;br /&gt;
   &lt;br /&gt;
   -- if this is true we will display errors and warning to the user&lt;br /&gt;
   local display_warnings = true&lt;br /&gt;
   &lt;br /&gt;
   -- if we are doing two tool pocketing define tool to use for area clearance&lt;br /&gt;
   local area_clear_tool = nil&lt;br /&gt;
   &lt;br /&gt;
   -- we just create a 10mm end mill&lt;br /&gt;
  &lt;br /&gt;
   area_clear_tool = Tool(&lt;br /&gt;
                          &amp;quot;Lua Clearance End Mill&amp;quot;, &lt;br /&gt;
                          Tool.END_MILL       -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
                          )&lt;br /&gt;
                     &lt;br /&gt;
   area_clear_tool.InMM = true&lt;br /&gt;
   area_clear_tool.ToolDia = 10&lt;br /&gt;
   area_clear_tool.Stepdown = 3&lt;br /&gt;
   area_clear_tool.Stepover = 3&lt;br /&gt;
   area_clear_tool.RateUnits = Tool.MM_SEC  -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
   area_clear_tool.FeedRate = 30&lt;br /&gt;
   area_clear_tool.PlungeRate = 10&lt;br /&gt;
   area_clear_tool.SpindleSpeed = 20000&lt;br /&gt;
   area_clear_tool.ToolNumber = 2&lt;br /&gt;
   &lt;br /&gt;
   -- Create our toolpath&lt;br /&gt;
&lt;br /&gt;
   local toolpath_manager = ToolpathManager()&lt;br /&gt;
 &lt;br /&gt;
   local toolpath_id = toolpath_manager:CreateVCarvingToolpath(&lt;br /&gt;
                                              name,&lt;br /&gt;
                                              tool,&lt;br /&gt;
                                              area_clear_tool,&lt;br /&gt;
                                              vcarve_data,&lt;br /&gt;
                                              pocket_data,&lt;br /&gt;
                                              pos_data,&lt;br /&gt;
                                              geometry_selector,&lt;br /&gt;
                                              create_2d_previews,&lt;br /&gt;
                                              display_warnings&lt;br /&gt;
                                              )&lt;br /&gt;
   &lt;br /&gt;
   if toolpath_id  == nil  then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
   end                                                    &lt;br /&gt;
&lt;br /&gt;
   return true  &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[  ------------- main --------------------------------------------------  &lt;br /&gt;
|&lt;br /&gt;
|  Entry point for script&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function main()&lt;br /&gt;
&lt;br /&gt;
    -- Check we have a document loaded&lt;br /&gt;
    local job = VectricJob()&lt;br /&gt;
 &lt;br /&gt;
    if not job.Exists then&lt;br /&gt;
       DisplayMessageBox(&amp;quot;No job loaded&amp;quot;)&lt;br /&gt;
       return false;  &lt;br /&gt;
    end&lt;br /&gt;
 &lt;br /&gt;
   local selection = job.Selection&lt;br /&gt;
   if selection.IsEmpty  then&lt;br /&gt;
       MessageBox(&amp;quot;Please select one or more vectors to VCarve&amp;quot;)&lt;br /&gt;
       return false  &lt;br /&gt;
    end&lt;br /&gt;
    &lt;br /&gt;
	local mtl_block = MaterialBlock()&lt;br /&gt;
	&lt;br /&gt;
    local start_depth = 0.0&lt;br /&gt;
    local flat_depth = mtl_block.Thickness * 0.5&lt;br /&gt;
    local vbit_angle = 90.0&lt;br /&gt;
    local tool_dia = 32.0&lt;br /&gt;
    local tool_stepdown = 2.5&lt;br /&gt;
    local tool_stepover_percent = 2.0&lt;br /&gt;
    local tool_in_mm = true&lt;br /&gt;
    &lt;br /&gt;
    local success = CreateVCarvingToolpath( &lt;br /&gt;
                                           &amp;quot;Lua VCarving Toolpath&amp;quot;, &lt;br /&gt;
                                           start_depth, &lt;br /&gt;
                                           flat_depth, &lt;br /&gt;
                                           vbit_angle,&lt;br /&gt;
                                           tool_dia, &lt;br /&gt;
                                           tool_stepdown, &lt;br /&gt;
                                           tool_stepover_percent,&lt;br /&gt;
                                           tool_in_mm &lt;br /&gt;
                                           )&lt;br /&gt;
    &lt;br /&gt;
    &lt;br /&gt;
    return success;&lt;br /&gt;
end     &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===:CreatePrismCarvingToolpath(===&lt;br /&gt;
[[File:Top.jpg|right|30px|link=ToolpathManager]]&lt;br /&gt;
'''Usage:''' :CreatePrismCarvingToolpath(&lt;br /&gt;
:::::String name,&lt;br /&gt;
:::::Tool tool,&lt;br /&gt;
:::::PrismCarveParameterData prism_data,&lt;br /&gt;
:::::ToolpathPosData pos_data,&lt;br /&gt;
:::::GeometrySelectorgeometry_selector,&lt;br /&gt;
:::::bool create_2d_preview,&lt;br /&gt;
:::::bool  interactive)&lt;br /&gt;
Creates a prism carving toolpath for the currently selected vectors. &lt;br /&gt;
&lt;br /&gt;
'''Returns:''' the UUID for the toolpath created.&lt;br /&gt;
::''name(string) Name for the toolpath to be created''&lt;br /&gt;
::''tool (Tool) Tool to use for the toolpath  ''&lt;br /&gt;
::''prism_data (PrismParameterData) Settings for prism carving ''&lt;br /&gt;
::''pos_data (ToolpathPosData) Settings for home position, safe z etc''&lt;br /&gt;
::''geometry_selector (GeometrySelector) Can be used to automatically select vectors on layers etc ''&lt;br /&gt;
::''create_2d_preview(bool) If true create preview vectors in 2d view ''&lt;br /&gt;
::''interactive(bool) If true display warnings etc to user''&lt;br /&gt;
&lt;br /&gt;
====Example Code: CreatePrismToolpath====&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;from Create_Prism_CarvingToolpath.lua&lt;br /&gt;
 -- VECTRIC LUA SCRIPT require &amp;quot;strict&amp;quot;&lt;br /&gt;
 -- [[ CreatePrismToolpath &lt;br /&gt;
|&lt;br /&gt;
|   Create a prism toolpath within the program for the currently selected vectors&lt;br /&gt;
|  Parameters:&lt;br /&gt;
|     name,                -- Name for toolpath&lt;br /&gt;
|     start_depth      -- Start depth for toolpath below surface of material&lt;br /&gt;
|    cut_depth          -- cut depth for drilling toolpath&lt;br /&gt;
|    vbit_angle         -- angle of vbit to use&lt;br /&gt;
|    vbit_dia            -- diameter of VBit  to use&lt;br /&gt;
|    vbit_stepdown    -- stepdown for tool&lt;br /&gt;
|    tool_stepover_percent -- percentage stepover for tool&lt;br /&gt;
|    tool_in_mm        -- true if tool size and stepdown are in mm&lt;br /&gt;
|&lt;br /&gt;
|  returns (Values:&lt;br /&gt;
|     true if toolpath created OK else false&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
function CreatePrismToolpath( name , start_depth, cut_depth, vbit_angle,&lt;br /&gt;
vbit_dia, vbit_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
 -- Create tool we will use to machine vectors&lt;br /&gt;
local tool = Tool(&lt;br /&gt;
&amp;quot;Lua VBit&amp;quot;,&lt;br /&gt;
Tool.VBIT      -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
tool.InMM = tool_in_mm&lt;br /&gt;
===.tool.ToolDia = vbit_dia=== &lt;br /&gt;
tool.Stepdown = vbit_stepdown&lt;br /&gt;
tool.Stepover = vbit_dia * (tool_stepover_percent or 100)&lt;br /&gt;
tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN,                                  -- INCHES_SEC, INCHES_MIN, FEET_MIN    tool.FeedRate = 30&lt;br /&gt;
tool.PlungeRate = 10&lt;br /&gt;
tool.SpindleSpeed = 20000&lt;br /&gt;
tool.ToolNumber = 1&lt;br /&gt;
tool.VBitAngle = 90.0               -- used for vbit only&lt;br /&gt;
tool.ClearStepover = vbit_dia * (tool_stepover_percent or 100) * 2 -- used for vbit only&lt;br /&gt;
 -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
local pos_data = ToolpathPosData()&lt;br /&gt;
&lt;br /&gt;
pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
pos_data.SafeZGap = 5.0&lt;br /&gt;
&lt;br /&gt;
 -- Create  object used to pass profile options&lt;br /&gt;
local prism_data = PrismCarveParameterData()&lt;br /&gt;
 -- start depth for toolpath&lt;br /&gt;
prism_data.StartDepth = start_depth&lt;br /&gt;
&lt;br /&gt;
 -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
prism_data.CutDepth = cut_depth&lt;br /&gt;
&lt;br /&gt;
 -- direction of cut for offet clearance (ProfileParameterData.CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION ) &lt;br /&gt;
&lt;br /&gt;
::''NOTE: enum from ProfileParameterData''&lt;br /&gt;
prism_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
&lt;br /&gt;
 -- calculate the minimum cut depth to fully form the bevel on the current&lt;br /&gt;
 -- selection with the current tool&lt;br /&gt;
local min_bevel_depth = prism_data:CalculateMinimumBevelDepth(tool, true)&lt;br /&gt;
if min_bevel_depth &amp;gt; cut_depth then&lt;br /&gt;
DisplayMessageBox(&lt;br /&gt;
&amp;quot;A prism will not be fully formed with a depth of &amp;quot;   cut_depth   &amp;quot;\r\n&amp;quot;&lt;br /&gt;
&amp;quot;A depth of &amp;quot;   min_bevel_depth   &amp;quot; is required to fully form the prism&amp;quot;&lt;br /&gt;
) end&lt;br /&gt;
&lt;br /&gt;
 -- Create object which can be used to automatically select geometry&lt;br /&gt;
local geometry_selector = GeometrySelector()&lt;br /&gt;
&lt;br /&gt;
 -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
local create_2d_previews = true&lt;br /&gt;
&lt;br /&gt;
 -- if this is true we will display errors and warning to the user&lt;br /&gt;
local display_warnings = true&lt;br /&gt;
&lt;br /&gt;
 -- Create our toolpath&lt;br /&gt;
&lt;br /&gt;
local toolpath_manager = ToolpathManager()&lt;br /&gt;
&lt;br /&gt;
local toolpath_id = toolpath_manager:CreatePrismCarvingToolpath(                                               name,                                               tool,                                               prism_data,                                               pos_data,                                               geometry_selector,                                               create_2d_previews,                                               display_warnings&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
if toolpath_id  == nil  then&lt;br /&gt;
DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;) &lt;br /&gt;
return false&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
 -- [[ main&lt;br /&gt;
|&lt;br /&gt;
|  Entry point for script&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
function main()&lt;br /&gt;
&lt;br /&gt;
 -- Check we have a job loaded&lt;br /&gt;
job = VectricJob()&lt;br /&gt;
&lt;br /&gt;
if not job.Exists then&lt;br /&gt;
DisplayMessageBox(&amp;quot;No job loaded&amp;quot;)&lt;br /&gt;
return false;&lt;br /&gt;
end&lt;br /&gt;
local selection = job.Selection&lt;br /&gt;
if selection.IsEmpty  then&lt;br /&gt;
MessageBox(&amp;quot;Please select one or more vectors to bevel carve&amp;quot;)&lt;br /&gt;
return false&lt;br /&gt;
end&lt;br /&gt;
local start_depth = 0.0&lt;br /&gt;
local cut_depth = 20.0&lt;br /&gt;
local vbit_angle = 90.0&lt;br /&gt;
local tool_dia = 32.0&lt;br /&gt;
local tool_stepdown = 2.5&lt;br /&gt;
local tool_stepover_percent = 2.0&lt;br /&gt;
local tool_in_mm = true&lt;br /&gt;
&lt;br /&gt;
local success = CreatePrismToolpath(&lt;br /&gt;
&amp;quot;Lua Prism Toolpath&amp;quot;,                                             start_depth,                                             cut_depth,                                             vbit_angle,                                            tool_dia,                                             tool_stepdown,                                             tool_stepover_percent,                                            tool_in_mm&lt;br /&gt;
)&lt;br /&gt;
return success;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===:CreateFlutingToolpath()===&lt;br /&gt;
[[File:Top.jpg|right|30px|link=ToolpathManager]]&lt;br /&gt;
'''Usage:''':CreateFlutingToolpath(&lt;br /&gt;
:::::String name,&lt;br /&gt;
:::::Tool tool,&lt;br /&gt;
:::::FlutingParameterDatafluting_data,&lt;br /&gt;
:::::ToolpathPosData pos_data,&lt;br /&gt;
:::::GeometrySelector geometry_selector,&lt;br /&gt;
:::::bool create_2d_preview,     &lt;br /&gt;
:::::bool  interactive&lt;br /&gt;
:::::)&lt;br /&gt;
Creates a  fluting toolpath for the currently selected vectors. &lt;br /&gt;
&lt;br /&gt;
'''Returns:''' the UUID for the toolpath created.&lt;br /&gt;
::''name(string) Name for the toolpath to be created ''&lt;br /&gt;
::''tool (Tool) Tool to use for the toolpath''&lt;br /&gt;
::''fluting_data (FlutingParameterData) Settings for fluting ''&lt;br /&gt;
::''pos_data(ToolpathPosData)Settings for home position, safe z etc''&lt;br /&gt;
::''geometry_selector(GeometrySelector) Can be used to automatically select vectors on layers etc ''&lt;br /&gt;
::''create_2d_preview(bool) If true create preview vectors in 2d view ''&lt;br /&gt;
::''interactive(bool) If true display warnings etc to user''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=====Example Code: CreateFlutingToolpath()=====&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;nowiki&amp;gt;-- VECTRIC LUA SCRIPT&lt;br /&gt;
-- Copyright 2013 Vectric Ltd.&lt;br /&gt;
&lt;br /&gt;
-- Gadgets are an entirely optional add-in to Vectric's core software products. &lt;br /&gt;
-- They are provided 'as-is', without any express or implied warranty, and you make use of them entirely at your own risk.&lt;br /&gt;
-- In no event will the author(s) or Vectric Ltd. be held liable for any damages arising from their use.&lt;br /&gt;
&lt;br /&gt;
-- Permission is granted to anyone to use this software for any purpose, &lt;br /&gt;
-- including commercial applications, and to alter it and redistribute it freely, &lt;br /&gt;
-- subject to the following restrictions:&lt;br /&gt;
&lt;br /&gt;
-- 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.&lt;br /&gt;
-- 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.&lt;br /&gt;
-- 3. This notice may not be removed or altered from any source distribution.&lt;br /&gt;
&lt;br /&gt;
require &amp;quot;strict&amp;quot;&lt;br /&gt;
&lt;br /&gt;
--[[  ----------------- CreateFlutingToolpath -----------------  &lt;br /&gt;
|&lt;br /&gt;
|   Create a drilling toolpath within the program for the currently selected vectors&lt;br /&gt;
|  Parameters:&lt;br /&gt;
|    name,               -- Name for toolpath&lt;br /&gt;
|    start_depth         -- Start depth for toolpath below surface of material&lt;br /&gt;
|    cut_depth           -- cut depth for toolpath&lt;br /&gt;
|    tool_dia            -- diameter of tool to use&lt;br /&gt;
|    tool_stepdown       -- stepdown for tool&lt;br /&gt;
|    tool_in_mm          -- true if tool size and stepdown are in mm&lt;br /&gt;
|&lt;br /&gt;
|  Return Values:&lt;br /&gt;
|     true if toolpath created OK else false&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function CreateFlutingToolpath( name , start_depth, cut_depth, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
&lt;br /&gt;
  -- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&lt;br /&gt;
    &amp;quot;Lua Ball Nose&amp;quot;, &lt;br /&gt;
    Tool.BALL_NOSE       -- BALL_NOSE, END_MILL, VBIT, THROUGH_DRILL&lt;br /&gt;
  )&lt;br /&gt;
&lt;br /&gt;
  tool.InMM = tool_in_mm&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * 0.25&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC  -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
  tool.FeedRate = 30&lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBitAngle = 90.0                -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * 0.5  -- used for vbit only&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
&lt;br /&gt;
  pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
  pos_data.SafeZGap = 5.0&lt;br /&gt;
&lt;br /&gt;
  -- Create  object used to pass fluting options&lt;br /&gt;
  local fluting_data = FlutingParameterData()&lt;br /&gt;
  -- start depth for toolpath&lt;br /&gt;
  fluting_data.StartDepth = start_depth&lt;br /&gt;
&lt;br /&gt;
  -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  fluting_data.CutDepth = cut_depth&lt;br /&gt;
&lt;br /&gt;
  -- type of fluting FULL_LENGTH, RAMP_START or RAMP_START_END&lt;br /&gt;
  fluting_data.FluteType = FlutingParameterData.RAMP_START_END&lt;br /&gt;
&lt;br /&gt;
  -- type of ramping RAMP_LINEAR, RAMP_SMOOTH&lt;br /&gt;
  fluting_data.RampType = FlutingParameterData.RAMP_LINEAR&lt;br /&gt;
&lt;br /&gt;
  -- if true use ratio field for controling ramp length else absolute length value&lt;br /&gt;
  fluting_data.UseRampRatio = false&lt;br /&gt;
&lt;br /&gt;
  -- length of ramp as ratio of flute length(range 0 - 1.0) (for start and end - ratio is of half length)&lt;br /&gt;
  fluting_data.RampRatio = 0.2&lt;br /&gt;
&lt;br /&gt;
  -- length to ramp over - if UseRampRatio == false&lt;br /&gt;
  fluting_data.RampLength = 15&lt;br /&gt;
&lt;br /&gt;
  -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  fluting_data.ProjectToolpath = false&lt;br /&gt;
&lt;br /&gt;
  -- Create object which can used to automatically select geometry on layers etc&lt;br /&gt;
  local geometry_selector = GeometrySelector() &lt;br /&gt;
&lt;br /&gt;
  -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
&lt;br /&gt;
  -- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
&lt;br /&gt;
  -- Create our toolpath&lt;br /&gt;
&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreateFlutingToolpath(&lt;br /&gt;
    name,&lt;br /&gt;
    tool,&lt;br /&gt;
    fluting_data,&lt;br /&gt;
    pos_data,&lt;br /&gt;
    geometry_selector,&lt;br /&gt;
    create_2d_previews,&lt;br /&gt;
    display_warnings&lt;br /&gt;
  )&lt;br /&gt;
&lt;br /&gt;
  if toolpath_id  == nil  then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
    return false&lt;br /&gt;
  end                                                    &lt;br /&gt;
&lt;br /&gt;
  return true  &lt;br /&gt;
&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
--[[  ----------------- main ----------------- &lt;br /&gt;
|&lt;br /&gt;
|  Entry point for script&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
&lt;br /&gt;
function main()&lt;br /&gt;
&lt;br /&gt;
  -- Check we have a job loaded&lt;br /&gt;
  local job = VectricJob()&lt;br /&gt;
&lt;br /&gt;
  if not job.Exists then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;No job loaded&amp;quot;)&lt;br /&gt;
    return false;  &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  local selection = job.Selection&lt;br /&gt;
  if selection.IsEmpty  then&lt;br /&gt;
    MessageBox(&amp;quot;Please select one or more vectors to flute&amp;quot;)&lt;br /&gt;
    return false  &lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  local start_depth = 0.0&lt;br /&gt;
  local cut_depth = 1.0&lt;br /&gt;
  local tool_dia = 1.0&lt;br /&gt;
  local tool_stepdown = 0.5&lt;br /&gt;
  local tool_in_mm = false&lt;br /&gt;
&lt;br /&gt;
  local success = CreateFlutingToolpath( &lt;br /&gt;
    &amp;quot;Lua Fluting Toolpath&amp;quot;, &lt;br /&gt;
    start_depth, &lt;br /&gt;
    cut_depth, &lt;br /&gt;
    tool_dia, &lt;br /&gt;
    tool_stepdown, &lt;br /&gt;
    tool_in_mm &lt;br /&gt;
  )&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return success;&lt;br /&gt;
end   &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===:CreateRoughingToolpath()===&lt;br /&gt;
[[File:Top.jpg|right|30px|link=ToolpathManager]]&lt;br /&gt;
'''Usage:''' :CreateRoughingToolpath(&lt;br /&gt;
:::::String name,''&lt;br /&gt;
:::::Tool tool,''&lt;br /&gt;
:::::RoughingParameterData roughing_ data, ''&lt;br /&gt;
:::::ToolpathPosData pos_data,  ''&lt;br /&gt;
:::::GeometrySelector geometry_selector,  ''&lt;br /&gt;
:::::bool  interactive) Aspire Only''&lt;br /&gt;
Creates a roughing toolpath.  &lt;br /&gt;
&lt;br /&gt;
'''Returns:''' the UUID for the toolpath created. NOTE: This method is only available in Aspire&lt;br /&gt;
::''name(string) Name for the toolpath to be created''&lt;br /&gt;
::''tool (Tool) Tool to use for the toolpath''&lt;br /&gt;
::''roughing_data(RoughingParameterData) Settings for roughing, strategy etc ''&lt;br /&gt;
::''pos_data(ToolpathPosData) Settings for home position, safe z etc''&lt;br /&gt;
::''geometry_selector(GeometrySelector)Can be used to automatically select vectors on layers etc ''&lt;br /&gt;
::''interactive(bool) If true display warnings etc to user''&lt;br /&gt;
&lt;br /&gt;
====Example Code: CreateRoughingToolpath====&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;From 05_Roughing_Toolpath.lua&lt;br /&gt;
&lt;br /&gt;
function CreateRoughingToolpath()&lt;br /&gt;
&lt;br /&gt;
 -- Toolpath name&lt;br /&gt;
local name = &amp;quot;Lua Roughing Toolpath&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 -- Metric unit parameters&lt;br /&gt;
local tool_dia = 6.35 -- Quarter of an inch&lt;br /&gt;
local tool_stepdown = 5&lt;br /&gt;
local tool_stepover_percent = 40&lt;br /&gt;
&lt;br /&gt;
 -- Create tool we will use to machine vectors&lt;br /&gt;
local tool = Tool(&amp;quot;Lua End Mill&amp;quot;, Tool.END_MILL)&lt;br /&gt;
&lt;br /&gt;
tool.InMM = true&lt;br /&gt;
tool.ToolDia = tool_dia&lt;br /&gt;
tool.Stepdown = tool_stepdown&lt;br /&gt;
tool.Stepover = tool_dia * (tool_stepover_percent or 100)&lt;br /&gt;
tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
tool.FeedRate = 30&lt;br /&gt;
tool.PlungeRate = 10&lt;br /&gt;
tool.SpindleSpeed = 20000&lt;br /&gt;
tool.ToolNumber = 1&lt;br /&gt;
tool.VBitAngle = 90.0               -- used for vbit only&lt;br /&gt;
tool.ClearStepover = tool_dia * (tool_stepover_percent or 100) -- used for vbit only&lt;br /&gt;
 -- we will set home position and safe z relative to material block size&lt;br /&gt;
local mtl_block = MaterialBlock()&lt;br /&gt;
local mtl_box = mtl_block.MaterialBox   local mtl_box_blc = mtl_box.BLC&lt;br /&gt;
&lt;br /&gt;
 -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
local pos_data = ToolpathPosData()&lt;br /&gt;
pos_data:SetHomePosition(mtl_box_blc.x, mtl_box_blc.y, mtl_box.TRC.z + (mtl_block.Thickness&lt;br /&gt;
* 0.2))&lt;br /&gt;
pos_data.SafeZGap = mtl_block.Thickness * 0.1&lt;br /&gt;
&lt;br /&gt;
 -- Pocketing parameters   local start_depth = 0&lt;br /&gt;
local cut_depth = mtl_box.ZLength&lt;br /&gt;
&lt;br /&gt;
 -- Create object used to pass roughing options&lt;br /&gt;
local roughing_data = RoughingParameterData() -- start depth for toolpath&lt;br /&gt;
roughing_data.StartDepth = start_depth&lt;br /&gt;
&lt;br /&gt;
 -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
roughing_data.CutDepth = cut_depth&lt;br /&gt;
&lt;br /&gt;
 -- Machining allowance&lt;br /&gt;
roughing_data.MachiningAllowance = 0.0&lt;br /&gt;
&lt;br /&gt;
 -- Allowance to leave on when machining (this is different from machining allowance)&lt;br /&gt;
roughing_data.Allowance = 0.0&lt;br /&gt;
&lt;br /&gt;
 -- if true use z level roughing&lt;br /&gt;
roughing_data.DoZLevelRoughing = true  -- z level clearance strategy&lt;br /&gt;
roughing_data.ZLevelStrategy = RoughingParameterData.RASTER_X&lt;br /&gt;
roughing_data.ZLevelProfile = RoughingParameterData.LAST&lt;br /&gt;
 -- angle for raster if using raster clearance&lt;br /&gt;
roughing_data.RasterAngle = 0&lt;br /&gt;
&lt;br /&gt;
 -- if true we ramp into pockets (always zig zag)&lt;br /&gt;
roughing_data.DoRamping = false  -- if ramping, distance to ramp over&lt;br /&gt;
roughing_data.RampDistance = 10.0&lt;br /&gt;
&lt;br /&gt;
 -- Create object which can used to automatically select geometry on layers etc&lt;br /&gt;
local geometry_selector = GeometrySelector()&lt;br /&gt;
&lt;br /&gt;
 -- if this is true we will display errors and warning to the user&lt;br /&gt;
local display_warnings = true&lt;br /&gt;
&lt;br /&gt;
 -- Create our toolpath&lt;br /&gt;
local toolpath_manager = ToolpathManager()&lt;br /&gt;
local toolpath_id = toolpath_manager:CreateRoughingToolpath(&lt;br /&gt;
                                               name,&lt;br /&gt;
                                               tool,&lt;br /&gt;
                                               roughing_data,&lt;br /&gt;
                                               pos_data,&lt;br /&gt;
                                               geometry_selector,&lt;br /&gt;
                                               display_warnings&lt;br /&gt;
                                              )&lt;br /&gt;
&lt;br /&gt;
if not toolpath_id then&lt;br /&gt;
DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;) end&lt;br /&gt;
end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===:CreateFinishingToolpath() Aspire Only===&lt;br /&gt;
[[File:Top.jpg|right|30px|link=ToolpathManager]]&lt;br /&gt;
String name,&lt;br /&gt;
Tool tool,&lt;br /&gt;
PocketParameterData pocket_data,&lt;br /&gt;
ToolpathPosData pos_data,  GeometrySelector geometry_selector,  bool create_2d_preview,  bool  interactive&lt;br /&gt;
)&lt;br /&gt;
Creates a finishing toolpath for the currently selected vectors. &lt;br /&gt;
&lt;br /&gt;
'''Returns:''' the UUID for the toolpath created.&lt;br /&gt;
NOTE: This method is only available in Aspire&lt;br /&gt;
&lt;br /&gt;
name(string) Name for the toolpath to be created&lt;br /&gt;
tool (Tool) Tool to use for the toolpath pocket_data (PoketParameterData) Setting for pocketing depth, style etc pos_data(ToolpathPosData) Settings for home position, safe z etc&lt;br /&gt;
geometry_selector(GeometrySelector) Can be used to automatically select vectors on layers etc create_2d_preview(bool) If true create preview vectors in 2d view interactive(bool) If true display warnings etc to user&lt;br /&gt;
&lt;br /&gt;
====Example Code: CreateFinishingToolpath====&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;From 04_Finishing_Toolpath.lua&lt;br /&gt;
function CreateFinishingToolpath()&lt;br /&gt;
&lt;br /&gt;
  -- Toolpath name&lt;br /&gt;
  local name = &amp;quot;Lua Finishing Toolpath&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  -- Metric unit parameters&lt;br /&gt;
  local tool_dia = 3.175 -- 8th of an inch&lt;br /&gt;
  local tool_stepdown = 5&lt;br /&gt;
  local tool_stepover_percent = 10&lt;br /&gt;
&lt;br /&gt;
  -- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&amp;quot;Lua Ball Nose&amp;quot;, Tool.BALL_NOSE)&lt;br /&gt;
&lt;br /&gt;
  tool.InMM = true&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * (tool_stepover_percent or 100)&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
  tool.FeedRate = 30   &lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBitAngle = 90.0               -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * (tool_stepover_percent or 100) -- used for vbit only&lt;br /&gt;
  -- we will set home position and safe z relative to material block size&lt;br /&gt;
  local mtl_block = MaterialBlock()&lt;br /&gt;
  local mtl_box = mtl_block.MaterialBox&lt;br /&gt;
  local mtl_box_blc = mtl_box.BLC&lt;br /&gt;
&lt;br /&gt;
  -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
  pos_data:SetHomePosition(mtl_box_blc.x, mtl_box_blc.y, mtl_box.TRC.z +&lt;br /&gt;
    (mtl_block.Thickness * 0.2))&lt;br /&gt;
  pos_data.SafeZGap = mtl_block.Thickness * 0.1&lt;br /&gt;
&lt;br /&gt;
  -- Pocketing parameters   local start_depth = 0&lt;br /&gt;
  local cut_depth = mtl_box.ZLength&lt;br /&gt;
&lt;br /&gt;
  -- Create object used to pass pocketing options&lt;br /&gt;
  local pocket_data = PocketParameterData()&lt;br /&gt;
  -- start depth for toolpath&lt;br /&gt;
  pocket_data.StartDepth = start_depth&lt;br /&gt;
&lt;br /&gt;
  -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  pocket_data.CutDepth = cut_depth&lt;br /&gt;
&lt;br /&gt;
  -- direction of cut for offet clearance(ProfileParameterData.CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION) &lt;br /&gt;
  NOTE: enum from ProfileParameterData&lt;br /&gt;
  pocket_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
&lt;br /&gt;
  -- Allowance to leave on when machining&lt;br /&gt;
  pocket_data.Allowance = 0.0&lt;br /&gt;
&lt;br /&gt;
  -- if true use raster clearance strategy , else use offset area clearance&lt;br /&gt;
  pocket_data.DoRasterClearance = true  -- angle for raster if using raster clearance&lt;br /&gt;
  pocket_data.RasterAngle = 0&lt;br /&gt;
  -- type of profile pass to perform  PocketParameterData.PROFILE_NONE , PocketParameterData.PROFILE_FIRST orPocketParameterData.PROFILE_LAST&lt;br /&gt;
  pocket_data.ProfilePassType = PocketParameterData.PROFILE_LAST&lt;br /&gt;
&lt;br /&gt;
  -- if true we ramp into pockets (always zig zag)&lt;br /&gt;
  pocket_data.DoRamping = false  -- if ramping, distance to ramp over&lt;br /&gt;
  pocket_data.RampDistance = 10.0&lt;br /&gt;
&lt;br /&gt;
  -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  pocket_data.ProjectToolpath = false&lt;br /&gt;
&lt;br /&gt;
  -- Create object which can used to automatically select geometry on layers etc&lt;br /&gt;
  local geometry_selector = GeometrySelector()&lt;br /&gt;
&lt;br /&gt;
  -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
&lt;br /&gt;
  -- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
&lt;br /&gt;
  -- Create our toolpath&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreateFinishingToolpath(name, tool, pocket_data, pos_data, geometry_selector, create_2d_previews display_warnings )&lt;br /&gt;
&lt;br /&gt;
  if not toolpath_id then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===:LoadToolpathTemplate(string template_path)===&lt;br /&gt;
[[File:Top.jpg|right|30px|link=ToolpathManager]]&lt;br /&gt;
Load a toolpath template from passed file. &lt;br /&gt;
&lt;br /&gt;
'''Returns:''' (bool) true if template loaded OK, else false&lt;br /&gt;
template_path (string) Full path to template file to load&lt;br /&gt;
&lt;br /&gt;
====Example Code:====&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;-- VECTRIC LUA SCRIPT&lt;br /&gt;
&lt;br /&gt;
require &amp;quot;strict&amp;quot;&lt;br /&gt;
&lt;br /&gt;
-- [[ -------------- main ---------------------&lt;br /&gt;
|&lt;br /&gt;
|  Entry point for script&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
function main()&lt;br /&gt;
&lt;br /&gt;
  -- Check we have a job loaded&lt;br /&gt;
  &lt;br /&gt;
  local job = VectricJob()&lt;br /&gt;
&lt;br /&gt;
  if not job.Exists then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;No job loaded&amp;quot;)&lt;br /&gt;
    return false&lt;br /&gt;
  end&lt;br /&gt;
  &lt;br /&gt;
  local template_path = &amp;quot;c:\\temp\\TestToolpathTemplate.ToolpathTemplate&amp;quot;&lt;br /&gt;
&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  if not toolpath_manager:LoadToolpathTemplate(template_path) then&lt;br /&gt;
    MessageBox(&amp;quot;Failed to load template &amp;quot;   template_path)&lt;br /&gt;
    return false&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  MessageBox(&amp;quot;Loaded template &amp;quot;   template_path)&lt;br /&gt;
&lt;br /&gt;
  local calc_result = toolpath_manager:RecalculateAllToolpaths()&lt;br /&gt;
  &lt;br /&gt;
  if calc_result == nil then&lt;br /&gt;
    MessageBox(&amp;quot;Recalculate all toolpaths failed&amp;quot;)&lt;br /&gt;
  else&lt;br /&gt;
    MessageBox(&amp;quot;Results from recalculate all\n&amp;quot;   calc_result)&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  return true&lt;br /&gt;
end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===:CopyToolpathWithId( UUID id, bool insert_at_end, bool rename)===&lt;br /&gt;
[[File:Top.jpg|right|30px|link=ToolpathManager]]&lt;br /&gt;
Copy (duplicate) toolpath with passed id , returns copied toolpath and adds to toolpath list&lt;br /&gt;
id (UUID) Id of toolpath to copy&lt;br /&gt;
insert_at_end (bool) If true, new toolpath is inserted at end of list, else following original to copy rename (bool) If true, new toolpath is automatically renamed, else keeps same name&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:DeleteAllToolpaths()=== &lt;br /&gt;
Deletes ALL toolpaths in job.&lt;br /&gt;
(Revised: Feb 10, 2020)&lt;br /&gt;
====Example Code:====&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  local toolpath_mgr = ToolpathManager()&lt;br /&gt;
        toolpath_mgr:DeleteAllToolpaths()&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===:DeleteToolpath( Toolpath toolpath)===&lt;br /&gt;
Delete passed toolpath Note: make sure you do not refer to toolpath in script after this call!&lt;br /&gt;
toolpath (Toolpath) Toolpath to delete&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:DeleteToolpathWithId( UUID id)===&lt;br /&gt;
Delete toolpath with passed id  id(UUID)id of toolpath to delete&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:Find( UUID id)===&lt;br /&gt;
'''Returns:''' the POSITION in the list of the toolpath with hte passed id Note: nil if no toolpath with id found id(UUID)id of toolpath to find position for&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:GetAt( pos)===&lt;br /&gt;
'''Returns:''' the toolpath at the passed position &lt;br /&gt;
&lt;br /&gt;
::''pos (POSTION) current position in list''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:GetGroupToolpathWithIndex( UUID id, integer index)===&lt;br /&gt;
[[File:Top.jpg|right|30px|link=ToolpathManager]]&lt;br /&gt;
'''Returns:''' (the &amp;lt;q&amp;gt;n&amp;lt;/q&amp;gt;th toolpath of the passed group id. Toolpaths created together such as the two toolpaths from a flat bottom vcarve with two tools share a unique groupid property.&lt;br /&gt;
&lt;br /&gt;
::''id (UUID) Id of toolpath group''&lt;br /&gt;
&lt;br /&gt;
::''index (integer)Index (inrange 0 to n to 1) of toolpath in group to return''&lt;br /&gt;
&lt;br /&gt;
===:GetNext( pos)===&lt;br /&gt;
'''Returns:''' Both the toolpath at the current position '''AND'''a new value for position pointing to the next item in the list (or nil if at end of list)&lt;br /&gt;
&lt;br /&gt;
::''pos (POSTION) current position in list''&lt;br /&gt;
&lt;br /&gt;
::'''Example Code:'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;Note: GetNext(pos) is returning two values&lt;br /&gt;
    local pos = uuid_list:GetHeadPosition()&lt;br /&gt;
	local id&lt;br /&gt;
	while pos ~= nil do&lt;br /&gt;
	  id, pos = uuid_list:GetNext(pos)&lt;br /&gt;
      DO SOMETHING WITH ID&lt;br /&gt;
	end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===:GetNumberOfToolpathsInGroup( UUID id)===&lt;br /&gt;
'''Returns:''' (the number of toolpaths which have the passed group id. Toolpaths created together such as the two toolpaths from a flat bottom vcarve with two tools share a unique groupid property.&lt;br /&gt;
id (UUID) Id of toolpath group to count members for&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:GetPrev( pos)===&lt;br /&gt;
[[File:Top.jpg|right|30px|link=ToolpathManager]]&lt;br /&gt;
'''Returns:''' Both the toolpath at the current position '''AND'''a new value for position, pointing to the previous item in the list (or nil if at start of list)&lt;br /&gt;
&lt;br /&gt;
::''pos (POSTION) current position in list''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:GetSelectedToolpath()===&lt;br /&gt;
'''Returns:''' the currently selected toolpath or nil if no toolpath currently selected&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:GetHeadPosition()===&lt;br /&gt;
'''Returns:''' (POSITION) a variable to allow access to the head of the list of toolpaths&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:GetTailPosition()===&lt;br /&gt;
'''Returns:''' (POSITION) a variable to allow access to the tail of the list of toolpaths&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:RecalculateAllToolpaths()===&lt;br /&gt;
[[File:Top.jpg|right|30px|link=ToolpathManager]]&lt;br /&gt;
Recalculate all toolpaths in the job. &lt;br /&gt;
&lt;br /&gt;
'''Returns:''' a string containing a list of all the toolpaths recalculated if it succeeds, else nil.&lt;br /&gt;
&lt;br /&gt;
WARNING: Recalculating all toolpaths will destroy the original toolpaths and create new ones with the same ID. &lt;br /&gt;
&lt;br /&gt;
Do not try and reuse a toolpath variable after this call. See&lt;br /&gt;
&lt;br /&gt;
====Example Code:====&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  local toolpath_mgr = ToolpathManager()&lt;br /&gt;
  DisplayMessageBox(toolpath_mgr:RecalculateAllToolpaths())&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===:RecalculateToolpath(Toolpath toolpath )===&lt;br /&gt;
For information on how to retrieve a specific toolpath after it has been recalculated.&lt;br /&gt;
&lt;br /&gt;
'''For Example:'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;local orig_id = luaUUID()&lt;br /&gt;
orig_id:SetId(toolpath.Id)&lt;br /&gt;
local recalced_toolpath = nil&lt;br /&gt;
if toolpath_manager:RecalculateToolpath(toolpath) then&lt;br /&gt;
  local recalced_pos = toolpath_manager:Find(orig_id.RawId)&lt;br /&gt;
  if recalced_pos == nil then&lt;br /&gt;
    MessageBox(&amp;quot;Failed to find toolpath after calculation&amp;quot;)&lt;br /&gt;
    return false&lt;br /&gt;
  else&lt;br /&gt;
    recalced_toolpath = toolpath_manager:GetAt(recalced_pos)&lt;br /&gt;
  end -- if end&lt;br /&gt;
end -- if end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===:RecalculateToolpath( Toolpath toolpath)===&lt;br /&gt;
[[File:Top.jpg|right|30px|link=ToolpathManager]]&lt;br /&gt;
Recalculates passed toolpath. &lt;br /&gt;
&lt;br /&gt;
'''Returns:''' (bool) true if toolpath recalculated ok&lt;br /&gt;
toolpath (Toolpath) Toolpath to recalculate&lt;br /&gt;
&lt;br /&gt;
WARNING:  The passed toolpath is invalid after this call as a new toolpath with the same id is created internally. If you wish to continue accesing the toolpath after recalculating, save its id BEFORE calling:RecalculateToolpath() and then use:Find(id) to find the position of the recalculated toolpath and use:GetAt(position) to return the recalculated toolpath.&lt;br /&gt;
&lt;br /&gt;
===:SaveToolpathAsTemplate( Toolpath toolpath, string template_path)===&lt;br /&gt;
Save a toolpath as a template to passed file. &lt;br /&gt;
&lt;br /&gt;
'''Returns:''' (bool) true if template saved, else false. If passed toolpath is part of a group (Note: flat bottom vcarving) all toolpaths in group are saved to the template&lt;br /&gt;
toolpath (Toolpath) Toolpath to save as a template template_path (string) Full path to template file to save&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:SaveVisibleToolpathsAsTemplate( string template_path)===&lt;br /&gt;
Save all visible toolpaths as a template to passed file. &lt;br /&gt;
&lt;br /&gt;
'''Returns:''' (bool) true if template saved, else false.&lt;br /&gt;
template_path (string) Full path to template file to save&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:ToolpathModified( Toolpath toolpath)===&lt;br /&gt;
[[File:Top.jpg|right|30px|link=ToolpathManager]]&lt;br /&gt;
This method must be called if parameters for a toolpath are modified from script.&lt;br /&gt;
=====For Example:=====&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;tool parameters are changed. If this method is not called the ui will not show the changes you have made.&lt;br /&gt;
toolpath (Toolpath) Toolpath which has been modified &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===:ToolpathWithNameExists( string name)===&lt;br /&gt;
'''Returns:''' (bool) true if there is one or more existing toolpaths with passed name &lt;br /&gt;
&lt;br /&gt;
::''name (string) Toolpath name to check for id (UUID) Id of toolpath to delete''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:UndrawAllToolpath()===&lt;br /&gt;
Undraw (set visibility to false) ALL toolpaths in job.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:SetAllToolpathsVisibility( bool visibility)===&lt;br /&gt;
Set visibility for all toolpaths in job.&lt;br /&gt;
&lt;br /&gt;
::''visibility (bool) true to draw all toolpaths, false to stop drawing them''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 10.0, published August 21, 2019. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=JimAndi_Toolbox&amp;diff=1097</id>
		<title>JimAndi Toolbox</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=JimAndi_Toolbox&amp;diff=1097"/>
		<updated>2024-11-16T17:21:44Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: /* CreatePrismToolpath */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:SDK]]&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
==Table and Array Tools==&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
&lt;br /&gt;
===ArrayClear===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
ArrayClear - Clears the data from a data array.&lt;br /&gt;
&lt;br /&gt;
local tbl = {1, 2, 5, 6}&lt;br /&gt;
&lt;br /&gt;
tbl = ArrayClear(tbl)&lt;br /&gt;
&lt;br /&gt;
returns tbl = {}&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function ArrayClear(arrayName)&lt;br /&gt;
   for _,v in ipairs(arrayName) do&lt;br /&gt;
     table.remove(arrayName, i)&lt;br /&gt;
   end -- for end&lt;br /&gt;
   return true&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===NameCheck===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Checks if Name is in the list of it is default name.&lt;br /&gt;
&lt;br /&gt;
a = {1, 2, 5, 6}&lt;br /&gt;
&lt;br /&gt;
Words = NameCheck(a, 5) -- returns true&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function NameCheck(Name, Defalt, ListName)&lt;br /&gt;
     if Name ~= Defalt then&lt;br /&gt;
       for i=1, ListName do&lt;br /&gt;
         if Name == i then&lt;br /&gt;
           return true&lt;br /&gt;
         end&lt;br /&gt;
       end&lt;br /&gt;
       return false&lt;br /&gt;
     else&lt;br /&gt;
       return  true&lt;br /&gt;
     end&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===RemoveDuplicates===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns table of unique items in &amp;quot;A&amp;quot; acending or &amp;quot;D&amp;quot; decending&lt;br /&gt;
&lt;br /&gt;
local tbl = {1, 2, 5, 3, 5, 6, 4}&lt;br /&gt;
&lt;br /&gt;
tbl = ArrayClear(tbl, &amp;quot;A&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 returns tbl = {1, 2, 3, 4, 5, 6}&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function RemoveDuplicates(tab, order)&lt;br /&gt;
     local hashSet = {}&lt;br /&gt;
     local new = {}&lt;br /&gt;
     local value&lt;br /&gt;
     for i = 1, #tab do&lt;br /&gt;
       value = (tab[i])&lt;br /&gt;
       if hashSet[value] == nil then&lt;br /&gt;
         table.insert(new, value)&lt;br /&gt;
         hashSet[value] = true&lt;br /&gt;
       end&lt;br /&gt;
     end&lt;br /&gt;
     if string.upper(order) ==&amp;quot;A&amp;quot; then&lt;br /&gt;
       table.sort(new)&lt;br /&gt;
     else&lt;br /&gt;
       table.sort(new, function(a, b) return a &amp;gt; b end)&lt;br /&gt;
     end&lt;br /&gt;
     return new&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===RemoveTableItem=== &lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns table with item removed.&lt;br /&gt;
&lt;br /&gt;
local tbl = {1, 2, 3, 4, 5, 6}&lt;br /&gt;
&lt;br /&gt;
tbl = RemoveTableItem(tbl, 4)&lt;br /&gt;
&lt;br /&gt;
 returns tbl = {1, 2, 3, 5, 6}&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;  function RemoveTableItem(tabName, tabItem)&lt;br /&gt;
     for x = 1 in ipairs(tabName) do&lt;br /&gt;
       if tabName[x] == tabItem then&lt;br /&gt;
          table.remove(tabName, i)&lt;br /&gt;
       end&lt;br /&gt;
     end -- for end&lt;br /&gt;
     return true&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===TableLength===&lt;br /&gt;
&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; Returns table item count&lt;br /&gt;
 local tbl = {1, 2, 3, 4, 5, 6}&lt;br /&gt;
 tbl = TableLength(tbl)&lt;br /&gt;
&lt;br /&gt;
 returns tbl = 6&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
  function TableLength(tbl)&lt;br /&gt;
     -- tbl = {7, 6, 5, 4, 3, 2, 1}&lt;br /&gt;
     local count = 0&lt;br /&gt;
     for _ in pairs(tbl) do&lt;br /&gt;
       count = count + 1&lt;br /&gt;
     end&lt;br /&gt;
     return count&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===FindDups===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Find all duplicate items and returns two tables the dup and clean tables&lt;br /&gt;
&lt;br /&gt;
Returns table item count&lt;br /&gt;
&lt;br /&gt;
local tbl = {1, 2, 2, 4, 4, 6}&lt;br /&gt;
&lt;br /&gt;
local tbl1 = {}&lt;br /&gt;
&lt;br /&gt;
local tbl2 = {}&lt;br /&gt;
&lt;br /&gt;
tbl1, tbl2 = TableLength(tbl)&lt;br /&gt;
&lt;br /&gt;
returns tbl1, tbl2 = 6&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function FindDups(checktbl, duptbl, cleantbl)&lt;br /&gt;
     function tLength(tbl) -- tLength returns table count&lt;br /&gt;
       local count = 0&lt;br /&gt;
       for _ in pairs(tbl) do&lt;br /&gt;
         count = count + 1&lt;br /&gt;
       end&lt;br /&gt;
       return count&lt;br /&gt;
     end&lt;br /&gt;
     -- =================================&lt;br /&gt;
     local trip = false&lt;br /&gt;
     for i=1, tLength(checktbl) do&lt;br /&gt;
       for x=1, tLength(cleantbl) do&lt;br /&gt;
         if cleantbl[x] == checktbl[i] then&lt;br /&gt;
           trip = true&lt;br /&gt;
         end&lt;br /&gt;
       end&lt;br /&gt;
       if trip then&lt;br /&gt;
         table.insert(duptbl,   checktbl[i])&lt;br /&gt;
       else&lt;br /&gt;
         table.insert(cleantbl, checktbl[i])&lt;br /&gt;
       end&lt;br /&gt;
       trip = false&lt;br /&gt;
     end&lt;br /&gt;
     return table.sort(duptbl), table.sort(cleantbl)&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===ReverseTable===&lt;br /&gt;
&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
&lt;br /&gt;
Returns a reversed table&lt;br /&gt;
&lt;br /&gt;
local tbl = {1, 2, 3, 4, 5, 6}&lt;br /&gt;
&lt;br /&gt;
tbl = ReverseTable(tbl)&lt;br /&gt;
&lt;br /&gt;
returns tbl = {6, 5, 4, 3, 2, 1}&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function ReverseTable(tbl)&lt;br /&gt;
    --tbl = {7, 6, 7, A, 5, 4, 3, A, 2, 1}&lt;br /&gt;
     local n = #tbl&lt;br /&gt;
     local i = 1&lt;br /&gt;
     while i &amp;lt; n do&lt;br /&gt;
       tbl[i],tbl[n] = tbl[n],tbl[i]&lt;br /&gt;
       i = i + 1&lt;br /&gt;
       n = n - 1&lt;br /&gt;
     end&lt;br /&gt;
     return tbl&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Conversion Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This collection of functions that assist in the conversion activities.&lt;br /&gt;
&lt;br /&gt;
===Bool2Str===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
&amp;lt;nowiki&amp;gt; bool2Str - Converts true or false as a string.&lt;br /&gt;
 local x = true &lt;br /&gt;
 tbl = bool2Str(x)&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
 returns &amp;quot;true&amp;quot;&lt;br /&gt;
  function Bool2Str(x)&lt;br /&gt;
    if x then&lt;br /&gt;
      return &amp;quot;true&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      return &amp;quot;false&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  end --function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===D2S8===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
  D2S8 - Converts a Number (Double) to a String with 8 places&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function D2S8(d)                               -- Converts a Number (Double) to a String with 8 places&lt;br /&gt;
-- local x =12.2351&lt;br /&gt;
-- returns &amp;quot;12.23510000&amp;quot;&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
    return string.format(&amp;quot;%.8f&amp;quot;, d)&lt;br /&gt;
  end -- end function &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===D2S4===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; D2S4 - Converts a Number (Double) to a String with 4 places&lt;br /&gt;
 local x =12.23&lt;br /&gt;
  = D2S4(x)&lt;br /&gt;
&lt;br /&gt;
 returns x = &amp;quot;12.2300&amp;quot;&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
  function D2S4(d) &lt;br /&gt;
    return string.format(&amp;quot;%.4f&amp;quot;, d)&lt;br /&gt;
  end -- end function &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Toint===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; Toint - Converts a Double Number to a intiger&lt;br /&gt;
 local x = 12.23&lt;br /&gt;
  = toint(x)&lt;br /&gt;
&lt;br /&gt;
 returns x = 12&lt;br /&gt;
  function toint(number)&lt;br /&gt;
    return math.floor(tonumber(number) or error(&amp;quot;Could not cast '&amp;quot; .. tostring(number) .. &amp;quot;' to number.'&amp;quot;))&lt;br /&gt;
  end -- end function &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Rounder===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
&lt;br /&gt;
  return tonumber(string.format(&amp;quot;%.&amp;quot; .. (idp or 0) .. &amp;quot;f&amp;quot;, n&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
function Rounder(num, idp)                              --  Rounds a Number (Double) up or down&lt;br /&gt;
  return tonumber(string.format(&amp;quot;%.&amp;quot; .. (idp or 0) .. &amp;quot;f&amp;quot;, num))&lt;br /&gt;
end -- end function &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===RUsame===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
function RUsame(num, comp)                              --  Rounds a Number (Double) up or down&lt;br /&gt;
  local function toint(number)&lt;br /&gt;
    return math.floor(tonumber(number) or error(&amp;quot;Could not cast '&amp;quot; .. tostring(number) .. &amp;quot;' to number.'&amp;quot;))&lt;br /&gt;
  end&lt;br /&gt;
  local function Rounder(num, idp)                      --  Rounds a Number (Double) up or down&lt;br /&gt;
    return tonumber(string.format(&amp;quot;%.&amp;quot; .. (idp or 0) .. &amp;quot;f&amp;quot;, num))&lt;br /&gt;
  end -- end function&lt;br /&gt;
        num = math.abs(num)&lt;br /&gt;
  local idp = #comp&lt;br /&gt;
  local Mynum = Rounder(num, idp)&lt;br /&gt;
  local Myint = toint(Mynum)&lt;br /&gt;
  local Myval = tonumber(tostring(Myint) .. &amp;quot;.&amp;quot; .. comp)&lt;br /&gt;
  if (Mynum == Myval) then&lt;br /&gt;
    return true&lt;br /&gt;
  else&lt;br /&gt;
    return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
end -- end function &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===WithIn===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Retuns true if number is within tolerance with match&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function WithIn(Num, Mat, Tol)&lt;br /&gt;
    if ((Num &amp;gt;= (Mat - Tol)) and (Num &amp;lt;= (Mat + Tol))) then&lt;br /&gt;
      return true&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return false&lt;br /&gt;
  end -- end function &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Double2Fraction===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Converts a Measurement (Double) to a Fractional String&lt;br /&gt;
&lt;br /&gt;
local txt = Double2Fraction(1.25)&lt;br /&gt;
&lt;br /&gt;
returns txt =&amp;quot;1-1/4&amp;quot;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function Double2Fraction(Num)&lt;br /&gt;
  local Frac = &amp;quot;Error&amp;quot;&lt;br /&gt;
  if Num then&lt;br /&gt;
    Frac = tostring(Num)&lt;br /&gt;
  end&lt;br /&gt;
  if (not Milling.Unit) and Num then&lt;br /&gt;
    local AmountValuex = math.floor(math.abs(Num))&lt;br /&gt;
    local DicValue    = Num - AmountValuex&lt;br /&gt;
    local AmountValue = tostring(AmountValuex)&lt;br /&gt;
    Frac              = tostring(DicValue)&lt;br /&gt;
&lt;br /&gt;
    if Project.Fractions == &amp;quot;No Fractions&amp;quot; then&lt;br /&gt;
      Frac = tostring(Num)&lt;br /&gt;
&lt;br /&gt;
    elseif Project.Fractions == &amp;quot;1/8&amp;quot; then&lt;br /&gt;
      if     DicValue &amp;gt;= 0.9375 then&lt;br /&gt;
        AmountValue = tostring(AmountValuex + 1)&lt;br /&gt;
        Frac = &amp;quot;0&amp;quot;&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.8125 then Frac = &amp;quot;7/8&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.6875 then Frac = &amp;quot;3/4&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.5625 then Frac = &amp;quot;5/8&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.4375 then Frac = &amp;quot;1/2&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.3125 then Frac = &amp;quot;3/8&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.1875 then Frac = &amp;quot;1/4&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.0625 then Frac = &amp;quot;1/8&amp;quot; .. string.char(34)&lt;br /&gt;
      else&lt;br /&gt;
        Frac = &amp;quot;0&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    elseif Project.Fractions == &amp;quot;1/16&amp;quot; then&lt;br /&gt;
      if     DicValue &amp;gt;= 0.96875 then&lt;br /&gt;
        AmountValue = tostring(AmountValuex + 1)&lt;br /&gt;
        Frac = &amp;quot;0&amp;quot;&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.90625 then Frac = &amp;quot;15/16&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.84375 then Frac = &amp;quot;7/8&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.78125 then Frac = &amp;quot;13/16&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.71875 then Frac = &amp;quot;3/4&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.65625 then Frac = &amp;quot;11/16&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.59375 then Frac = &amp;quot;5/8&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.53125 then Frac = &amp;quot;9/16&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.46875 then Frac = &amp;quot;1/2&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.40625 then Frac = &amp;quot;7/16&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.34375 then Frac = &amp;quot;3/8&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.28125 then Frac = &amp;quot;5/16&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.21875 then Frac = &amp;quot;1/4&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.15625 then Frac = &amp;quot;3/16&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.09375 then Frac = &amp;quot;1/8&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.03125 then Frac = &amp;quot;1/16&amp;quot;  .. string.char(34)&lt;br /&gt;
      else&lt;br /&gt;
        Frac = &amp;quot;0&amp;quot;&lt;br /&gt;
      end -- If end&lt;br /&gt;
    elseif Project.Fractions == &amp;quot;1/32&amp;quot; then&lt;br /&gt;
      if     DicValue &amp;gt;= 0.984375 then&lt;br /&gt;
        AmountValue = tostring(AmountValuex + 1)&lt;br /&gt;
        Frac = &amp;quot;0&amp;quot;&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.953126 then Frac = &amp;quot;31/32&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.921876 then Frac = &amp;quot;15/16&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.890626 then Frac = &amp;quot;29/32&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.859376 then Frac = &amp;quot;7/8&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.828126 then Frac = &amp;quot;27/32&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.796876 then Frac = &amp;quot;13/16&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.765626 then Frac = &amp;quot;25/32&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.737376 then Frac = &amp;quot;3/4&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.703126 then Frac = &amp;quot;23/32&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.671876 then Frac = &amp;quot;11/16&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.640626 then Frac = &amp;quot;21/32&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.609376 then Frac = &amp;quot;5/8&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.578126 then Frac = &amp;quot;19/32&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.541260 then Frac = &amp;quot;9/16&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.515626 then Frac = &amp;quot;17/32&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.484376 then Frac = &amp;quot;1/2&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.468760 then Frac = &amp;quot;15/32&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.421876 then Frac = &amp;quot;7/16&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.390626 then Frac = &amp;quot;13/32&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.359376 then Frac = &amp;quot;3/8&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.328126 then Frac = &amp;quot;11/32&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.296876 then Frac = &amp;quot;5/16&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.265626 then Frac = &amp;quot;9/32&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.234376 then Frac = &amp;quot;1/4&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.203126 then Frac = &amp;quot;7/32&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.171876 then Frac = &amp;quot;3/16&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.140626 then Frac = &amp;quot;5/32&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.109376 then Frac = &amp;quot;1/8&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.078126 then Frac = &amp;quot;3/32&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.046876 then Frac = &amp;quot;1/16&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.015626 then Frac = &amp;quot;1/32&amp;quot;  .. string.char(34)&lt;br /&gt;
      else&lt;br /&gt;
        Frac = &amp;quot;0&amp;quot;&lt;br /&gt;
      end -- If end&lt;br /&gt;
    elseif Project.Fractions == &amp;quot;1/64&amp;quot; then&lt;br /&gt;
      if     DicValue &amp;gt;= 0.9921875 then&lt;br /&gt;
        AmountValue = tostring(AmountValuex + 1)&lt;br /&gt;
        Frac = &amp;quot;0&amp;quot;&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.9765625 then Frac = &amp;quot;62/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.9609375 then Frac = &amp;quot;31/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.9453125 then Frac = &amp;quot;61/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.9296875 then Frac = &amp;quot;15/16&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.9140625 then Frac = &amp;quot;59/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.8984375 then Frac = &amp;quot;29/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.8828125 then Frac = &amp;quot;57/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.8671875 then Frac = &amp;quot;7/8&amp;quot;   .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.8515625 then Frac = &amp;quot;55/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.8359375 then Frac = &amp;quot;27/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.8203125 then Frac = &amp;quot;53/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.8046875 then Frac = &amp;quot;13/16&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.7890625 then Frac = &amp;quot;51/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.7734375 then Frac = &amp;quot;25/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.7578125 then Frac = &amp;quot;49/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.7421875 then Frac = &amp;quot;3/4&amp;quot;   .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.7265625 then Frac = &amp;quot;47/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.7109375 then Frac = &amp;quot;23/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.6953125 then Frac = &amp;quot;45/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.6796875 then Frac = &amp;quot;11/16&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.6640625 then Frac = &amp;quot;43/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.6484375 then Frac = &amp;quot;21/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.6328125 then Frac = &amp;quot;41/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.6171875 then Frac = &amp;quot;5/8&amp;quot;   .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.6015625 then Frac = &amp;quot;39/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.5859375 then Frac = &amp;quot;19/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.5703125 then Frac = &amp;quot;37/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.5546875 then Frac = &amp;quot;9/16&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.5390625 then Frac = &amp;quot;35/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.5234375 then Frac = &amp;quot;17/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.5078125 then Frac = &amp;quot;33/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.4921875 then Frac = &amp;quot;1/2&amp;quot;   .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.4765625 then Frac = &amp;quot;31/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.4609375 then Frac = &amp;quot;15/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.4453125 then Frac = &amp;quot;29/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.4296875 then Frac = &amp;quot;7/16&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.4140625 then Frac = &amp;quot;27/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.3984375 then Frac = &amp;quot;13/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.3828125 then Frac = &amp;quot;25/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.3671875 then Frac = &amp;quot;3/8&amp;quot;   .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.3515625 then Frac = &amp;quot;23/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.3359375 then Frac = &amp;quot;11/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.3203125 then Frac = &amp;quot;21/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.3046875 then Frac = &amp;quot;5/16&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.2890625 then Frac = &amp;quot;19/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.2734375 then Frac = &amp;quot;9/32&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.2578125 then Frac = &amp;quot;17/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.2421875 then Frac = &amp;quot;1/4&amp;quot;   .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.2265625 then Frac = &amp;quot;15/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.2109375 then Frac = &amp;quot;7/32&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.1953125 then Frac = &amp;quot;13/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.1796875 then Frac = &amp;quot;3/16&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.1640625 then Frac = &amp;quot;11/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.1484375 then Frac = &amp;quot;5/32&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.1328125 then Frac = &amp;quot;9/64&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.1171875 then Frac = &amp;quot;1/8&amp;quot;   .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.1015625 then Frac = &amp;quot;7/64&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.0859375 then Frac = &amp;quot;3/32&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.0703125 then Frac = &amp;quot;5/64&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.0546875 then Frac = &amp;quot;1/16&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.0390625 then Frac = &amp;quot;3/64&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.0234375 then Frac = &amp;quot;1/32&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.0078125 then Frac = &amp;quot;1/64&amp;quot;  .. string.char(34)&lt;br /&gt;
        else&lt;br /&gt;
          Frac = &amp;quot;0&amp;quot;&lt;br /&gt;
        end -- If end&lt;br /&gt;
      end&lt;br /&gt;
    if Project.Fractions == &amp;quot;No Fractions&amp;quot; then&lt;br /&gt;
      Frac = tostring(Num)&lt;br /&gt;
    else&lt;br /&gt;
      if Frac == &amp;quot;0&amp;quot; then&lt;br /&gt;
        Frac = AmountValue .. string.char(34)&lt;br /&gt;
      else&lt;br /&gt;
        if AmountValue ~= &amp;quot;0&amp;quot; then&lt;br /&gt;
          Frac = AmountValue .. &amp;quot;-&amp;quot; .. Frac&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  return Frac&lt;br /&gt;
end -- end function &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Time and Date Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This collection of functions are utilized in the date and time calculations.&lt;br /&gt;
&lt;br /&gt;
===StartDateTime===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
StartDateTime - Returns the Date and Time.&lt;br /&gt;
&lt;br /&gt;
local dt= StartDateTime(true)&lt;br /&gt;
&lt;br /&gt;
returns tbl = &amp;quot;10/02/23&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;   function StartDateTime(LongShort)&lt;br /&gt;
--[[ Date Value Codes&lt;br /&gt;
--  |    %a  abbreviated weekday name (e.g., Wed)&lt;br /&gt;
--  |    %A  full weekday name (e.g., Wednesday)&lt;br /&gt;
--  |    %b  abbreviated month name (e.g., Sep)&lt;br /&gt;
--  |    %B  full month name (e.g., September)&lt;br /&gt;
--  |    %c  date and time (e.g., 09/16/98 23:48:10)&lt;br /&gt;
--  |    %d  day of the month (16) [01-31]&lt;br /&gt;
--  |    %H  hour, using a 24-hour clock (23) [00-23]&lt;br /&gt;
--  |    %I  hour, using a 12-hour clock (11) [01-12]&lt;br /&gt;
--  |    %M  minute (48) [00-59]&lt;br /&gt;
--  |    %m  month (09) [01-12]&lt;br /&gt;
--  |    %p  either &amp;quot;am&amp;quot; or &amp;quot;pm&amp;quot; (pm)&lt;br /&gt;
--  |    %S  second (10) [00-60]&lt;br /&gt;
--  |    %w  weekday (3) [0-6 = Sunday-Saturday]&lt;br /&gt;
--  |    %x  date (e.g., 09/16/98)&lt;br /&gt;
--  |    %X  time (e.g., 23:48:10)&lt;br /&gt;
--  |    %Y  full year (e.g., 1998)&lt;br /&gt;
--  |    %y  two-digit year (98) [00-99]&lt;br /&gt;
--  |    %%  the character `%´ ]]&lt;br /&gt;
    if LongShort then&lt;br /&gt;
      return os.date(&amp;quot;%b %d, %Y&amp;quot;) .. &amp;quot; - &amp;quot; .. os.date(&amp;quot;%I&amp;quot;) .. &amp;quot;:&amp;quot; .. os.date(&amp;quot;%m&amp;quot;) .. os.date(&amp;quot;%p&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      return os.date(&amp;quot;%Y%m%d%H%M&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===StartDate===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
StartDate - Returns the Date and Time.&lt;br /&gt;
&lt;br /&gt;
local dt= StartDate(true)&lt;br /&gt;
&lt;br /&gt;
returns tbl = &amp;quot;10/02/23&amp;quot;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function StartDate(LongShort)&lt;br /&gt;
--[[ Date Value Codes&lt;br /&gt;
--  |    %a  abbreviated weekday name (e.g., Wed)&lt;br /&gt;
--  |    %A  full weekday name (e.g., Wednesday)&lt;br /&gt;
--  |    %b  abbreviated month name (e.g., Sep)&lt;br /&gt;
--  |    %B  full month name (e.g., September)&lt;br /&gt;
--  |    %c  date and time (e.g., 09/16/98 23:48:10)&lt;br /&gt;
--  |    %d  day of the month (16) [01-31]&lt;br /&gt;
--  |    %H  hour, using a 24-hour clock (23) [00-23]&lt;br /&gt;
--  |    %I  hour, using a 12-hour clock (11) [01-12]&lt;br /&gt;
--  |    %M  minute (48) [00-59]&lt;br /&gt;
--  |    %m  month (09) [01-12]&lt;br /&gt;
--  |    %p  either &amp;quot;am&amp;quot; or &amp;quot;pm&amp;quot; (pm)&lt;br /&gt;
--  |    %S  second (10) [00-60]&lt;br /&gt;
--  |    %w  weekday (3) [0-6 = Sunday-Saturday]&lt;br /&gt;
--  |    %x  date (e.g., 09/16/98)&lt;br /&gt;
--  |    %X  time (e.g., 23:48:10)&lt;br /&gt;
--  |    %Y  full year (e.g., 1998)&lt;br /&gt;
--  |    %y  two-digit year (98) [00-99]&lt;br /&gt;
--  |    %%  the character `%´ ]]&lt;br /&gt;
&lt;br /&gt;
    if LongShort then&lt;br /&gt;
      return os.date(&amp;quot;%b %d, %Y&amp;quot;)  -- &amp;quot;Sep 01, 2022&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      return os.date(&amp;quot;%Y%m%d&amp;quot;)     -- &amp;quot;20220901&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Wait===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Wait - Waits for a duration.&lt;br /&gt;
&lt;br /&gt;
local dt = Wait(true)&lt;br /&gt;
&lt;br /&gt;
returns tbl = &amp;quot;10/02/23&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;nowiki&amp;gt; function Wait(time)&lt;br /&gt;
    local duration = os.time() + time&lt;br /&gt;
    while os.time() &amp;lt; duration do end&lt;br /&gt;
    end&lt;br /&gt;
 end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Debugging Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This collection of functions assist in the debugging of code.&lt;br /&gt;
&lt;br /&gt;
===DMark - places a circle and notation to assist in geometry debugging===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws a circle and marks on the drawing for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
call = DebugMarkPoint(&amp;quot;Note: Hi&amp;quot;, Pt1)&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function DMark(Note, Pt)&lt;br /&gt;
  -- ==== Sub Function&lt;br /&gt;
    local function DrawCircle(job, Cpt, CircleRadius, LayerName)  -- Draws a circle&lt;br /&gt;
      local pa   = Polar2D(Cpt, 180.0, CircleRadius)&lt;br /&gt;
      local pb   = Polar2D(Cpt,   0.0, CircleRadius)&lt;br /&gt;
      local line = Contour(0.0)&lt;br /&gt;
      line:AppendPoint(pa); line:ArcTo(pb,1); line:ArcTo(pa,1)&lt;br /&gt;
      local layer = job.LayerManager:GetLayerWithName(LayerName)&lt;br /&gt;
      layer:AddObject(CreateCadContour(line), true)&lt;br /&gt;
      return true&lt;br /&gt;
    end -- function end&lt;br /&gt;
  -- ====&lt;br /&gt;
    local BubbleSize = 1.25&lt;br /&gt;
    if not Project.DebugAngle then&lt;br /&gt;
      Project.DebugAngle = 0.0&lt;br /&gt;
    end&lt;br /&gt;
    Project.DebugAngle = Project.DebugAngle + 2.0&lt;br /&gt;
    if Project.DebugAngle &amp;gt;= 90.0 and Project.DebugAngle &amp;lt;= 358.0 then&lt;br /&gt;
      Project.DebugAngle = 272.0&lt;br /&gt;
    elseif Project.DebugAngle &amp;gt;= 360.0 then&lt;br /&gt;
      Project.DebugAngle = 2.0&lt;br /&gt;
    end&lt;br /&gt;
    if Pt then&lt;br /&gt;
      local job = VectricJob()&lt;br /&gt;
      local Pt1 = Polar2D(Pt, Project.DebugAngle, BubbleSize)&lt;br /&gt;
      local Pt2 = Polar2D(Pt1, 0.0, BubbleSize * 0.25)&lt;br /&gt;
      local Pt3 = Polar2D(Pt2, 315.0, BubbleSize * 0.0883883476483188 * 4.0)&lt;br /&gt;
      local line = Contour(0.0)&lt;br /&gt;
      local layer = job.LayerManager:GetLayerWithName(&amp;quot;Debug&amp;quot;)&lt;br /&gt;
      line:AppendPoint(Pt)&lt;br /&gt;
      line:LineTo(Pt1)&lt;br /&gt;
      line:LineTo(Pt2)&lt;br /&gt;
      layer:AddObject(CreateCadContour(line), true)&lt;br /&gt;
      DrawWriter(Note, Pt3, BubbleSize * 0.5, &amp;quot;Debug&amp;quot;, 0.0)&lt;br /&gt;
      DrawCircle(job, Pt, BubbleSize * 0.5, &amp;quot;Debug&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Issue with Point for - &amp;quot; .. Note)&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===StatusMessage===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Useage: (Type of Message, Dialog Header, Question or Message, Err No.)&lt;br /&gt;
&lt;br /&gt;
StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Base Cabinet Settings&amp;quot;, &amp;quot;Face Frame Bottom Rail Width - value cannot be 0.&amp;quot;, &amp;quot;(9000)&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Note: if the debug flag is on (true) a message box shows the message length, dialog size and error number&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function StatusMessage(Type, Header, Question, ErrorNumber)&lt;br /&gt;
&lt;br /&gt;
  local dialog&lt;br /&gt;
  local X = 460&lt;br /&gt;
  local Y = 124&lt;br /&gt;
  local step = 35&lt;br /&gt;
  Question = WrapString(Question, step)&lt;br /&gt;
  local QL = string.len(Question)&lt;br /&gt;
  if (QL &amp;gt; step) and (QL &amp;lt; step * 2) then&lt;br /&gt;
    Y = Y + 12&lt;br /&gt;
  elseif (QL &amp;gt; (step * 2) +1) and (QL &amp;lt; 105) then&lt;br /&gt;
    Y = Y + 24&lt;br /&gt;
  elseif (QL &amp;gt; (step * 3) +1) and (QL &amp;lt; (step * 4)) then&lt;br /&gt;
    Y = Y + 36&lt;br /&gt;
  elseif (QL &amp;gt; (step * 4) +1) and (QL &amp;lt; (step * 5)) then&lt;br /&gt;
    Y = Y + 48&lt;br /&gt;
  elseif (QL &amp;gt; (step * 5) +1) and (QL &amp;lt; (step * 6)) then&lt;br /&gt;
    Y = Y + 60&lt;br /&gt;
  elseif (QL &amp;gt; (step * 6) +1) and (QL &amp;lt; (step * 7)) then&lt;br /&gt;
    Y = Y + 72&lt;br /&gt;
  elseif (QL &amp;gt; (step * 7) +1) and (QL &amp;lt; (step * 8)) then&lt;br /&gt;
    Y = Y + 84&lt;br /&gt;
  elseif (QL &amp;gt; (step * 8) +1) and (QL &amp;lt; (step * 9)) then&lt;br /&gt;
    Y = Y + 96&lt;br /&gt;
  elseif (QL &amp;gt; (step * 9) +1) and (QL &amp;lt; (step * 10)) then&lt;br /&gt;
    Y = Y + 108&lt;br /&gt;
  elseif (QL &amp;gt; (step * 10) +1) and (QL &amp;lt; (step * 11)) then&lt;br /&gt;
    Y = Y + 120&lt;br /&gt;
  else&lt;br /&gt;
    Y = Y + 150&lt;br /&gt;
  end&lt;br /&gt;
  if Project.Debugger then&lt;br /&gt;
    Queston = Question .. &amp;quot; - &amp;quot; .. ErrorNumber&lt;br /&gt;
  end&lt;br /&gt;
  if Type == &amp;quot;Alert&amp;quot; then&lt;br /&gt;
    dialog = HTML_Dialog(true, DialogWindow.myHtml16, X, Y, Header)&lt;br /&gt;
  else -- &amp;quot;Error&amp;quot;&lt;br /&gt;
    dialog = HTML_Dialog(true, DialogWindow.myHtml17, X, Y, Header)&lt;br /&gt;
  end -- if end&lt;br /&gt;
  if Project.Debugger then&lt;br /&gt;
    Question = Question .. &amp;quot; &amp;quot; .. ErrorNumber&lt;br /&gt;
  end&lt;br /&gt;
  dialog:AddLabelField(&amp;quot;Question&amp;quot;, Type .. &amp;quot;: &amp;quot; .. Question)&lt;br /&gt;
  dialog:ShowDialog()&lt;br /&gt;
  if Project.Debugger then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Question Len &amp;quot; .. &amp;quot; = &amp;quot; .. tostring(string.len(Question)) .. &amp;quot;: \nWindow = &amp;quot; .. tostring(dialog.WindowWidth) .. &amp;quot; x &amp;quot; .. tostring(dialog.WindowHeight))&lt;br /&gt;
  end&lt;br /&gt;
  return true&lt;br /&gt;
end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===DebugMarkPoint===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Used in debugging drawing issues - Draws a Circle and Text at the provided point(x,y) &lt;br /&gt;
&lt;br /&gt;
call = DebugMarkPoint(&amp;quot;Note: Hi&amp;quot;, Pt1, 0.125, &amp;quot;Jim&amp;quot;)&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DebugMarkPoint(Note, Pt, Size, LayerName)&lt;br /&gt;
    if Size == nil then&lt;br /&gt;
      Size = 0.125&lt;br /&gt;
    end&lt;br /&gt;
    if LayerName == nil then&lt;br /&gt;
      LayerName = &amp;quot;Debug&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  -- ==== Sub Function&lt;br /&gt;
    local function DrawCircle(job, Cpt, CircleRadius, LayerName)  -- Draws a circle&lt;br /&gt;
      local pa = Polar2D(Cpt, 180.0, CircleRadius)&lt;br /&gt;
      local pb = Polar2D(Cpt,   0.0, CircleRadius)&lt;br /&gt;
      local line = Contour(0.0)&lt;br /&gt;
      line:AppendPoint(pa); line:ArcTo(pb,1);   line:ArcTo(pa,1)&lt;br /&gt;
      local layer = job.LayerManager:GetLayerWithName(LayerName)&lt;br /&gt;
      layer:AddObject(CreateCadContour(line), true)&lt;br /&gt;
      return true&lt;br /&gt;
    end -- sub function end&lt;br /&gt;
  -- ====&lt;br /&gt;
    local job = VectricJob()&lt;br /&gt;
    local Pt1 = Polar2D(Pt, Project.DebugAngle, Size * 2.0)&lt;br /&gt;
    local Pt2 = Polar2D(Pt1, 0.0, 0.500 * Size)&lt;br /&gt;
    local Pt3 = Polar2D(Pt2, 315.0, (0.500 * Size) * 1.4142135623731)&lt;br /&gt;
    local line = Contour(0.0)&lt;br /&gt;
    local layer = job.LayerManager:GetLayerWithName(LayerName)&lt;br /&gt;
    line:AppendPoint(Pt)&lt;br /&gt;
    line:LineTo(Pt1)&lt;br /&gt;
    line:LineTo(Pt2)&lt;br /&gt;
    layer:AddObject(CreateCadContour(line), true)&lt;br /&gt;
    DrawWriter(Note, Pt3, Size, LayerName, 0.0)&lt;br /&gt;
    DrawCircle(job, Pt, Size, LayerName)&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===ShowDialogSize===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function ShowDialogSize()&lt;br /&gt;
    DisplayMessageBox(tostring(dialog.WindowWidth) .. &amp;quot; x &amp;quot; ..  tostring(dialog.WindowHeight))&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Dialog and Menu Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document.&lt;br /&gt;
&lt;br /&gt;
===DialogSize===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function DialogSize(Str)                                -- Returns the X and Y value of the dialogue&lt;br /&gt;
  local InText = string.find(string.upper(Str) , &amp;quot;X&amp;quot;)&lt;br /&gt;
  local DialogX = All_Trim(string.sub(Str, 1, InText - 1))&lt;br /&gt;
  local DialogY = All_Trim(string.sub(Str, InText + 1))&lt;br /&gt;
  return tonumber(DialogX), tonumber(DialogY)&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===ProgressBarAmount===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function ProgressBarAmount(TotalRecords, Record)        -- Calculates the percent amount of progression based on total process&lt;br /&gt;
  --[[&lt;br /&gt;
  local MyProgressBar&lt;br /&gt;
    MyProgressBar = ProgressBar(&amp;quot;Working&amp;quot;, ProgressBar.LINEAR)                -- Setup Type of progress bar&lt;br /&gt;
    MyProgressBar:SetPercentProgress(0)                                       -- Sets progress bar to zero&lt;br /&gt;
    MyProgressBar:SetPercentProgress(ProgressAmount(Door.Records, myRecord))  -- sends percent of process progress bar (adds to the bar)&lt;br /&gt;
    MyProgressBar:SetPercentProgress(ProgressAmount(12000, 416))              -- sends percent of process progress bar (adds to the bar)&lt;br /&gt;
    MyProgressBar:SetText(&amp;quot;Compete&amp;quot;)                                          -- Sets the label to Complete&lt;br /&gt;
    MyProgressBar:Finished()                                                  -- Close Progress Bar&lt;br /&gt;
  ]]&lt;br /&gt;
    local X1 = (100.0 / TotalRecords)&lt;br /&gt;
    local X2 = X1 * Record&lt;br /&gt;
    local X3 = math.abs(X2)&lt;br /&gt;
    local X4 = (math.floor(X3))&lt;br /&gt;
    return (math.floor(math.abs((100.0 / TotalRecords) * Record)))&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===OnLuaButton_InquiryGearCalulate===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function OnLuaButton_InquiryGearCalulate(dialog)&lt;br /&gt;
  Gear.Addendum         = dialog:GetDoubleField(&amp;quot;Gear.Addendum&amp;quot;)&lt;br /&gt;
  Gear.Dedendum         = dialog:GetDoubleField(&amp;quot;Gear.Dedendum&amp;quot;)&lt;br /&gt;
  Gear.AddendumDiameter = dialog:GetDoubleField(&amp;quot;Gear.AddendumDiameter&amp;quot;)&lt;br /&gt;
  Gear.DedendumDiameter = dialog:GetDoubleField(&amp;quot;Gear.DedendumDiameter&amp;quot;)&lt;br /&gt;
  Gear.ToothTickness    = dialog:GetDoubleField(&amp;quot;Gear.ToothTickness&amp;quot;)&lt;br /&gt;
  Gear.Slotwidth        = dialog:GetDoubleField(&amp;quot;Gear.Slotwidth&amp;quot;)&lt;br /&gt;
  Gear.PitchAmount      = dialog:GetDoubleField(&amp;quot;Gear.PitchAmount&amp;quot;)&lt;br /&gt;
  Gear.FilletRadius     = dialog:GetDoubleField(&amp;quot;Gear.FilletRadius&amp;quot;)&lt;br /&gt;
  Gear.ToplandAmount    = dialog:GetDoubleField(&amp;quot;Gear.ToplandAmount&amp;quot;)&lt;br /&gt;
  Gear.FaceFlankRadius  = dialog:GetDoubleField(&amp;quot;Gear.FaceFlankRadius&amp;quot;)&lt;br /&gt;
  Gear.ToothCount       = dialog:GetDropDownListValue(&amp;quot;Gear.ToothCount&amp;quot;)&lt;br /&gt;
  Gear.ShowLines        = dialog:GetDropDownListValue(&amp;quot;Gear.ShowLines&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  dialog:UpdateDoubleField(&amp;quot;Gear.Addendum&amp;quot;,                      Gear.Addendum)&lt;br /&gt;
  dialog:UpdateDoubleField(&amp;quot;Gear.Dedendum&amp;quot;,                      Gear.Dedendum)&lt;br /&gt;
  dialog:UpdateDoubleField(&amp;quot;Gear.AddendumDiameter&amp;quot;,              Gear.AddendumDiameter)&lt;br /&gt;
  dialog:UpdateDoubleField(&amp;quot;Gear.DedendumDiameter&amp;quot;,              Gear.DedendumDiameter)&lt;br /&gt;
  dialog:UpdateDoubleField(&amp;quot;Gear.ToothTickness&amp;quot;,                 Gear.ToothTickness)&lt;br /&gt;
  dialog:UpdateDoubleField(&amp;quot;Gear.Slotwidth&amp;quot;,                     Gear.Slotwidth)&lt;br /&gt;
  dialog:UpdateDoubleField(&amp;quot;Gear.PitchAmount&amp;quot;,                   Gear.PitchAmount)&lt;br /&gt;
  dialog:UpdateDoubleField(&amp;quot;Gear.FilletRadius&amp;quot;,                  Gear.FilletRadius)&lt;br /&gt;
  dialog:UpdateDoubleField(&amp;quot;Gear.ToplandAmount&amp;quot;,                 Gear.ToplandAmount)&lt;br /&gt;
  dialog:UpdateDoubleField(&amp;quot;Gear.FaceFlankRadius&amp;quot;,               Gear.FaceFlankRadius)&lt;br /&gt;
&lt;br /&gt;
  return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===InquiryDropList===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function InquiryDropList(Header, Quest, DX, DY, DList)&lt;br /&gt;
--[[&lt;br /&gt;
    Drop list foe user input&lt;br /&gt;
    Caller: local y = InquiryDropList(&amp;quot;Cabinet Maker&amp;quot;, &amp;quot;Select Cabinet Style&amp;quot;, 290, 165, IniFile)&lt;br /&gt;
    Dialog Header = &amp;quot;Cabinet Maker&amp;quot;&lt;br /&gt;
    Quest = &amp;quot;Select Cabinet Style&amp;quot;&lt;br /&gt;
    Selection Array = IniFile&lt;br /&gt;
    Returns = String&lt;br /&gt;
]]&lt;br /&gt;
    local myHtml = [[&amp;lt;!DOCTYPE HTML&amp;gt;&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;My List Box&amp;lt;/title&amp;gt;&amp;lt;style&amp;gt;.FormButton{font-weight:700;width:75px;font-size:12px;white-space:nowrap;font-family:Arial,Helvetica,sans-serif font-size: 12px}.h1-l{font-size:12px;font-weight:700;text-align:left;white-space:nowrap}.h1-c{font-size:12px;font-weight:700;text-align:center;white-space:nowrap}table{width:100%;border:0}body,td,th{background-color:#3a4660;background-position:center;overflow:hidden;font-family:arial,helvetica,sans-serif;font-size:12px;color:#fff;background-image:url(']].. DialogWindow.myBackGround ..[[')}html{overflow:hidden}&amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;h1-l&amp;quot; id=&amp;quot;Questions&amp;quot;&amp;gt;&amp;lt;strong class=&amp;quot;h2&amp;quot;&amp;gt;Message Here&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;h1-c&amp;quot;&amp;gt;&amp;lt;select name=&amp;quot;DList&amp;quot; size=&amp;quot;10&amp;quot; class=&amp;quot;h1-c&amp;quot; id=&amp;quot;ListBox&amp;quot;&amp;gt;&amp;lt;option&amp;gt;My Default 1&amp;lt;/option&amp;gt;&amp;lt;option selected=&amp;quot;selected&amp;quot;&amp;gt;My Default 2&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;My Default 3&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;My Default 4&amp;lt;/option&amp;gt;&amp;lt;/select&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;th class=&amp;quot;h1-l&amp;quot; colspan=&amp;quot;3&amp;quot; id=&amp;quot;QuestionID&amp;quot;&amp;gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;h1-c&amp;quot;&amp;gt;&amp;lt;input id=&amp;quot;ButtonCancel&amp;quot; class=&amp;quot;FormButton&amp;quot; name=&amp;quot;ButtonCancel&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;Cancel&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;h1-c&amp;quot;&amp;gt;&amp;lt;input id=&amp;quot;ButtonOK&amp;quot; class=&amp;quot;FormButton&amp;quot; name=&amp;quot;ButtonOK&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;OK&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;]] ;&lt;br /&gt;
&lt;br /&gt;
    local dialog = HTML_Dialog(true, myHtml, DX, DY, Header)&lt;br /&gt;
          dialog:AddLabelField(&amp;quot;Questions&amp;quot;, Quest)&lt;br /&gt;
          dialog:AddDropDownList(&amp;quot;ListBox&amp;quot;, &amp;quot;DEFAULT&amp;quot;)&lt;br /&gt;
          dialog:AddDropDownListValue(&amp;quot;ListBox&amp;quot;, &amp;quot;DEFAULT&amp;quot;)&lt;br /&gt;
    for index, value in pairs(DList) do&lt;br /&gt;
        dialog:AddDropDownListValue(&amp;quot;ListBox&amp;quot;, value)&lt;br /&gt;
    end&lt;br /&gt;
    if not dialog:ShowDialog() then&lt;br /&gt;
      return &amp;quot;.&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      return dialog:GetDropDownListValue(&amp;quot;ListBox&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===InquiryFileBox===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function InquiryFileBox(Header, Quest, DefaltPath)&lt;br /&gt;
--[[&lt;br /&gt;
    Dialog Box for user to pick a file&lt;br /&gt;
    Caller: local X = InquiryFileBox(&amp;quot;Select File&amp;quot;, &amp;quot;Where is the file location?&amp;quot;, &amp;quot;C:\\&amp;quot;)&lt;br /&gt;
    Dialog Header = &amp;quot;File Name&amp;quot;&lt;br /&gt;
    User Question = &amp;quot;Path name?&amp;quot;&lt;br /&gt;
    Default Value = &amp;quot;C:\\&amp;quot;&lt;br /&gt;
    Returns = String&lt;br /&gt;
  ]]&lt;br /&gt;
  local myHtml = [[&amp;lt;html&amp;gt; &amp;lt;head&amp;gt; &amp;lt;title&amp;gt;Easy Tools&amp;lt;/title&amp;gt; &amp;lt;style type = &amp;quot;text/css&amp;quot;&amp;gt;  html {overflow: hidden; } body {&lt;br /&gt;
             background-color: #EBEBEB; overflow:hidden; font-family: Arial, Helvetica, sans-serif; font-size: 12px; } body, td,&lt;br /&gt;
             th {font-family: Arial, Helvetica, sans-serif ; font-size: 12px ; color: #000 ; } .FormButton {font-weight: bold ;&lt;br /&gt;
             width: 100% ; font-family: Arial, Helvetica, sans-serif ; font-size: 12px ; } body { background-color: #EBEBEB; }&lt;br /&gt;
             &amp;lt;/style&amp;gt; &amp;lt;/head&amp;gt; &amp;lt;body bgcolor = &amp;quot;#EBEBEB&amp;quot; text = &amp;quot;#000000&amp;quot;&amp;gt; &amp;lt;table width = &amp;quot;470&amp;quot; border = &amp;quot;0&amp;quot; cellpadding = &amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;tr&amp;gt; &amp;lt;th align = &amp;quot;left&amp;quot; valign = &amp;quot;top&amp;quot; bgcolor = &amp;quot;#EBEBEB&amp;quot; id = &amp;quot;QuestionID&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Message Here&amp;lt;/strong&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
             &amp;lt;th align = &amp;quot;left&amp;quot; valign = &amp;quot;middle&amp;quot; bgcolor = &amp;quot;#EBEBEB&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/th&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt;&lt;br /&gt;
             &amp;lt;th width = &amp;quot;381&amp;quot; align = &amp;quot;right&amp;quot; valign = &amp;quot;middle&amp;quot; bgcolor = &amp;quot;#EBEBEB&amp;quot; id = &amp;quot;QuestionID&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;input name = &amp;quot;ReadFile&amp;quot; type = &amp;quot;text&amp;quot; id = &amp;quot;ReadFile&amp;quot; size = &amp;quot;60&amp;quot;&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
             &amp;lt;th width = &amp;quot;83&amp;quot; align = &amp;quot;center&amp;quot; valign = &amp;quot;middle&amp;quot; bgcolor = &amp;quot;#EBEBEB&amp;quot;&amp;gt; &amp;lt;span style=&amp;quot;width: 15%&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;input id = &amp;quot;FilePicker&amp;quot; class = &amp;quot;FilePicker&amp;quot; name = &amp;quot;FilePicker&amp;quot; type = &amp;quot;button&amp;quot; value = &amp;quot;Path&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td colspan = &amp;quot;2&amp;quot; align = &amp;quot;center&amp;quot; valign = &amp;quot;middle&amp;quot; bgcolor = &amp;quot;#EBEBEB&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;table border = &amp;quot;0&amp;quot; width = &amp;quot;100%&amp;quot;&amp;gt; &amp;lt;tr align = &amp;quot;right&amp;quot;&amp;gt; &amp;lt;td style = &amp;quot;width: 20%&amp;quot;&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
             &amp;lt;td style = &amp;quot;width: 20%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;td style = &amp;quot;width: 25%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;td style = &amp;quot;width: 15%&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;input id = &amp;quot;ButtonCancel&amp;quot; class = &amp;quot;FormButton&amp;quot; name = &amp;quot;ButtonCancel&amp;quot; type = &amp;quot;button&amp;quot; value = &amp;quot;Cancel&amp;quot;&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
             &amp;lt;td style = &amp;quot;width: 15%&amp;quot;&amp;gt; &amp;lt;input id = &amp;quot;ButtonOK&amp;quot; class = &amp;quot;FormButton&amp;quot; name = &amp;quot;ButtonOK&amp;quot; type = &amp;quot;button&amp;quot; value = &amp;quot;OK&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;/table&amp;gt; &amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;/table&amp;gt; &amp;lt;/body&amp;gt;  &amp;lt;/html&amp;gt;]]&lt;br /&gt;
  -- =============================================&lt;br /&gt;
  local dialog = HTML_Dialog(true, myHtml, 505, 150, Header)&lt;br /&gt;
    dialog:AddLabelField(&amp;quot;QuestionID&amp;quot;, Quest)&lt;br /&gt;
    dialog:AddTextField(&amp;quot;ReadFile&amp;quot;, DefaltPath )&lt;br /&gt;
    dialog:AddFilePicker(true, &amp;quot;FilePickerButton&amp;quot;, &amp;quot;ReadFile&amp;quot;, true)&lt;br /&gt;
    if not dialog:ShowDialog() then&lt;br /&gt;
      return &amp;quot;&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      return dialog:GetTextField(&amp;quot;ReadFile&amp;quot;)&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===InquiryPathBox===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function InquiryPathBox(Header, Quest, DefaltPath)&lt;br /&gt;
--[[&lt;br /&gt;
    Number Box for user input with default value&lt;br /&gt;
    Caller: local X = InquiryPathBox(&amp;quot;Select Path&amp;quot;, &amp;quot;Where is the file location?&amp;quot;, &amp;quot;C:\\&amp;quot;)&lt;br /&gt;
    Dialog Header = &amp;quot;Tool Name&amp;quot;&lt;br /&gt;
    User Question = &amp;quot;Path name?&amp;quot;&lt;br /&gt;
    Default Value = &amp;quot;C:\\&amp;quot;&lt;br /&gt;
    Returns = String&lt;br /&gt;
  ]]&lt;br /&gt;
  local myHtml = [[ &amp;lt;html&amp;gt; &amp;lt;head&amp;gt; &amp;lt;title&amp;gt;Easy Tools&amp;lt;/title&amp;gt; &amp;lt;style type = &amp;quot;text/css&amp;quot;&amp;gt;  html {overflow: hidden; } body {&lt;br /&gt;
             background-color: #EBEBEB; overflow:hidden; font-family: Arial, Helvetica, sans-serif; font-size: 12px; } body, td,&lt;br /&gt;
             th {font-family: Arial, Helvetica, sans-serif ; font-size: 12px ; color: #000 ; } .FormButton {font-weight: bold ;&lt;br /&gt;
             width: 100% ; font-family: Arial, Helvetica, sans-serif ; font-size: 12px ; } body { background-color: #EBEBEB; }&lt;br /&gt;
             &amp;lt;/style&amp;gt; &amp;lt;/head&amp;gt; &amp;lt;body bgcolor = &amp;quot;#EBEBEB&amp;quot; text = &amp;quot;#000000&amp;quot;&amp;gt; &amp;lt;table width = &amp;quot;470&amp;quot; border = &amp;quot;0&amp;quot; cellpadding = &amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;tr&amp;gt; &amp;lt;th align = &amp;quot;left&amp;quot; valign = &amp;quot;top&amp;quot; bgcolor = &amp;quot;#EBEBEB&amp;quot; id = &amp;quot;QuestionID&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Message Here&amp;lt;/strong&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
             &amp;lt;th align = &amp;quot;left&amp;quot; valign = &amp;quot;middle&amp;quot; bgcolor = &amp;quot;#EBEBEB&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/th&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt;&lt;br /&gt;
             &amp;lt;th width = &amp;quot;381&amp;quot; align = &amp;quot;right&amp;quot; valign = &amp;quot;middle&amp;quot; bgcolor = &amp;quot;#EBEBEB&amp;quot; id = &amp;quot;QuestionID&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;input name = &amp;quot;DInput&amp;quot; type = &amp;quot;text&amp;quot; id = &amp;quot;DInput&amp;quot; size = &amp;quot;60&amp;quot;&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
             &amp;lt;th width = &amp;quot;83&amp;quot; align = &amp;quot;center&amp;quot; valign = &amp;quot;middle&amp;quot; bgcolor = &amp;quot;#EBEBEB&amp;quot;&amp;gt; &amp;lt;span style=&amp;quot;width: 15%&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;input id = &amp;quot;DirectoryPicker&amp;quot; class = &amp;quot;DirectoryPicker&amp;quot; name = &amp;quot;DirectoryPicker&amp;quot; type = &amp;quot;button&amp;quot; value = &amp;quot;Path&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td colspan = &amp;quot;2&amp;quot; align = &amp;quot;center&amp;quot; valign = &amp;quot;middle&amp;quot; bgcolor = &amp;quot;#EBEBEB&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;table border = &amp;quot;0&amp;quot; width = &amp;quot;100%&amp;quot;&amp;gt; &amp;lt;tr align = &amp;quot;right&amp;quot;&amp;gt; &amp;lt;td style = &amp;quot;width: 20%&amp;quot;&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
             &amp;lt;td style = &amp;quot;width: 20%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;td style = &amp;quot;width: 25%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;td style = &amp;quot;width: 15%&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;input id = &amp;quot;ButtonCancel&amp;quot; class = &amp;quot;FormButton&amp;quot; name = &amp;quot;ButtonCancel&amp;quot; type = &amp;quot;button&amp;quot; value = &amp;quot;Cancel&amp;quot;&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
             &amp;lt;td style = &amp;quot;width: 15%&amp;quot;&amp;gt; &amp;lt;input id = &amp;quot;ButtonOK&amp;quot; class = &amp;quot;FormButton&amp;quot; name = &amp;quot;ButtonOK&amp;quot; type = &amp;quot;button&amp;quot; value = &amp;quot;OK&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;/table&amp;gt; &amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;/table&amp;gt; &amp;lt;/body&amp;gt;  &amp;lt;/html&amp;gt;]]&lt;br /&gt;
  -- =============================================&lt;br /&gt;
  local dialog = HTML_Dialog(true, myHtml, 505, 150, Header)&lt;br /&gt;
    dialog:AddLabelField(&amp;quot;QuestionID&amp;quot;, Quest)&lt;br /&gt;
    dialog:AddTextField(&amp;quot;DInput&amp;quot;, DefaltPath )&lt;br /&gt;
    dialog:AddDirectoryPicker(&amp;quot;DirectoryPicker&amp;quot;,  &amp;quot;DInput&amp;quot;,  true)&lt;br /&gt;
    if not dialog:ShowDialog() then&lt;br /&gt;
      return &amp;quot;&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      return dialog:GetTextField(&amp;quot;DInput&amp;quot;)&lt;br /&gt;
    end -- if end&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===InquiryAreYouSureYesNo===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function InquiryAreYouSureYesNo(Header, Question1, Question2)&lt;br /&gt;
 --[[&lt;br /&gt;
     Drop list for user to input project info&lt;br /&gt;
     Caller = local y = InquiryAreYouSureYesNo(&amp;quot;Pie Question&amp;quot;, &amp;quot;Do you want free pie&amp;quot;)&lt;br /&gt;
     Dialog Header = &amp;quot;Pie Question&amp;quot;&lt;br /&gt;
     User Question1 = &amp;quot;Do you want a Free Pie&amp;quot;&lt;br /&gt;
     User Question2 = &amp;quot;You only get one&amp;quot;&lt;br /&gt;
     Returns = true / false&lt;br /&gt;
   ]]&lt;br /&gt;
    local myHtml = [[ &amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Yes or No Question&amp;lt;/title&amp;gt;]] .. DialogWindow.Style ..[[&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; class=&amp;quot;h2-lw&amp;quot; id=&amp;quot;Question1&amp;quot;&amp;gt;Question1&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; class=&amp;quot;h2-lw&amp;quot; id=&amp;quot;Question2&amp;quot;&amp;gt;Question2&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;h2-l&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; class=&amp;quot;h2-l&amp;quot;&amp;gt;Are you sure?&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;h2-l&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot;&amp;gt;&amp;lt;h2&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/h2&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
   &amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;h1-l&amp;quot;&amp;gt;&amp;lt;input id=&amp;quot;ButtonOK&amp;quot; class=&amp;quot;FormButton FormBut&amp;quot; name=&amp;quot;ButtonOK&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;  Yes  &amp;quot;&amp;gt; &amp;lt;/td&amp;gt; &amp;lt;td class=&amp;quot;h1-r&amp;quot;&amp;gt; &amp;lt;input id=&amp;quot;ButtonCancel&amp;quot; class=&amp;quot;FormButton FormBut&amp;quot; name=&amp;quot;ButtonCancel&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;  No  &amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;]]&lt;br /&gt;
-- =========================================================&lt;br /&gt;
    local dialog = HTML_Dialog(true, myHtml, 440, 218, Header)&lt;br /&gt;
    dialog:AddLabelField(&amp;quot;Question1&amp;quot;, Question1)&lt;br /&gt;
    dialog:AddLabelField(&amp;quot;Question2&amp;quot;, Question2)&lt;br /&gt;
    if not dialog:ShowDialog() then&lt;br /&gt;
      return false&lt;br /&gt;
    else&lt;br /&gt;
      return true&lt;br /&gt;
    end&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===InquiryDoubleBox===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function InquiryDoubleBox(Header, Quest, DefaltN)&lt;br /&gt;
--[[&lt;br /&gt;
-- nquiryNumberBox for user input with default number value&lt;br /&gt;
-- Caller: local x = InquiryNumberBox(&amp;quot;Cabinet Maker&amp;quot;, &amp;quot;Enter the cabinet height&amp;quot;, 30.0)&lt;br /&gt;
-- Dialog Header: &amp;quot;Cabinet Maker&amp;quot;&lt;br /&gt;
-- User Question: &amp;quot;Enter the cabinet height&amp;quot;&lt;br /&gt;
-- Default value = 30.0&lt;br /&gt;
-- Returns = double&lt;br /&gt;
]]&lt;br /&gt;
   local myHtml = [[&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Get Double Value&amp;lt;/title&amp;gt;&amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;html{overflow:hidden}body{background-color:#ebebeb;overflow:hidden;font-family:Arial,Helvetica,sans-serif;font-size:12px;text:#000}.h1-l{font-family:Arial,Helvetica,sans-serif;font-size:12px;font-weight:700;text-align:left;white-space:nowrap}.h1-r{font-family:Arial,Helvetica,sans-serif;font-size:12px;font-weight:700;text-align:right;white-space:nowrap}.h1-c{font-family:Arial,Helvetica,sans-serif;font-size:12px;font-weight:700;text-align:center;white-space:nowrap}table{width:100%;border:0;cellpadding:0}.FilePicker{font-weight:700;font-family:Arial,Helvetica,sans-serif;font-size:12px;width:50px}.FormButton{font-weight:700;width:65px;font-family:Arial,Helvetica,sans-serif;font-size:12px}&amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td id=&amp;quot;QuestionID&amp;quot; class=&amp;quot;h1-r&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Message Here&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;NumberInput&amp;quot; size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;2&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr class=&amp;quot;h1-c&amp;quot;&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input id=&amp;quot;ButtonCancel&amp;quot; class=&amp;quot;FormButton&amp;quot; name=&amp;quot;ButtonCancel&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;Cancel&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input id=&amp;quot;ButtonOK&amp;quot; class=&amp;quot;FormButton&amp;quot; name=&amp;quot;ButtonOK&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;OK&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;]]&lt;br /&gt;
   local dialog = HTML_Dialog(true, myHtml, 260, 125, Header)&lt;br /&gt;
   dialog:AddLabelField(&amp;quot;QuestionID&amp;quot;, Quest) ;&lt;br /&gt;
   dialog:AddDoubleField(&amp;quot;NumberInput&amp;quot;, DefaltN) ;&lt;br /&gt;
  if not dialog:ShowDialog() then&lt;br /&gt;
    return -1&lt;br /&gt;
  else&lt;br /&gt;
    return dialog:GetDoubleField(&amp;quot;NumberInput&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===InquiryIntegerBox===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function InquiryIntegerBox(Header, Quest, DefaltI)&lt;br /&gt;
--[[&lt;br /&gt;
-- InquiryIntegerBox for user input with default number value&lt;br /&gt;
-- Caller: local x = InquiryIntegerBox(&amp;quot;Cabinet Maker&amp;quot;, &amp;quot;Enter the door count&amp;quot;, 4)&lt;br /&gt;
-- Dialog Header: &amp;quot;Cabinet Maker&amp;quot;&lt;br /&gt;
-- User Question: &amp;quot;Enter the door count&amp;quot;&lt;br /&gt;
-- Default value = 4&lt;br /&gt;
-- Returns = integer&lt;br /&gt;
]]&lt;br /&gt;
   local myHtml = [[&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Get Integer&amp;lt;/title&amp;gt;&amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;html{overflow:auto}body{background-color:#ebebeb}table{width:100%;border:0}body,td,th{font-family:Arial,Helvetica,sans-serif;font-size:12px;color:#000}.FormButton{font-weight:700;width:85px;font-family:Arial,Helvetica,sans-serif;font-size:12px}body{background-color:#ebebeb;text:#000}&amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td id=&amp;quot;QuestionID&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Message Here&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;IntegerInput&amp;quot; size=&amp;quot;10&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;2&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input id=&amp;quot;ButtonCancel&amp;quot; class=&amp;quot;FormButton&amp;quot; name=&amp;quot;ButtonCancel&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;Cancel&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input id=&amp;quot;ButtonOK&amp;quot; class=&amp;quot;FormButton&amp;quot; name=&amp;quot;ButtonOK&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;OK&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;]]&lt;br /&gt;
   local dialog = HTML_Dialog(true, myHtml, 505, 140, Header)&lt;br /&gt;
   dialog:AddLabelField(&amp;quot;QuestionID&amp;quot;, Quest)&lt;br /&gt;
   dialog:AddIntegerField(&amp;quot;IntegerInput&amp;quot;, DefaltI)&lt;br /&gt;
  if not dialog:ShowDialog() then&lt;br /&gt;
    return -1&lt;br /&gt;
  else&lt;br /&gt;
    return dialog:GetIntegerField(&amp;quot;IntegerInput&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===InquiryTextgBox===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function InquiryTextgBox(Header, Quest, DefaltS)&lt;br /&gt;
--[[&lt;br /&gt;
-- InquiryStringBox for user input with default number value&lt;br /&gt;
-- Caller: local x = InquiryTextgBox(&amp;quot;Cabinet Maker&amp;quot;, &amp;quot;Enter the cabinet Name&amp;quot;, &amp;quot;Jim&amp;quot;)&lt;br /&gt;
-- Dialog Header: &amp;quot;Cabinet Maker&amp;quot;&lt;br /&gt;
-- User Question: &amp;quot;Enter the cabinet Name&amp;quot;&lt;br /&gt;
-- Default value = Jim&lt;br /&gt;
-- Returns = string&lt;br /&gt;
]]&lt;br /&gt;
   local myHtml = [[&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Get Number&amp;lt;/title&amp;gt;&amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;html{overflow:auto}body{background-color:#ebebeb}table{width:100%;border:0}body,td,th{font-family:Arial,Helvetica,sans-serif;font-size:12px;color:#000}.FormButton{font-weight:700;width:85px;font-family:Arial,Helvetica,sans-serif;font-size:12px}body{background-color:#ebebeb;text:#000}&amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td id=&amp;quot;QuestionID&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Message Here&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;StringInput&amp;quot; size=&amp;quot;10&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;2&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input id=&amp;quot;ButtonCancel&amp;quot; class=&amp;quot;FormButton&amp;quot; name=&amp;quot;ButtonCancel&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;Cancel&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input id=&amp;quot;ButtonOK&amp;quot; class=&amp;quot;FormButton&amp;quot; name=&amp;quot;ButtonOK&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;OK&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;]]&lt;br /&gt;
   local dialog = HTML_Dialog(true, myHtml, 505, 140, Header)&lt;br /&gt;
   dialog:AddLabelField(&amp;quot;QuestionID&amp;quot;, Quest)&lt;br /&gt;
   dialog:AddTextField(&amp;quot;StringInput&amp;quot;, DefaltS)&lt;br /&gt;
  if not dialog:ShowDialog() then&lt;br /&gt;
    return -1&lt;br /&gt;
  else&lt;br /&gt;
    return dialog:GetTextField(&amp;quot;NumberInput&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===OnLuaButton_InquiryError===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function OnLuaButton_InquiryError(Message)&lt;br /&gt;
    --[[&lt;br /&gt;
     Provides user information on an Error&lt;br /&gt;
     Caller = local ItWorked = OnLuaButton_InquiryError(&amp;quot;No number found&amp;quot;)&lt;br /&gt;
     Dialog Header = &amp;quot;Something Error&amp;quot;&lt;br /&gt;
     User Message = &amp;quot;No Number etc...&amp;quot;&lt;br /&gt;
     Returns = True&lt;br /&gt;
   ]]&lt;br /&gt;
  local myHtml = [[&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Error&amp;lt;/title&amp;gt;&amp;lt;style type = &amp;quot;text/css&amp;quot;&amp;gt;.FormButton{font-weight:bold;width:75px;font-family:Arial,Helvetica,sans-serif;font-size:12px;white-space:nowrap}.Error{font-family:Arial,Helvetica,sans-serif;font-size:18px;font-weight:bold;color:#F00;text-align:left;white-space:nowrap;padding-right:4px;padding-left:10px;padding-top:4px;padding-bottom:4px}.ErrorMessage{font-family:Arial,Helvetica,sans-serif;font-size:12px;color:#000;font-weight:bold;text-align:left;white-space:nowrap;padding-right:4px;padding-left:10px;padding-top:4px;padding-bottom:4px}.ErrorTable{background-color:#FFF white-space:nowrap}html{overflow:hidden}&amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body text = &amp;quot;#000000&amp;quot;&amp;gt;&amp;lt;table width=&amp;quot;100%&amp;quot; border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;0&amp;quot; class=&amp;quot;ErrorTable&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;th align=&amp;quot;center&amp;quot; nowrap=&amp;quot;nowrap&amp;quot; class=&amp;quot;Error&amp;quot;&amp;gt;Error!&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td id=&amp;quot;ErrorMessage&amp;quot;&amp;gt;&amp;lt;label class=&amp;quot;ErrorMessage&amp;quot;&amp;gt;-&amp;lt;/label&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&amp;quot;30%&amp;quot; align=&amp;quot;right&amp;quot; style = &amp;quot;width: 15%&amp;quot;&amp;gt;&amp;lt;input id = &amp;quot;ButtonOK&amp;quot; class = &amp;quot;FormButton&amp;quot; name = &amp;quot;ButtonOK&amp;quot; type = &amp;quot;button&amp;quot; value = &amp;quot;Exit&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;]]&lt;br /&gt;
  local dialogWide =  (#Message + 300)&lt;br /&gt;
  local dialog = HTML_Dialog(true, myHtml, 250, dialogWide, &amp;quot;Gadget Error&amp;quot;)&lt;br /&gt;
  dialog:AddLabelField(&amp;quot;ErrorMessage&amp;quot;,   Message)&lt;br /&gt;
  dialog:ShowDialog()&lt;br /&gt;
  Dovetail.InquiryErrorX = Dialog.WindowWidth&lt;br /&gt;
  Dovetail.InquiryErrorY = Dialog.WindowHeight&lt;br /&gt;
  WriteRegistry()&lt;br /&gt;
  return  true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===PresentMessage===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function PresentMessage(Header, Type, Line)&lt;br /&gt;
    --[[&lt;br /&gt;
     Provides user information on an Error&lt;br /&gt;
     Caller = local ItWorked = OnLuaButton_InquiryError(&amp;quot;No number found&amp;quot;)&lt;br /&gt;
     Dialog Header = &amp;quot;Something Error&amp;quot;&lt;br /&gt;
     User Message = &amp;quot;No Number etc...&amp;quot;&lt;br /&gt;
     Returns = True&lt;br /&gt;
   ]]&lt;br /&gt;
  local myHtml = [[&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Error&amp;lt;/title&amp;gt;]] .. DialogWindow.Style ..[[&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;th valign=&amp;quot;top&amp;quot; id=&amp;quot;MessageType&amp;quot; class=&amp;quot;Error&amp;quot;&amp;gt;-&amp;lt;/th&amp;gt;&amp;lt;td id=&amp;quot;MessageLine&amp;quot;&amp;gt;&amp;lt;label class=&amp;quot;ErrorMessage&amp;quot;&amp;gt;-&amp;lt;/label&amp;gt;&amp;lt;td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;input id = &amp;quot;ButtonOK&amp;quot; class = &amp;quot;FormButton&amp;quot; name = &amp;quot;ButtonOK&amp;quot; type = &amp;quot;button&amp;quot; value = &amp;quot;OK&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;]]&lt;br /&gt;
  local dialog = HTML_Dialog(true, myHtml, 500, 150, Header)&lt;br /&gt;
  dialog:AddLabelField(&amp;quot;MessageType&amp;quot;, Type .. &amp;quot;: &amp;quot;)&lt;br /&gt;
  dialog:AddLabelField(&amp;quot;MessageLine&amp;quot;, Line)&lt;br /&gt;
  dialog:ShowDialog()&lt;br /&gt;
  return  true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===OnLuaButton_InquiryAbout===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function OnLuaButton_InquiryAbout()&lt;br /&gt;
local myHtml = [[&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;About&amp;lt;/title&amp;gt;]] .. DialogWindow.Style ..[[&amp;lt;/head&amp;gt;&amp;lt;body text = &amp;quot;#000000&amp;quot;&amp;gt;&amp;lt;table width=&amp;quot;680&amp;quot; border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;0&amp;quot;&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td align=&amp;quot;center&amp;quot; nowrap=&amp;quot;nowrap&amp;quot; class=&amp;quot;header1-c&amp;quot; id=&amp;quot;SysName&amp;quot;&amp;gt;Easy Cabinet Maker&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td align=&amp;quot;center&amp;quot; nowrap=&amp;quot;nowrap&amp;quot; id=&amp;quot;Version&amp;quot; class=&amp;quot;ver-c&amp;quot;&amp;gt;Version&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td align=&amp;quot;center&amp;quot; nowrap=&amp;quot;nowrap&amp;quot;&amp;gt;&amp;lt;hr&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td align=&amp;quot;center&amp;quot; nowrap=&amp;quot;nowrap&amp;quot; class=&amp;quot;header2-c&amp;quot;&amp;gt;Disclaimer&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td align=&amp;quot;center&amp;quot; class=&amp;quot;p1-l&amp;quot;&amp;gt;&amp;lt;p class=&amp;quot;p1-l&amp;quot;&amp;gt;The ]] .. Dovetail.AppName .. [[ Gadget is a plugin for Vectric software, V-Carve Pro and Aspire.&amp;lt;br&amp;gt; Gadgets are an entirely optional add-in to Vectric's core software products.&amp;lt;br&amp;gt; They are provided 'as-is', without any express or implied warranty, and you make use of them entirely at your own risk.&amp;lt;br&amp;gt; In no event will the author(s) or Vectric Ltd. be held liable for any damages arising from their use.&amp;lt;br&amp;gt; &amp;lt;br&amp;gt; Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:&amp;lt;br&amp;gt; 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.&amp;lt;br&amp;gt; * If you use this software in a product, an acknowledgement in the product documentation would be appreciated but is not required.&amp;lt;br&amp;gt; 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.&amp;lt;br&amp;gt; 3. This notice may not be removed or altered from any source distribution.&amp;lt;br&amp;gt; &amp;lt;br&amp;gt;The author heavily utilized the SDK documentation and supplied code samples in addition to the outstanding user community on the Vectric User forum.&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;https://forum.vectric.com&amp;quot; class=&amp;quot;webLink-c&amp;quot;&amp;gt;Vectric User Forum&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;header2-c&amp;quot;&amp;gt;JimAndi&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;h1-c&amp;quot;&amp;gt;Houston, TX.&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td&amp;gt;&amp;lt;hr&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td width=&amp;quot;30%&amp;quot; align=&amp;quot;center&amp;quot; style = &amp;quot;width: 15%&amp;quot;&amp;gt;&amp;lt;input id = &amp;quot;ButtonOK&amp;quot; class = &amp;quot;FormButton&amp;quot; name = &amp;quot;ButtonOK&amp;quot; type = &amp;quot;button&amp;quot; value = &amp;quot;OK&amp;quot;&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;]]&lt;br /&gt;
  local dialog = HTML_Dialog(true, myHtml, 720, 468, &amp;quot;About&amp;quot;)&lt;br /&gt;
  dialog:AddLabelField(&amp;quot;SysName&amp;quot;, Project.ProgramName)&lt;br /&gt;
  dialog:AddLabelField(&amp;quot;Version&amp;quot;, &amp;quot;Version: &amp;quot; .. Project.ProgramVersion)&lt;br /&gt;
  dialog:ShowDialog()&lt;br /&gt;
  Project.AboutXY = tostring(dialog.WindowWidth) .. &amp;quot; x &amp;quot; .. tostring(dialog.WindowHeight)&lt;br /&gt;
  return  true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Color_HTML ===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function Color_HTML ()&lt;br /&gt;
  MessageBox(&amp;quot; X = &amp;quot; .. tostring(dialog.WindowWidth) ..&lt;br /&gt;
             &amp;quot; Y = &amp;quot; .. tostring(dialog.WindowHeight)&lt;br /&gt;
 )&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
--[[ -- begin HTML for Layer Color&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td width=&amp;quot;200&amp;quot; align=&amp;quot;right&amp;quot; valign=&amp;quot;middle&amp;quot; nowrap class=&amp;quot;h1-rp&amp;quot;&amp;gt;Layer Name&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td width=&amp;quot;300&amp;quot; align=&amp;quot;right&amp;quot; valign=&amp;quot;middle&amp;quot; nowrap class=&amp;quot;h1-l&amp;quot; id=&amp;quot;ValueTable&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;input name=&amp;quot;Panel.PinHole&amp;quot; type=&amp;quot;text&amp;quot; class=&amp;quot;h1-l&amp;quot; id=&amp;quot;Panel.PinHole&amp;quot; size=&amp;quot;50&amp;quot; maxlength=&amp;quot;50&amp;quot;/&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td width=&amp;quot;150&amp;quot;align=&amp;quot;right&amp;quot; valign=&amp;quot;middle&amp;quot; nowrap class=&amp;quot;h1-l&amp;quot;&amp;gt;&amp;lt;label for=&amp;quot;Panel.LineColor01&amp;quot;&amp;gt;Color&amp;lt;/label&amp;gt;&lt;br /&gt;
      &amp;lt;select name=&amp;quot;Panel.LineColor01&amp;quot; id=&amp;quot;Panel.LineColor01&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;option selected=&amp;quot;selected&amp;quot;&amp;gt;Black&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Blue&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Brown&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Cyan&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Gray&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Green&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Lime&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Magenta&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Maroon&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Navy&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Olive&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Orange&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Purple&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Red&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Silver&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Teal&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;White&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Yellow&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;table width=&amp;quot;101%&amp;quot; border=&amp;quot;0&amp;quot; id=&amp;quot;ButtonTable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
]] -- end HTML&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Style===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function Style()&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
DialogWindow.Style = [[ &amp;lt;style&amp;gt;&lt;br /&gt;
.DirectoryPicker {&lt;br /&gt;
  font-weight: bold;&lt;br /&gt;
  font-size: 12px;&lt;br /&gt;
  white-space: nowrap;&lt;br /&gt;
  background-color: #663300;&lt;br /&gt;
  color: #FFFFFF;&lt;br /&gt;
}&lt;br /&gt;
.FormButton {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	width: 75px;&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	background-color: #663300;&lt;br /&gt;
	color: #FFFFFF;&lt;br /&gt;
}&lt;br /&gt;
.FormButton-Help {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	width: 75px;&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	background-color: #663300;&lt;br /&gt;
	color: #FFFFFF;&lt;br /&gt;
	padding-left: 10;&lt;br /&gt;
	padding-right: 10;&lt;br /&gt;
}&lt;br /&gt;
.LuaButton {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	background-color: #663300;&lt;br /&gt;
	color: #FFFFFF;&lt;br /&gt;
}&lt;br /&gt;
.ToolNameLabel {&lt;br /&gt;
	font-weight: bolder;&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	text-align: left;&lt;br /&gt;
	color: #000;&lt;br /&gt;
	width: 70%;&lt;br /&gt;
}&lt;br /&gt;
.ToolPicker {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	width: 50px;&lt;br /&gt;
	background-color: #663300;&lt;br /&gt;
	color: #FFFFFF;&lt;br /&gt;
}&lt;br /&gt;
.alert-c {&lt;br /&gt;
	font-size: 14px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.alert-l {&lt;br /&gt;
	font-size: 14px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-shadow: 5px 5px 10px #FFF;&lt;br /&gt;
	text-align: left;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.alert-r {&lt;br /&gt;
	font-size: 14px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: right;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.error {&lt;br /&gt;
	font-size: 18px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	color: #FF0000;&lt;br /&gt;
	text-align: left;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	padding-right: 4px;&lt;br /&gt;
	padding-left: 10px;&lt;br /&gt;
	padding-top: 4px;&lt;br /&gt;
	padding-bottom: 4px;&lt;br /&gt;
}&lt;br /&gt;
.errorMessage {&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	color: #000;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: left;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	padding-right: 4px;&lt;br /&gt;
	padding-left: 10px;&lt;br /&gt;
	padding-top: 4px;&lt;br /&gt;
	padding-bottom: 4px;&lt;br /&gt;
}&lt;br /&gt;
.errorTable {&lt;br /&gt;
	background-color: #FFFFFF;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.p1-l {&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
.h1-c {&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.h1-cOk {&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	width: 15%;&lt;br /&gt;
}&lt;br /&gt;
.h1-l {&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: left;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.h1-r {&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: right;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.h1-rP {&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: right;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	padding-right: 4px;&lt;br /&gt;
	padding-left: 4px;&lt;br /&gt;
}&lt;br /&gt;
.h1-rPx {&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: right;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	padding-right: 8px;&lt;br /&gt;
	padding-left: 8px;&lt;br /&gt;
}&lt;br /&gt;
.h2-c {&lt;br /&gt;
	font-size: 14px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	text-shadow: 2px 2px white;&lt;br /&gt;
}&lt;br /&gt;
.h2-l {&lt;br /&gt;
	font-size: 14px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	color: #663300;&lt;br /&gt;
	text-align: left;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	text-shadow: 2px 2px white;&lt;br /&gt;
}&lt;br /&gt;
.h2-r {&lt;br /&gt;
	font-size: 14px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	color: #663300;&lt;br /&gt;
	text-align: right;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	text-shadow: 2px 2px white;&lt;br /&gt;
}&lt;br /&gt;
.h3-bc {&lt;br /&gt;
	font-size: 16px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.h3-c {&lt;br /&gt;
	font-size: 16px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.h3-l {&lt;br /&gt;
	font-size: 16px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: left;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.h3-r {&lt;br /&gt;
	font-size: 16px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: right;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.h4-c {&lt;br /&gt;
	font-size: 18px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.h4-l {&lt;br /&gt;
	font-size: 18px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: left;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.h4-r {&lt;br /&gt;
	font-size: 18px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: right;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.help_But {&lt;br /&gt;
	width: 45px;&lt;br /&gt;
}&lt;br /&gt;
.MyCenter{&lt;br /&gt;
	text-align:center;&lt;br /&gt;
	width:10;&lt;br /&gt;
}&lt;br /&gt;
.MyLeft{&lt;br /&gt;
	text-align:left;&lt;br /&gt;
	width:10;&lt;br /&gt;
}&lt;br /&gt;
.MyRight{&lt;br /&gt;
	text-align:right;&lt;br /&gt;
	width:10;&lt;br /&gt;
}&lt;br /&gt;
.helplabel-r {&lt;br /&gt;
	cursor: pointer;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	text-align: right;&lt;br /&gt;
}&lt;br /&gt;
.helplabel-rp {&lt;br /&gt;
	cursor: pointer;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	text-align: right;&lt;br /&gt;
	padding-right: 8px;&lt;br /&gt;
}&lt;br /&gt;
.jsTag-no-vis {&lt;br /&gt;
	font-size: 10px;&lt;br /&gt;
	display: none;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	color: #00F;&lt;br /&gt;
	visibility: hidden;&lt;br /&gt;
}&lt;br /&gt;
.jsbutton {&lt;br /&gt;
	background-color: #663300;&lt;br /&gt;
	border: 2px solid #999;&lt;br /&gt;
	border-right-color: #000;&lt;br /&gt;
	border-bottom-color: #000;&lt;br /&gt;
	border-top-color: #FFF;&lt;br /&gt;
	border-left-color: #FFF;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	text-decoration: none;&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	margin: 1px 1px;&lt;br /&gt;
	color: #FFFFFF;&lt;br /&gt;
}&lt;br /&gt;
.p1-c {&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.p1-r {&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	text-align: right;&lt;br /&gt;
}&lt;br /&gt;
.ver-c {&lt;br /&gt;
	font-size: 10px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	color: #ffd9b3;&lt;br /&gt;
}&lt;br /&gt;
.webLink-c {&lt;br /&gt;
	font-size: 16px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	background-color: yellow;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
body {&lt;br /&gt;
	background-color: #3a4660;&lt;br /&gt;
	background-position: center;&lt;br /&gt;
	overflow: hidden;&lt;br /&gt;
	font-family: arial, helvetica, sans-serif;&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	color: #FFFFFF;&lt;br /&gt;
	background-image: url(]].. DialogWindow.myBackGround ..[[);&lt;br /&gt;
}&lt;br /&gt;
html {&lt;br /&gt;
	overflow: hidden&lt;br /&gt;
}&lt;br /&gt;
table {&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	border: 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;]]&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Orgin===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function Orgin()                                       -- Anchor Point&lt;br /&gt;
-- ================================&lt;br /&gt;
  DialogWindow.Orgin = [[&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;2&amp;quot; class=&amp;quot;h2-l&amp;quot;&amp;gt;Anchor Point&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr class=&amp;quot;MyLeft&amp;quot;&amp;gt;&amp;lt;td class=&amp;quot;MyLeft&amp;quot;&amp;gt;&amp;lt;table class=&amp;quot;MyCenter&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;DrawingOrigin&amp;quot; checked=&amp;quot;checked&amp;quot; value=&amp;quot;V1&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;hr&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;DrawingOrigin&amp;quot; checked=&amp;quot;checked&amp;quot; value=&amp;quot;V2&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;auto-style9&amp;quot;&amp;gt;|&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;DrawingOrigin&amp;quot; checked=&amp;quot;checked&amp;quot; value=&amp;quot;V3&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;|&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;DrawingOrigin&amp;quot; checked=&amp;quot;checked&amp;quot; value=&amp;quot;V4&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;hr&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;DrawingOrigin&amp;quot; checked=&amp;quot;checked&amp;quot; value=&amp;quot;V5&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&amp;quot;81%&amp;quot;&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr class=&amp;quot;MyLeft&amp;quot;&amp;gt;&amp;lt;td&amp;gt;X&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input name=&amp;quot;OriginX0&amp;quot; type=&amp;quot;text&amp;quot; id=&amp;quot;OriginX&amp;quot; size=&amp;quot;8&amp;quot; maxlength=&amp;quot;8&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr class=&amp;quot;MyLeft&amp;quot;&amp;gt;&amp;lt;td&amp;gt;Y&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input name=&amp;quot;OriginY0&amp;quot; type=&amp;quot;text&amp;quot; id=&amp;quot;OriginY&amp;quot; size=&amp;quot;8&amp;quot; maxlength=&amp;quot;8&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;]]&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===GetColor===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function GetColor(str)                                  -- returns the RGB value for the standard color names&lt;br /&gt;
-- str = &amp;quot;Purple&amp;quot;&lt;br /&gt;
-- returns = 128 0 128&lt;br /&gt;
    local Colors = {}&lt;br /&gt;
    Colors.Black  = &amp;quot;0,0,0&amp;quot;;       Colors.White  = &amp;quot;255,255,255&amp;quot;; Colors.Red    = &amp;quot;255,0,0&amp;quot;&lt;br /&gt;
    Colors.Lime   = &amp;quot;0,255,0&amp;quot;;     Colors.Blue   = &amp;quot;0,0,255&amp;quot;;     Colors.Yellow = &amp;quot;255,255,0&amp;quot;&lt;br /&gt;
    Colors.Cyan   = &amp;quot;0,255,255&amp;quot;;   Colors.Magenta = &amp;quot;255,0,255&amp;quot;;  Colors.Silver = &amp;quot;192,192,192&amp;quot;&lt;br /&gt;
    Colors.Gray   = &amp;quot;128,128,128&amp;quot;; Colors.Maroon = &amp;quot;128,0,0&amp;quot;;     Colors.Olive  = &amp;quot;128,128,0&amp;quot;&lt;br /&gt;
    Colors.Green  = &amp;quot;0,128,0&amp;quot;;     Colors.Purple = &amp;quot;128,0,128&amp;quot;;   Colors.Teal   = &amp;quot;0,128,128&amp;quot;&lt;br /&gt;
    Colors.Navy   = &amp;quot;0,0,128&amp;quot;&lt;br /&gt;
    local Red, Green, Blue = 0&lt;br /&gt;
    if &amp;quot;&amp;quot; == str then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error: Empty string passed&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      str = Colors[str]&lt;br /&gt;
      if &amp;quot;string&amp;quot; == type(str) then&lt;br /&gt;
        if string.find(str, &amp;quot;,&amp;quot;) then&lt;br /&gt;
          Red  = tonumber(string.sub(str, 1, assert(string.find(str, &amp;quot;,&amp;quot;) - 1)))&lt;br /&gt;
          str = string.sub(str, assert(string.find(str, &amp;quot;,&amp;quot;) + 1))&lt;br /&gt;
          Green = tonumber(string.sub(str, 1, assert(string.find(str, &amp;quot;,&amp;quot;) - 1)))&lt;br /&gt;
          Blue = tonumber(string.sub(str, assert(string.find(str, &amp;quot;,&amp;quot;) + 1)))&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        DisplayMessageBox(&amp;quot;Error: Color Not Found&amp;quot;)&lt;br /&gt;
        Red = 0&lt;br /&gt;
        Green = 0&lt;br /&gt;
        Blue = 0&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    return Red, Green, Blue&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===StatusMessage===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function StatusMessage(Type, Header, Question, length) -- Standardize messaging dialogues&lt;br /&gt;
  -- StatusMessage(&amp;quot;Alert&amp;quot;,    &amp;quot;Alert Test&amp;quot;,     &amp;quot;This is a test of Alert&amp;quot;,    165)&lt;br /&gt;
  -- StatusMessage(&amp;quot;Question&amp;quot;, &amp;quot;Question Test&amp;quot;,  &amp;quot;This is a test of Question&amp;quot;, 165)&lt;br /&gt;
  -- StatusMessage(&amp;quot;Tick&amp;quot;,     &amp;quot;Tick Test&amp;quot;,      &amp;quot;This is a test of Tick&amp;quot;,     165)&lt;br /&gt;
  -- StatusMessage(&amp;quot;Minus&amp;quot;,    &amp;quot;Minus Test&amp;quot;,     &amp;quot;This is a test of Minus&amp;quot;,    165)&lt;br /&gt;
  -- StatusMessage(&amp;quot;Error&amp;quot;,    &amp;quot;Error Test&amp;quot;,     &amp;quot;This is a test of Error&amp;quot;,    165)&lt;br /&gt;
  -- StatusMessage(&amp;quot;Success&amp;quot;,  &amp;quot;Success Test&amp;quot;,   &amp;quot;This is a test of Success&amp;quot;,  165)&lt;br /&gt;
  -- StatusMessage(&amp;quot;Blank&amp;quot;,    &amp;quot;Blank Test&amp;quot;,     &amp;quot;This is a test of Blank&amp;quot;,    165)&lt;br /&gt;
  local Image = &amp;quot;&amp;quot;&lt;br /&gt;
  if     Type == &amp;quot;Alert&amp;quot; then&lt;br /&gt;
    Image = AlertImage()&lt;br /&gt;
  elseif Type == &amp;quot;Question&amp;quot; then&lt;br /&gt;
    Image = QuestionImage()&lt;br /&gt;
  elseif Type == &amp;quot;Tick&amp;quot; then&lt;br /&gt;
    Image = TickImage()&lt;br /&gt;
  elseif Type == &amp;quot;Minus&amp;quot; then&lt;br /&gt;
    Image = MinusImage()&lt;br /&gt;
  elseif Type == &amp;quot;Error&amp;quot; then&lt;br /&gt;
    Image = ErrorImage()&lt;br /&gt;
  elseif Type == &amp;quot;Success&amp;quot; then&lt;br /&gt;
    Image = SuccessImage()&lt;br /&gt;
  else -- &amp;quot;Status&amp;quot;&lt;br /&gt;
    Image = TickImage()&lt;br /&gt;
  end -- if end&lt;br /&gt;
  local help = [[&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;]] .. Header ..[[&amp;lt;/title&amp;gt;&amp;lt;style&amp;gt;&lt;br /&gt;
.FormButton {font-family: Arial, Helvetica, sans-serif;font-weight: bold;font-size: 12px;white-space: nowrap;background-color: #663300;color: #FFFFFF;width: 75px;&lt;br /&gt;
}table {width: 100%;border: 0;}.h2-lm {font-family: Arial, Helvetica, sans-serif;font-size: 14px;font-weight: bold;text-align: left;}.h2-r {font-family: Arial, Helvetica, sans-serif;font-size: 14px;font-weight: bold;text-align: right;white-space: nowrap;}.h2-l {font-family: Arial, Helvetica, sans-serif;font-size: 14px;font-weight: bold;text-align: left;white-space: nowrap;}body {background-color: #3a4660;background-position: center;overflow: hidden;font-family: arial, helvetica, sans-serif;font-size: 12px;color: #FFFFFF;background-image: url(]] .. myBackGround() .. [[);}html {overflow: hidden}&amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;table&amp;gt; &amp;lt;tr&amp;gt;  &amp;lt;td class=&amp;quot;h2-l&amp;quot;&amp;gt;&amp;lt;]] .. Image .. [[&amp;quot; width=&amp;quot;60&amp;quot; height=&amp;quot;60&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td class=&amp;quot;h2-lm&amp;quot; id=&amp;quot;Question&amp;quot;&amp;gt;]] .. Question .. [[&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td colspan=2&amp;gt;&amp;lt;h2&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/h2&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;h2-r&amp;quot;&amp;gt;&amp;lt;input id=&amp;quot;ButtonOK&amp;quot; class=&amp;quot;FormButton&amp;quot; name=&amp;quot;ButtonOK&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;OK&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;]]&lt;br /&gt;
  local dialog = HTML_Dialog(true, help , 550,  length, Header)&lt;br /&gt;
  dialog:ShowDialog()&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===DialogStringChecks===&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DialogStringChecks()&lt;br /&gt;
  local MyTrue = false&lt;br /&gt;
  if Milling.LNBottomProfile == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Bottom Profile layer name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryLayers()&lt;br /&gt;
  elseif  Milling.LNSideProfile  == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Side Profile layer name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryLayers()&lt;br /&gt;
  elseif  Milling.LNSidePocket  == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Side Pocket layer name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryLayers()&lt;br /&gt;
  elseif Milling.LNFrontProfile == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Front Profile layer name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryLayers()&lt;br /&gt;
  elseif Milling.LNFrontPocket  == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Front Pocket layer name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryLayers()&lt;br /&gt;
  elseif Milling.LNBackProfile  == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Back Profile layer name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryLayers()&lt;br /&gt;
  elseif Milling.LNBackPocket == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Back Pocket layer name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryLayers()&lt;br /&gt;
  elseif Milling.LNDrawNotes == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Draw Notes layer name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryLayers()&lt;br /&gt;
  elseif Milling.LNPartLabels == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Part Lables layer name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryLayers()&lt;br /&gt;
  elseif Milling.LNBlume == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Blume layer name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryLayers()&lt;br /&gt;
  elseif Project.ProjectName == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Project Name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryProjectInfo()&lt;br /&gt;
  elseif Project.ContactEmail  == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Contact Email cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryProjectInfo()&lt;br /&gt;
  elseif Project.ContactName == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Contact Name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryProjectInfo()&lt;br /&gt;
  elseif Project.ContactPhoneNumber == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Project Name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryProjectInfo()&lt;br /&gt;
  elseif Project.DrawerID == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Contact Phone Number cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryProjectInfo()&lt;br /&gt;
  elseif Project.ProjectPath == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Project Path cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryProjectInfo()&lt;br /&gt;
  else&lt;br /&gt;
    MyTrue = true&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return MyTrue&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Directory and File Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===MakeFolder()===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y values.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function MakeFolder(xPath)&lt;br /&gt;
    os.execute( &amp;quot;mkdir  &amp;quot; .. xPath)&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===PathFix()===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function PathFix(xPath)              -- Returns path with /&lt;br /&gt;
    return string.gsub(xPath, &amp;quot;\\&amp;quot;, &amp;quot;/&amp;quot;)&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===IsDir()===&lt;br /&gt;
&lt;br /&gt;
Validates a directory path&lt;br /&gt;
&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function IsDir(path)                     -- Returns true if path is found&lt;br /&gt;
    local function exists(file)&lt;br /&gt;
      local ok, err, code = os.rename(file, file)&lt;br /&gt;
      if not ok then&lt;br /&gt;
        if code == 13 then&lt;br /&gt;
          return true&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- if end&lt;br /&gt;
      return ok, err&lt;br /&gt;
    end -- function end&lt;br /&gt;
    return exists(path..&amp;quot;/&amp;quot;)&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===FileExists()===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y values.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function FileExists(name)&lt;br /&gt;
-- FileExists(name&lt;br /&gt;
-- DisplayMessageBox(name)&lt;br /&gt;
    local f=io.open(name,&amp;quot;r&amp;quot;)&lt;br /&gt;
    if f~=nil then&lt;br /&gt;
      io.close(f)&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DirectoryProcessor()===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
&lt;br /&gt;
Returns number of files that were processed by an operation.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function DirectoryProcessor(job, dir_name, filter, do_sub_dirs, function_ptr)&lt;br /&gt;
      local num_files_processed = 0&lt;br /&gt;
      local directory_reader = DirectoryReader()&lt;br /&gt;
      local cur_dir_reader = DirectoryReader()&lt;br /&gt;
      directory_reader:BuildDirectoryList(dir_name, do_sub_dirs)&lt;br /&gt;
      directory_reader:SortDirs()&lt;br /&gt;
      local number_of_directories = directory_reader:NumberOfDirs()&lt;br /&gt;
      for i = 1, number_of_directories do&lt;br /&gt;
        local cur_directory = directory_reader:DirAtIndex(i)&lt;br /&gt;
         -- get contents of current directory&lt;br /&gt;
         -- dont include sub dirs, use passed filter&lt;br /&gt;
        cur_dir_reader:BuildDirectoryList(cur_directory.Name, false)&lt;br /&gt;
        cur_dir_reader:GetFiles(filter, true, false)&lt;br /&gt;
         -- call passed method for each file:&lt;br /&gt;
        local num_files_in_dir = cur_dir_reader:NumberOfFiles()&lt;br /&gt;
        for j=1, num_files_in_dir  do&lt;br /&gt;
          local file_info = cur_dir_reader:FileAtIndex(j)&lt;br /&gt;
          if not function_ptr(job, file_info.Name) then&lt;br /&gt;
            return true&lt;br /&gt;
          end -- if end&lt;br /&gt;
           num_files_processed = num_files_processed + 1&lt;br /&gt;
        end -- for end&lt;br /&gt;
        -- empty out our directory object ready for next go&lt;br /&gt;
        cur_dir_reader:ClearDirs()&lt;br /&gt;
        cur_dir_reader:ClearFiles()&lt;br /&gt;
      end -- for end&lt;br /&gt;
      return num_files_processed&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Drawing Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DrawArrowLineArrow===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws a dimension line with arrow heads and extension leaders&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawArrowLineArrow(Pt1, Ext1, Pt2, Ext2, Off, Str, Layer, scale)&lt;br /&gt;
  -- DrawArrowLineArrow(pt1, true, pt3, true, 2.5, &amp;quot;122.5&amp;quot;, &amp;quot;TestLayer&amp;quot;, 6.0) -- both&lt;br /&gt;
  -- DrawArrowLineArrow(pt1, true, pt3, false, 2.5, &amp;quot;122.5&amp;quot;, &amp;quot;TestLayer&amp;quot;, 6.0) -- first leader only&lt;br /&gt;
  -- DrawArrowLineArrow(pt1, false, pt3, true, 2.5, &amp;quot;122.5&amp;quot;, &amp;quot;TestLayer&amp;quot;, 6.0) -- second leader only&lt;br /&gt;
  -- -----------------------------------------------------]]&lt;br /&gt;
    local job = VectricJob()&lt;br /&gt;
    if not job.Exists then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error: No job loaded&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    local DimArrow1Angle = GetPolarDirection(Pt1, Pt2, Polar2D(Pt2, 0.0, 1.0))&lt;br /&gt;
    local DimArrow2Angle = DimArrow1Angle + 180.0&lt;br /&gt;
    local LederAng       = DimArrow1Angle + 90.0&lt;br /&gt;
    local LedDrop        = LederAng + 180.0&lt;br /&gt;
    local TxtCenter      =  GetDistance(Pt1, Pt2) * 0.5&lt;br /&gt;
    local ArrowLen       = 0.125 * scale&lt;br /&gt;
    local StrSet         = (string.len(Str) * ArrowLen) * 0.5&lt;br /&gt;
    local PT01A          = Polar2D(Pt1, LederAng, ArrowLen * 2.0)&lt;br /&gt;
    local PT02A          = Polar2D(PT01A, LederAng, Off)&lt;br /&gt;
    local PT03A          = Polar2D(PT02A, LederAng, ArrowLen)&lt;br /&gt;
    local PT01B          = Polar2D(Pt2, LederAng, ArrowLen * 2.0)&lt;br /&gt;
    local PT02B          = Polar2D(PT01B, LederAng, Off)&lt;br /&gt;
    local PT03B          = Polar2D(PT02B, LederAng, ArrowLen)&lt;br /&gt;
    local Apt1           = Polar2D(PT02A, DimArrow1Angle + 15.0, ArrowLen)&lt;br /&gt;
    local Apt2           = Polar2D(PT02A, DimArrow1Angle - 15.0, ArrowLen)&lt;br /&gt;
    local TxtPt1         = Polar2D(Polar2D(PT02A, DimArrow1Angle, TxtCenter), DimArrow1Angle + 90.0, ArrowLen)&lt;br /&gt;
    local TxtPt          = Polar2D(TxtPt1, DimArrow2Angle, StrSet)&lt;br /&gt;
    local ArrowHead      = (ArrowLen * 0.333)&lt;br /&gt;
    local line1          = Contour(0.0)&lt;br /&gt;
    local layer1         = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
    line1:AppendPoint(Apt1)&lt;br /&gt;
    line1:LineTo(PT02A)&lt;br /&gt;
    line1:LineTo(Apt2)&lt;br /&gt;
    line1:LineTo(Apt1)&lt;br /&gt;
    layer1:AddObject(CreateCadContour(line1), true)&lt;br /&gt;
    local Apt3 = Polar2D(PT02B, DimArrow2Angle + 15.0, ArrowLen)&lt;br /&gt;
    local Apt4 = Polar2D(PT02B, DimArrow2Angle - 15.0, ArrowLen)&lt;br /&gt;
    local line2 = Contour(0.0)&lt;br /&gt;
    local layer2 = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
    line2:AppendPoint(Apt3)&lt;br /&gt;
    line2:LineTo(PT02B)&lt;br /&gt;
    line2:LineTo(Apt4)&lt;br /&gt;
    line2:LineTo(Apt3)&lt;br /&gt;
    layer2:AddObject(CreateCadContour(line2), true)&lt;br /&gt;
    if Ext1 then&lt;br /&gt;
      local lineA = Contour(0.0)&lt;br /&gt;
      local layerA = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
      lineA:AppendPoint(PT01A)&lt;br /&gt;
      lineA:LineTo(PT03A)&lt;br /&gt;
      layerA:AddObject(CreateCadContour(lineA), true)&lt;br /&gt;
    end -- if end&lt;br /&gt;
    if Ext2 then&lt;br /&gt;
      local lineB = Contour(0.0)&lt;br /&gt;
      local layerB = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
      lineB:AppendPoint(PT01B)&lt;br /&gt;
      lineB:LineTo(PT03B)&lt;br /&gt;
      layerB:AddObject(CreateCadContour(lineB), true)&lt;br /&gt;
    end -- if end&lt;br /&gt;
    local lineC = Contour(0.0)&lt;br /&gt;
    local layerC = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
    lineC:AppendPoint(PT02A)&lt;br /&gt;
    lineC:LineTo(PT02B)&lt;br /&gt;
    layerC:AddObject(CreateCadContour(lineC), true)&lt;br /&gt;
    DrawWriter(Double2Fraction(Str), TxtPt, ArrowLen, Layer, DimArrow1Angle)&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===LayerClear===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Deletes Layer if empty.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function LayerClear(LayerName)&lt;br /&gt;
   local Mylayer = Milling.job.LayerManager:GetLayerWithName(LayerName)&lt;br /&gt;
   if Mylayer.IsEmpty then&lt;br /&gt;
     Milling.job.LayerManager:RemoveLayer(Mylayer)&lt;br /&gt;
   end -- if end&lt;br /&gt;
   return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===LeaderLine===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawLeader(Pt1, Pt2, Pt3, Str, Layer, scale)   --Draws a leader with text&lt;br /&gt;
  --[[&lt;br /&gt;
  DrawLeader(pt1, pt2, &amp;quot;122.5&amp;quot;, &amp;quot;TestLayer&amp;quot;, 6.0)&lt;br /&gt;
  --]]&lt;br /&gt;
    local job = VectricJob()&lt;br /&gt;
    if not job.Exists then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error: No job loaded&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    local ArrowLen       = 0.125 * scale&lt;br /&gt;
    local DimArrowAngle  = GetPolarDirection(Pt1, Pt2, Polar2D(Pt2, 0.0, 1.0))&lt;br /&gt;
    local TxtAngle       = GetPolarDirection(Pt2, Pt3, Polar2D(Pt3, 0.0, 1.0))&lt;br /&gt;
    local TxtPt          = Polar2D(Polar2D(Pt3, TxtAngle, ArrowLen), TxtAngle-45, H(ArrowLen))&lt;br /&gt;
    local Apt1           = Polar2D(Pt1, DimArrowAngle + 15.0, ArrowLen)&lt;br /&gt;
    local Apt2           = Polar2D(Pt1, DimArrowAngle - 15.0, ArrowLen)&lt;br /&gt;
    local ArrowHead      = ArrowLen * 0.333&lt;br /&gt;
    local line1          = Contour(0.0)&lt;br /&gt;
    local layer1         = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
    line1:AppendPoint(Pt1)&lt;br /&gt;
    line1:LineTo(Apt2) ;  line1:LineTo(Apt1) ; line1:LineTo(Pt1)&lt;br /&gt;
    layer1:AddObject(CreateCadContour(line1), true)&lt;br /&gt;
    local lineC = Contour(0.0)&lt;br /&gt;
    local layerC = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
    lineC:AppendPoint(Pt1)&lt;br /&gt;
    lineC:LineTo(Pt2)&lt;br /&gt;
    lineC:LineTo(Pt3)&lt;br /&gt;
    layerC:AddObject(CreateCadContour(lineC), true)&lt;br /&gt;
    if IsAllNumber(Str) then&lt;br /&gt;
      DrawWriter(Double2Fraction(Str), TxtPt, ArrowLen, Layer, TxtAngle)&lt;br /&gt;
    else&lt;br /&gt;
      DrawWriter(Str, TxtPt, ArrowLen, Layer, TxtAngle)&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Scale===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Provides the correct scale rate-based drawing units.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function Scale(Num)&lt;br /&gt;
   local mtl_block = MaterialBlock()&lt;br /&gt;
   if mtl_block.InMM then&lt;br /&gt;
     return Num * 25.4&lt;br /&gt;
   else&lt;br /&gt;
     return Num&lt;br /&gt;
   end&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===AssyHoler===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws Assy Holes in a stright line (Rabbet and/or Dado).&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function AssyHoler(pt1, pt2, PartName)                  -- Draws Assy Holes in a stright line&lt;br /&gt;
     local Ang1 = GetPolarDirection(pt1, pt2)&lt;br /&gt;
     local Ang2 = GetPolarDirection(pt2, pt1)&lt;br /&gt;
            pt1 = Polar2D(pt1, Ang1, Milling.AssemblyHoleStartEnd)&lt;br /&gt;
     DrawCircle(pt1, Milling.AssemblyHoleRad, Milling.LNAssemblyHole .. PartName)&lt;br /&gt;
            pt2 = Polar2D(pt2, Ang2, Milling.AssemblyHoleStartEnd)&lt;br /&gt;
     DrawCircle(pt2, Milling.AssemblyHoleRad, Milling.LNAssemblyHole .. PartName)&lt;br /&gt;
     local Dist = GetDistance(pt1, pt2)&lt;br /&gt;
     if Project.Debugger then&lt;br /&gt;
        DMark(&amp;quot;pt1&amp;quot;, pt1)&lt;br /&gt;
        DMark(&amp;quot;pt2&amp;quot;, pt2)&lt;br /&gt;
     end -- if end &lt;br /&gt;
     BaseScrew(2)&lt;br /&gt;
     Milling.AssemblyHoleSpace = ((Milling.AssemblyHoleMaxSpace + Milling.AssemblyHoleMinSpace) * 0.5)&lt;br /&gt;
     HoleCount = Round(math.floor(Dist / Milling.AssemblyHoleSpace))&lt;br /&gt;
     HoleSpacing = (Dist / HoleCount)&lt;br /&gt;
     HoleCount = (Dist / HoleSpacing)&lt;br /&gt;
     if (Dist &amp;gt; (HoleSpacing * 2.0)) then&lt;br /&gt;
     for i = HoleCount, 1, -1 do&lt;br /&gt;
       pt1 = Polar2D(pt1, Ang1, HoleSpacing)&lt;br /&gt;
       DrawCircle(pt1, Milling.AssemblyHoleRad, Milling.LNAssemblyHole .. PartName)&lt;br /&gt;
       if Project.Debugger then&lt;br /&gt;
 &amp;gt;       DMark(&amp;quot;pt1w&amp;quot;, pt1)&lt;br /&gt;
       end -- if end&lt;br /&gt;
       BaseScrew(1)&lt;br /&gt;
     end -- for end&lt;br /&gt;
   elseif (Dist &amp;gt; HoleSpacing) then&lt;br /&gt;
     ptC = Polar2D(pt1, Ang1, Dist / 2.0)&lt;br /&gt;
     if Project.Debugger then&lt;br /&gt;
       DMark(&amp;quot;ptC&amp;quot;, ptC)&lt;br /&gt;
     end -- if end&lt;br /&gt;
     DrawCircle(ptC, Milling.AssemblyHoleRad, Milling.LNAssemblyHole .. PartName)&lt;br /&gt;
   else&lt;br /&gt;
     -- Done No Holes&lt;br /&gt;
   end -- if end&lt;br /&gt;
   return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DrawBoneCenter2Pts===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws dog bone joints.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawBoneCenter2Pts(pt1, pt2, SlotWidth, BitRadius)&lt;br /&gt;
   Local Project = {}&lt;br /&gt;
   Project.job   = VectricJob()&lt;br /&gt;
   Project.ang   = GetPolarDirection(pt1, pt2)&lt;br /&gt;
   Project.dis   = H(SlotWidth)&lt;br /&gt;
   Project.bit   = math.sin(math.rad(45.0)) * BitRadius&lt;br /&gt;
   Project.ptA   = Polar2D(pt1, Project.ang +  90.0, Project.dis)&lt;br /&gt;
   Project.ptAa  = Polar2D(Project.ptA, Project.ang, Project.bit)&lt;br /&gt;
   Project.ptAb  = Polar2D(Project.ptA, Project.ang + 270.0, Project.bit)&lt;br /&gt;
   Project.ptB   = Polar2D(pt1, Project.ang + 270.0, Project.dis)&lt;br /&gt;
   Project.ptBa  = Polar2D(Project.ptB, Project.ang +  90.0, Project.bit)&lt;br /&gt;
   Project.ptBb  = Polar2D(Project.ptB, Project.ang, Project.bit)&lt;br /&gt;
   Project.ptC   = Polar2D(pt2, Project.ang + 270.0, Project.dis)&lt;br /&gt;
   Project.ptCa  = Polar2D(Project.ptC, Project.ang +  90.0, Project.bit)&lt;br /&gt;
   Project.ptCb  = Polar2D(Project.ptC, Project.ang - 180.0, Project.bit)&lt;br /&gt;
   Project.ptD   = Polar2D(pt2, Project.ang +  90.0, Project.dis)&lt;br /&gt;
   Project.ptDa  = Polar2D(Project.ptD, Project.ang - 180.0, Project.bit)&lt;br /&gt;
   Project.ptDb  = Polar2D(Project.ptD, Project.ang + 270.0, Project.bit)&lt;br /&gt;
   Project.line  = Contour(0.0)&lt;br /&gt;
   Project.layer = Project.job.LayerManager:GetLayerWithName(&amp;quot;DogBone&amp;quot;)&lt;br /&gt;
   Project.line:AppendPoint(Project.ptAa)&lt;br /&gt;
   Project.line:ArcTo(Project.ptAb, 1.0)&lt;br /&gt;
   Project.line:LineTo(Project.ptBa)&lt;br /&gt;
   Project.line:ArcTo(Project.ptBb, 1.0)&lt;br /&gt;
   Project.line:LineTo(Project.ptCb)&lt;br /&gt;
   Project.line:ArcTo(Project.ptCa, 1.0)&lt;br /&gt;
   Project.line:LineTo(Project.ptDb)&lt;br /&gt;
   Project.line:ArcTo(Project.ptDa, 1.0)&lt;br /&gt;
   Project.line:LineTo(Project.ptAa)&lt;br /&gt;
   Project.layer:AddObject(CreateCadContour(Project.line), true)&lt;br /&gt;
   return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===InsideCornerNipper===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws the nipping of a corner for easy fitting.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function InsideCornerNipper(AngPlung, BitRadius, CornerPt)&lt;br /&gt;
   local NipLength = math.sin(math.rad(45.0)) * ((BitRadius + 0.04) * 2.0)&lt;br /&gt;
   local Pt1, Pt2 = Point2D()&lt;br /&gt;
   if Material.Orientation == &amp;quot;V&amp;quot; then&lt;br /&gt;
     Pt1 = Polar2D(CornerPt, (AngPlung + 90.0) - 45.0, NipLength)&lt;br /&gt;
     Pt2 = Polar2D(CornerPt, (AngPlung + 90.0) + 45.0, NipLength)&lt;br /&gt;
   else&lt;br /&gt;
     Pt1 = Polar2D(CornerPt, (AngPlung + 180.0) - 45.0, NipLength)&lt;br /&gt;
     Pt2 = Polar2D(CornerPt, (AngPlung + 180.0) + 45.0, NipLength)&lt;br /&gt;
   end&lt;br /&gt;
   return Pt1, Pt2&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===AddGroupToJob===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Builds a Grouping from the layer selection.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function AddGroupToJob(job, group, layer_name)&lt;br /&gt;
   --[[  --------------- AddGroupToJob --------------------------------------------------|&lt;br /&gt;
   |  Add passed group to the job - returns object created&lt;br /&gt;
   |  Parameters:&lt;br /&gt;
   |     job              -- job we are working with&lt;br /&gt;
   |     group            -- group of contours to   add to document&lt;br /&gt;
   |     layer_name       -- name of layer group will be created on|&lt;br /&gt;
   |  Return Values:&lt;br /&gt;
   |     object created to represent group in document&lt;br /&gt;
   ]]&lt;br /&gt;
   --  create a CadObject to represent the  group&lt;br /&gt;
   local cad_object = CreateCadGroup(group);&lt;br /&gt;
   -- create a layer with passed name if it doesnt already exist&lt;br /&gt;
   local layer = job.LayerManager:GetLayerWithName(layer_name)&lt;br /&gt;
   -- and add our object to it&lt;br /&gt;
   layer:AddObject(cad_object, true)&lt;br /&gt;
   return cad_object&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DrawArc===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws an Arc from points provided.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawArc(PtS, PtE, ArcRadius, Layer)&lt;br /&gt;
   --[[Draw Arc&lt;br /&gt;
   function main(script_path)&lt;br /&gt;
   local MyPt1 = Point2D(3.5,3.8)&lt;br /&gt;
   local MyPt2 = Point2D(3.5,6.8)&lt;br /&gt;
   local layer = &amp;quot;My Arc&amp;quot;&lt;br /&gt;
   DrawArc(MyPt1, MyPt2, -0.456, Layer)&lt;br /&gt;
   return true&lt;br /&gt;
   end -- function end&lt;br /&gt;
   -- -----------------------------------------------------]]&lt;br /&gt;
       local job = VectricJob()&lt;br /&gt;
       if not job.Exists then&lt;br /&gt;
         DisplayMessageBox(&amp;quot;Error: No job loaded&amp;quot;)&lt;br /&gt;
         return false&lt;br /&gt;
       end&lt;br /&gt;
       local line = Contour(0.0)&lt;br /&gt;
       local layer = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
       line:AppendPoint(PtS)&lt;br /&gt;
       line:ArcTo(PtE,1);&lt;br /&gt;
       layer:AddObject(CreateCadContour(line), true)&lt;br /&gt;
       return true&lt;br /&gt;
     end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DrawEllipse===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws a DrawEllipse from points provided.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawEllipse(CenterPt, LongAxe, ShortAxe, Layer)&lt;br /&gt;
   local LongAngle = 90.0&lt;br /&gt;
   local ValueAB = (LongAxe - ShortAxe) * 0.50&lt;br /&gt;
   local ValueAC = ValueAB * math.cos(math.rad(LongAngle))&lt;br /&gt;
   local job = VectricJob()&lt;br /&gt;
   local LRad = LongAxe * 0.50&lt;br /&gt;
   local ptT = Polar2D(CenterPt, LongAngle, LRad)&lt;br /&gt;
   local X = 0.0&lt;br /&gt;
   local pty = Point2D(0.0,0.0)&lt;br /&gt;
   local ptx = Point2D(0.0,0.0)&lt;br /&gt;
   local mylayer = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
   local line = Contour(0.0)&lt;br /&gt;
         line:AppendPoint(ptT)&lt;br /&gt;
     while (X &amp;lt; 360.0) do&lt;br /&gt;
        pty = Polar2D(CenterPt, LongAngle + X, LRad)&lt;br /&gt;
    ValueAC = ValueAB * math.cos(math.rad(LongAngle + X))&lt;br /&gt;
    if ((LongAngle + X) &amp;gt;= 90.0) then&lt;br /&gt;
      ptx = Polar2D(pty, 180.0, ValueAC)&lt;br /&gt;
    else&lt;br /&gt;
      ptx = Polar2D(pty,   0.0, ValueAC)&lt;br /&gt;
    end&lt;br /&gt;
    line:LineTo(ptx)&lt;br /&gt;
    X = X + 1&lt;br /&gt;
   end -- while end&lt;br /&gt;
   line:LineTo(ptT)&lt;br /&gt;
   mylayer:AddObject(CreateCadContour(line), true)&lt;br /&gt;
   return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DrawEllipse1===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws a DrawEllipse from points provided.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawEllipse1(DrawEllipse_CenterPt, DrawEllipse_LongAxe, DrawEllipse_ShortAxe, DrawEllipse_LongAxeAngle, DrawEllipse_Layer)&lt;br /&gt;
     -- ---------------------------------------------------]]&lt;br /&gt;
     function H(x)                                         -- Returns half the value&lt;br /&gt;
       return x * 0.5&lt;br /&gt;
     end -- function end&lt;br /&gt;
     -- ---------------------------------------------------]]&lt;br /&gt;
     function Polar2D(pt, ang, dis)                        -- Calculate a new point based on reference point, angle and distance.&lt;br /&gt;
     -- Returns a 2Dpoint(x, y)&lt;br /&gt;
       return Point2D((pt.X + dis * math.cos(math.rad(ang))), (pt.Y + dis * math.sin(math.rad(ang))))&lt;br /&gt;
     end -- End Function&lt;br /&gt;
     -- ---------------------------------------------------]]&lt;br /&gt;
     function GetDistance(objA, objB)&lt;br /&gt;
       local xDist = objB.x - objA.x&lt;br /&gt;
       local yDist = objB.y - objA.y&lt;br /&gt;
       return math.sqrt((xDist ^ 2) + (yDist ^ 2))&lt;br /&gt;
     end -- function end&lt;br /&gt;
     -- ---------------------------------------------------]]&lt;br /&gt;
     function Radius2Bulge (p1, p2, Rad)&lt;br /&gt;
       local chord = math.sqrt(((p2.x - p1.x) ^ 2) + ((p2.y - p1.y) ^ 2))&lt;br /&gt;
       local seg = (Rad - (0.5 * (math.sqrt((4.0 * Rad^2) - chord^2))))&lt;br /&gt;
       local bulge = (2 * seg) / chord&lt;br /&gt;
       return bulge&lt;br /&gt;
     end -- function end&lt;br /&gt;
     -- ---------------------------------------------------]]&lt;br /&gt;
   function GetPolarAngle(Start, Corner, End)&lt;br /&gt;
     local function GetPolarDirection(point1, point2)              --&lt;br /&gt;
       local ang = math.abs(math.deg(math.atan((point2.Y - point1.Y) / (point2.X - point1.X))))&lt;br /&gt;
       if point1.X &amp;lt; point2.X then&lt;br /&gt;
         if point1.Y &amp;lt; point2.Y then&lt;br /&gt;
           ang = ang + 0.0&lt;br /&gt;
         else&lt;br /&gt;
           ang = 360.0 - ang&lt;br /&gt;
         end -- if end&lt;br /&gt;
       else&lt;br /&gt;
         if point1.Y &amp;lt; point2.Y then&lt;br /&gt;
           ang = 180.0 - ang&lt;br /&gt;
         else&lt;br /&gt;
           ang = ang + 180.0&lt;br /&gt;
         end -- if end&lt;br /&gt;
       end -- if end&lt;br /&gt;
       if ang &amp;gt;=360 then&lt;br /&gt;
         ang = ang -360.0&lt;br /&gt;
       end -- if end&lt;br /&gt;
       return ang&lt;br /&gt;
     end -- function end&lt;br /&gt;
     return  math.abs(GetPolarDirection(Corner, Start) - GetPolarDirection(Corner, End))&lt;br /&gt;
   end -- function end&lt;br /&gt;
     -- ---------------------------------------------------]]&lt;br /&gt;
 &lt;br /&gt;
     -- Call = DrawEllipse(2DPoint(20.0, 20.0), 20.0, 10.0, 0.0, &amp;quot;Jim&amp;quot;)&lt;br /&gt;
     local job = VectricJob()&lt;br /&gt;
     local EndRadius = 0.0&lt;br /&gt;
     local TopRadius = 0.0&lt;br /&gt;
     local ptT = Polar2D(DrawEllipse_CenterPt,  (90.0 + DrawEllipse_LongAxeAngle), H(DrawEllipse_ShortAxe))&lt;br /&gt;
     local ptB = Polar2D(DrawEllipse_CenterPt, (270.0 + DrawEllipse_LongAxeAngle), H(DrawEllipse_ShortAxe))&lt;br /&gt;
     local ptR = Polar2D(DrawEllipse_CenterPt,   (0.0 + DrawEllipse_LongAxeAngle), H(DrawEllipse_LongAxe))&lt;br /&gt;
     local ptL = Polar2D(DrawEllipse_CenterPt, (180.0 + DrawEllipse_LongAxeAngle), H(DrawEllipse_LongAxe))&lt;br /&gt;
     local ptC = DrawEllipse_CenterPt&lt;br /&gt;
     --[[&lt;br /&gt;
       DMark(&amp;quot;ptC&amp;quot;, ptC)&lt;br /&gt;
       DMark(&amp;quot;ptT&amp;quot;, ptT)&lt;br /&gt;
       DMark(&amp;quot;ptB&amp;quot;, ptB)&lt;br /&gt;
       DMark(&amp;quot;ptL&amp;quot;, ptL)&lt;br /&gt;
       DMark(&amp;quot;ptR&amp;quot;, ptR)]]&lt;br /&gt;
     local C_Offset = H(DrawEllipse_LongAxe - DrawEllipse_ShortAxe)&lt;br /&gt;
     local LT_SlopeDist = H(GetDistance(ptL, ptT) - H(DrawEllipse_LongAxe - DrawEllipse_ShortAxe))&lt;br /&gt;
     local LT_Dist  = GetDistance(ptL, ptT)&lt;br /&gt;
     local LT_Angle = math.abs(90.0 - GetAngle(ptT, ptL, ptC))&lt;br /&gt;
     local pt_a = Polar2D(ptL, LT_Angle + DrawEllipse_LongAxeAngle, LT_SlopeDist)&lt;br /&gt;
     local aT_Dist  = GetDistance(pt_a, ptT)&lt;br /&gt;
     local aC_Dist = aT_Dist / (math.tan(math.rad(LT_Angle)))&lt;br /&gt;
     local Tc_Dist = math.sqrt(aT_Dist^2 + aC_Dist^2)&lt;br /&gt;
     local pt_c = Polar2D(ptT, (270.0 + DrawEllipse_LongAxeAngle), Tc_Dist)&lt;br /&gt;
     local cC_Dist  = GetDistance(pt_c, ptC)&lt;br /&gt;
     local b_Dist = math.tan(math.rad(LT_Angle)) * cC_Dist&lt;br /&gt;
     local pt_b = Polar2D(ptC, (180.0 + DrawEllipse_LongAxeAngle), b_Dist)&lt;br /&gt;
     local pt_d = Polar2D(ptB,  (90.0 + DrawEllipse_LongAxeAngle), Tc_Dist)&lt;br /&gt;
     local pt_e = Polar2D(ptC,   (0.0 + DrawEllipse_LongAxeAngle), b_Dist)&lt;br /&gt;
     local pt1  = Polar2D(pt_d, (270.0 + DrawEllipse_LongAxeAngle) - LT_Angle, Tc_Dist)&lt;br /&gt;
     local pt2  = Polar2D(pt_d, (270.0 + DrawEllipse_LongAxeAngle) + LT_Angle, Tc_Dist)&lt;br /&gt;
     local pt3  = Polar2D(pt_c,  (90.0 + DrawEllipse_LongAxeAngle) - LT_Angle, Tc_Dist)&lt;br /&gt;
     local pt4  = Polar2D(pt_c,  (90.0 + DrawEllipse_LongAxeAngle) + LT_Angle, Tc_Dist)&lt;br /&gt;
     --[[&lt;br /&gt;
       DMark(&amp;quot;pt1&amp;quot;, pt1)&lt;br /&gt;
       DMark(&amp;quot;pt2&amp;quot;, pt2)&lt;br /&gt;
       DMark(&amp;quot;pt3&amp;quot;, pt3)&lt;br /&gt;
       DMark(&amp;quot;pt4&amp;quot;, pt4)&lt;br /&gt;
       local line = Contour(0.0)&lt;br /&gt;
       local layer = job.LayerManager:GetLayerWithName(DrawEllipse_Layer)&lt;br /&gt;
       line:AppendPoint(pt1)&lt;br /&gt;
       line:LineTo(pt2)&lt;br /&gt;
       line:LineTo(pt3)&lt;br /&gt;
       line:LineTo(pt4)&lt;br /&gt;
       line:LineTo(pt1)&lt;br /&gt;
       layer:AddObject(CreateCadContour(line), true)]]&lt;br /&gt;
     local T_Sec   = GetDistance(ptC, ptT) - H(GetDistance(pt1, pt4))&lt;br /&gt;
     local R_Sec   = GetDistance(ptC, ptR) - H(GetDistance(pt1, pt2))&lt;br /&gt;
     local T_Chor  = GetDistance(pt1, pt2)&lt;br /&gt;
     local R_Chor  = GetDistance(pt1, pt4)&lt;br /&gt;
     local T_Bulge = Radius2Bulge (pt1, pt2, Tc_Dist)&lt;br /&gt;
     local L_Bulge = Radius2Bulge (pt1, pt4, GetDistance(ptL, pt_b))&lt;br /&gt;
 &lt;br /&gt;
     local line = Contour(0.0)&lt;br /&gt;
     local layer = job.LayerManager:GetLayerWithName(DrawEllipse_Layer)&lt;br /&gt;
     line:AppendPoint(pt1)&lt;br /&gt;
     line:ArcTo(pt2, T_Bulge)&lt;br /&gt;
     line:ArcTo(pt3, L_Bulge)&lt;br /&gt;
     line:ArcTo(pt4, T_Bulge)&lt;br /&gt;
     line:ArcTo(pt1, L_Bulge)&lt;br /&gt;
     layer:AddObject(CreateCadContour(line), true)&lt;br /&gt;
     job:Refresh2DView()&lt;br /&gt;
     return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DrawBox===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws a Box from points provided.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawBox(p1, p2, p3, p4, Layer)&lt;br /&gt;
     --[[ Draw Box&lt;br /&gt;
     function main(script_path)&lt;br /&gt;
     local MyPt1 = Point2D(1.0,1.0)&lt;br /&gt;
     local MyPt2 = Point2D(1.0,3.0)&lt;br /&gt;
     local MyPt3 = Point2D(3.0,1.0)&lt;br /&gt;
     local MyPt4 = Point2D(3.0,3.0)&lt;br /&gt;
     local layer = &amp;quot;My Box&amp;quot;&lt;br /&gt;
     DrawBox(MyPt1 ,MyPt2, MyPt3, MyPt4, Layer)&lt;br /&gt;
     return true&lt;br /&gt;
     end -- function end&lt;br /&gt;
   -- -----------------------------------------------------]]&lt;br /&gt;
       local job = VectricJob()&lt;br /&gt;
       if not job.Exists then&lt;br /&gt;
         DisplayMessageBox(&amp;quot;Error: No job loaded&amp;quot;)&lt;br /&gt;
         return false&lt;br /&gt;
       end -- if end&lt;br /&gt;
       local line = Contour(0.0)&lt;br /&gt;
       local layer = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
       line:AppendPoint(p1)&lt;br /&gt;
       line:LineTo(p2)&lt;br /&gt;
       line:LineTo(p3)&lt;br /&gt;
       line:LineTo(p4)&lt;br /&gt;
       line:LineTo(p1)&lt;br /&gt;
       layer:AddObject(CreateCadContour(line), true)&lt;br /&gt;
       return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DrawCircle===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws a circle.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawCircle(Pt1, CenterRadius, Layer)&lt;br /&gt;
   --[[ ==Draw Circle==&lt;br /&gt;
     function main(script_path)&lt;br /&gt;
     local MyPt1 = Point2D(1.0,1.0)&lt;br /&gt;
     local MyRad = 3.0&lt;br /&gt;
     local layer = &amp;quot;My Box&amp;quot;&lt;br /&gt;
     DrawCircle(MyPt1, MyRad, Layer)&lt;br /&gt;
     return true&lt;br /&gt;
     end -- function end&lt;br /&gt;
   -- -----------------------------------------------------]]&lt;br /&gt;
     local job = VectricJob()&lt;br /&gt;
     if not job.Exists then&lt;br /&gt;
       DisplayMessageBox(&amp;quot;Error: No job loaded&amp;quot;)&lt;br /&gt;
       return false&lt;br /&gt;
     end -- if end&lt;br /&gt;
     local pa = Polar2D(Pt1,   180.0, CenterRadius)&lt;br /&gt;
     local pb = Polar2D(Pt1,     0.0, CenterRadius)&lt;br /&gt;
     local Contour = Contour(0.0)&lt;br /&gt;
     local layer = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
     Contour:AppendPoint(pa)&lt;br /&gt;
     Contour:ArcTo(pb, 1)&lt;br /&gt;
     Contour:ArcTo(pa, 1)&lt;br /&gt;
     layer:AddObject(CreateCadContour(Contour), true)&lt;br /&gt;
     return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===DrawLine===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws a Line from points provided.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawLine(Pt1, Pt2, Layer)&lt;br /&gt;
   --[[Draws a line from Pt1 to Pt2 on the layer name.&lt;br /&gt;
   function main(script_path)&lt;br /&gt;
   local MyPt1 = Point2D(3.5,3.8)&lt;br /&gt;
   local MyPt2 = Point2D(3.5,6.8)&lt;br /&gt;
   local layer = &amp;quot;My Line&amp;quot;&lt;br /&gt;
   DrawLine(MyPt1 , MyPt2, MyPt3, Layer)&lt;br /&gt;
   return true&lt;br /&gt;
   end -- function end&lt;br /&gt;
   -- -----------------------------------------------------]]&lt;br /&gt;
     local job = VectricJob()&lt;br /&gt;
     if not job.Exists then&lt;br /&gt;
       DisplayMessageBox(&amp;quot;Error: No job loaded&amp;quot;)&lt;br /&gt;
       return false&lt;br /&gt;
     end&lt;br /&gt;
     local line = Contour(0.0)&lt;br /&gt;
     local layer = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
     line:AppendPoint(Pt1)&lt;br /&gt;
     line:LineTo(Pt2)&lt;br /&gt;
     layer:AddObject(CreateCadContour(line), true)&lt;br /&gt;
     return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DrawStar===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws a Star from points provided.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawStar(pt1, InRadius ,OutRadius, layer)      --This draw function requires the center point, inter star radius, outer star radius and layer name.&lt;br /&gt;
   --[[&lt;br /&gt;
     function main(script_path)&lt;br /&gt;
       local MyPt = Point2D(3.5,3.8)&lt;br /&gt;
       local InRadius = 9.0&lt;br /&gt;
       local OutRadius= 20.0&lt;br /&gt;
       local layer = &amp;quot;My Star&amp;quot;&lt;br /&gt;
       DrawStar(MyPt , InRadius ,OutRadius, layer)&lt;br /&gt;
       return true&lt;br /&gt;
     end -- function end&lt;br /&gt;
   -- -----------------------------------------------------]]&lt;br /&gt;
     local job = VectricJob()&lt;br /&gt;
     if not job.Exists then&lt;br /&gt;
       DisplayMessageBox(&amp;quot;Error: No job loaded&amp;quot;)&lt;br /&gt;
       return false&lt;br /&gt;
     end&lt;br /&gt;
     local p1 =  Polar2D(pt1,  18.0,  OutRadius)&lt;br /&gt;
     local p2 =  Polar2D(pt1,  54.0,  InRadius)&lt;br /&gt;
     local p3 =  Polar2D(pt1,  90.0,  OutRadius)&lt;br /&gt;
     local p4 =  Polar2D(pt1,  126.0, InRadius)&lt;br /&gt;
     local p5 =  Polar2D(pt1,  162.0, OutRadius)&lt;br /&gt;
     local p6 =  Polar2D(pt1,  198.0, InRadius)&lt;br /&gt;
     local p7 =  Polar2D(pt1,  234.0, OutRadius)&lt;br /&gt;
     local p8 =  Polar2D(pt1,  270.0, InRadius)&lt;br /&gt;
     local p9 =  Polar2D(pt1,  306.0, OutRadius)&lt;br /&gt;
     local p0 =  Polar2D(pt1,  342.0, InRadius)&lt;br /&gt;
     local line = Contour(0.0)&lt;br /&gt;
    -- local layers = job.LayerManager:GetLayerWithName(layer)&lt;br /&gt;
     line:AppendPoint(p1);&lt;br /&gt;
     line:LineTo(p2);  line:LineTo(p3)&lt;br /&gt;
     line:LineTo(p4);  line:LineTo(p5)&lt;br /&gt;
     line:LineTo(p6);  line:LineTo(p7)&lt;br /&gt;
     line:LineTo(p8);  line:LineTo(p9)&lt;br /&gt;
     line:LineTo(p0);  line:LineTo(p1)&lt;br /&gt;
     layer:AddObject(CreateCadContour(line), true)&lt;br /&gt;
     job:Refresh2DView()&lt;br /&gt;
     return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DrawTriangle===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws a Triangle from points provided.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawTriangle(p1, p2, p3, Layer)&lt;br /&gt;
   --&amp;lt;nowiki&amp;gt;[[Draw Triangle&lt;br /&gt;
     function main(script_path)&lt;br /&gt;
       local MyPt1 = Point2D(3.5,3.8)&lt;br /&gt;
       local MyPt2 = Point2D(3.5,6.8)&lt;br /&gt;
       local MyPt3 = Point2D(9.8,6.8)&lt;br /&gt;
       local layer = &amp;quot;My Triangle&amp;quot;&lt;br /&gt;
       DrawTriangle(MyPt1 , MyPt2, MyPt3, Layer)&lt;br /&gt;
       return true&lt;br /&gt;
     end -- function end &lt;br /&gt;
     local job = VectricJob()&lt;br /&gt;
     if not job.Exists then&lt;br /&gt;
       DisplayMessageBox(&amp;quot;Error: No job loaded&amp;quot;)&lt;br /&gt;
       return false&lt;br /&gt;
     end&lt;br /&gt;
     local line = Contour(0.0)&lt;br /&gt;
     local layer = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
     line:AppendPoint(p1)&lt;br /&gt;
     line:LineTo(p2)&lt;br /&gt;
     line:LineTo(p3)&lt;br /&gt;
     line:LineTo(p1)&lt;br /&gt;
     layer:AddObject(CreateCadContour(line), true)&lt;br /&gt;
     job:Refresh2DView()&lt;br /&gt;
     return true&lt;br /&gt;
   end -- function end&lt;br /&gt;
   -- =====================================================]]&lt;br /&gt;
   function Radius2Bulge (p1, p2, Rad)&lt;br /&gt;
     local chord = math.sqrt(((p2.x - p1.x) ^ 2) + ((p2.y - p1.y) ^ 2))&lt;br /&gt;
     local seg = (Rad - (0.5 * (math.sqrt((4.0 * Rad^2) - chord^2))))&lt;br /&gt;
     local bulge = (2 * seg) / chord&lt;br /&gt;
     return bulge&lt;br /&gt;
   end&lt;br /&gt;
   -- =====================================================]]&lt;br /&gt;
   function ChordSeg2Radius (Chr, Seg)&lt;br /&gt;
     local rad =  (((Chr * Chr)/(Seg * 4)) + Seg) / 2.0&lt;br /&gt;
     return rad&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CreateJob===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Create a new job/drawing setup.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function CreateJob(job_name, width, height, thickness, in_mm, job_origin, z_on_surface)&lt;br /&gt;
 --[[ ----------- CreateJob -------------------------------------------------&lt;br /&gt;
   | This function was provided &amp;quot;as is&amp;quot; by Vectric technical team and a part of the gadget API documentation.&lt;br /&gt;
   | Create a new empty job with the passed settings]]&lt;br /&gt;
   -- we fill in most of our bounds in a Box2D&lt;br /&gt;
   local job_bounds = Box2D()&lt;br /&gt;
   local blc = Point2D(0, 0)&lt;br /&gt;
   local trc = Point2D(width, height)&lt;br /&gt;
   local origin_offset = Vector2D(0,0)&lt;br /&gt;
   -- calculate bottom left corner offset for chosen origin&lt;br /&gt;
   if Template.DXFOrientation == &amp;quot;Vertical&amp;quot; then&lt;br /&gt;
     trc = Point2D(height, width)&lt;br /&gt;
     if (job_origin == &amp;quot;BLC&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(0, 0)&lt;br /&gt;
     elseif (job_origin == &amp;quot;BRC&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(height, 0)&lt;br /&gt;
     elseif (job_origin == &amp;quot;TRC&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(height, width)&lt;br /&gt;
     elseif (job_origin == &amp;quot;TLC&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(0, width)&lt;br /&gt;
     elseif (job_origin == &amp;quot;CENTRE&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(height / 2, width / 2)&lt;br /&gt;
     elseif (job_origin == &amp;quot;CENTER&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(height / 2, width / 2)&lt;br /&gt;
     else&lt;br /&gt;
       MessageBox(&amp;quot;Unknown XY origin specified &amp;quot; .. job_origin)&lt;br /&gt;
     end&lt;br /&gt;
   else&lt;br /&gt;
     if (job_origin == &amp;quot;BLC&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(0, 0)&lt;br /&gt;
     elseif (job_origin == &amp;quot;BRC&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(width, 0)&lt;br /&gt;
     elseif (job_origin == &amp;quot;TRC&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(width, height)&lt;br /&gt;
     elseif (job_origin == &amp;quot;TLC&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(0, height)&lt;br /&gt;
     elseif (job_origin == &amp;quot;CENTRE&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(width / 2, height / 2)&lt;br /&gt;
     elseif (job_origin == &amp;quot;CENTER&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(width / 2, height / 2)&lt;br /&gt;
     else&lt;br /&gt;
       MessageBox(&amp;quot;Unknown XY origin specified &amp;quot; .. job_origin)&lt;br /&gt;
     end&lt;br /&gt;
   end&lt;br /&gt;
   -- subtract the origin offset vector from our 'standard' corner positions to get position for corners for requested origin&lt;br /&gt;
   blc = blc - origin_offset&lt;br /&gt;
   trc = trc - origin_offset&lt;br /&gt;
   job_bounds:Merge(blc)&lt;br /&gt;
   job_bounds:Merge(trc)&lt;br /&gt;
   local success = CreateNewJob(job_name,job_bounds,thickness,in_mm,z_on_surface)&lt;br /&gt;
   return success&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DrawFontGrid - Draws font grid to create letters===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws the font grid for drawing new letters.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawFontGrid(job)&lt;br /&gt;
     local pt = Point2D(0.3,0.3)&lt;br /&gt;
     local scl  = 1.0 -- (scl * 0.5)&lt;br /&gt;
     local pA0  = pt&lt;br /&gt;
     local ang  = 0.0&lt;br /&gt;
     local pA1  = Polar2D(pt, ang + 90.0000, (0.2500 * scl))&lt;br /&gt;
     local pA2  = Polar2D(pt, ang + 90.0000, (0.5000 * scl))&lt;br /&gt;
     local pA3  = Polar2D(pt, ang + 90.0000, (0.7500 * scl))&lt;br /&gt;
     local pA4  = Polar2D(pt, ang + 90.0000, (1.0000 * scl))&lt;br /&gt;
     local pA5  = Polar2D(pt, ang + 90.0000, (1.2500 * scl))&lt;br /&gt;
     local pA6  = Polar2D(pt, ang + 90.0000, (1.5000 * scl))&lt;br /&gt;
     local pA7  = Polar2D(pt, ang + 90.0000, (1.7500 * scl))&lt;br /&gt;
     local pA8  = Polar2D(pt, ang + 90.0000, (2.0000 * scl))&lt;br /&gt;
     local pA9  = Polar2D(pt, ang + 90.0000, (2.2500 * scl))&lt;br /&gt;
     local pA10 = Polar2D(pt, ang + 90.0000, (2.5000 * scl))&lt;br /&gt;
 &lt;br /&gt;
     PointCircle(pA0)&lt;br /&gt;
     PointCircle(pA1)&lt;br /&gt;
     PointCircle(pA2)&lt;br /&gt;
     PointCircle(pA3)&lt;br /&gt;
     PointCircle(pA4)&lt;br /&gt;
     PointCircle(pA5)&lt;br /&gt;
     PointCircle(pA6)&lt;br /&gt;
     PointCircle(pA7)&lt;br /&gt;
     PointCircle(pA8)&lt;br /&gt;
     PointCircle(pA9)&lt;br /&gt;
     PointCircle(pA10)&lt;br /&gt;
 &lt;br /&gt;
     local pB0  = Polar2D(pt, ang +  0.0000, (0.2500 * scl))&lt;br /&gt;
     local pB1  = Polar2D(pt, ang + 45.0000, (0.3536 * scl))&lt;br /&gt;
     local pB2  = Polar2D(pt, ang + 63.4352, (0.5590 * scl))&lt;br /&gt;
     local pB3  = Polar2D(pt, ang + 71.5651, (0.7906 * scl))&lt;br /&gt;
     local pB4  = Polar2D(pt, ang + 75.9638, (1.0308 * scl))&lt;br /&gt;
     local pB5  = Polar2D(pt, ang + 78.6901, (1.2748 * scl))&lt;br /&gt;
     local pB6  = Polar2D(pt, ang + 80.5376, (1.5207 * scl))&lt;br /&gt;
     local pB7  = Polar2D(pt, ang + 81.8699, (1.7678 * scl))&lt;br /&gt;
     local pB8  = Polar2D(pt, ang + 82.8750, (2.0156 * scl))&lt;br /&gt;
     local pB10 = Polar2D(pt, ang + 84.2894, (2.5125 * scl))&lt;br /&gt;
 &lt;br /&gt;
     PointCircle(pB0)&lt;br /&gt;
     PointCircle(pB1)&lt;br /&gt;
     PointCircle(pB2)&lt;br /&gt;
     PointCircle(pB3)&lt;br /&gt;
     PointCircle(pB4)&lt;br /&gt;
     PointCircle(pB5)&lt;br /&gt;
     PointCircle(pB7)&lt;br /&gt;
     PointCircle(pB8)&lt;br /&gt;
     PointCircle(pB10)&lt;br /&gt;
 &lt;br /&gt;
     local pC0 = Polar2D(pt, ang +  0.0000, (0.5000 * scl))&lt;br /&gt;
     local pC1 = Polar2D(pt, ang + 26.5650, (0.5590 * scl))&lt;br /&gt;
     local pC2 = Polar2D(pt, ang + 45.0000, (0.7071 * scl))&lt;br /&gt;
     local pC3 = Polar2D(pt, ang + 56.3099, (0.9014 * scl))&lt;br /&gt;
     local pC4 = Polar2D(pt, ang + 63.4342, (1.1180 * scl))&lt;br /&gt;
     local pC5 = Polar2D(pt, ang + 68.1993, (1.3463 * scl))&lt;br /&gt;
     local pC6 = Polar2D(pt, ang + 71.5650, (1.5811 * scl))&lt;br /&gt;
     local pC7 = Polar2D(pt, ang + 63.4342, (1.1180 * scl))&lt;br /&gt;
     local pC8 = Polar2D(pt, ang + 74.0550, (1.8201 * scl))&lt;br /&gt;
     local pC10 = Polar2D(pt, ang + 78.6899, (2.5495 * scl))&lt;br /&gt;
 &lt;br /&gt;
     PointCircle(pC0)&lt;br /&gt;
     PointCircle(pC1)&lt;br /&gt;
     PointCircle(pC2)&lt;br /&gt;
     PointCircle(pC3)&lt;br /&gt;
     PointCircle(pC4)&lt;br /&gt;
     PointCircle(pC6)&lt;br /&gt;
     PointCircle(pC8)&lt;br /&gt;
     PointCircle(pC10)&lt;br /&gt;
 &lt;br /&gt;
     local pD0 = Polar2D(pt, ang +  0.0000, (0.6250 * scl))&lt;br /&gt;
     local pD1 = Polar2D(pt, ang + 21.8014, (0.6731 * scl))&lt;br /&gt;
     local pD2 = Polar2D(pt, ang + 33.6901, (0.9014 * scl))&lt;br /&gt;
     local pD4 = Polar2D(pt, ang + 57.9946, (1.1792 * scl))&lt;br /&gt;
     local pD7 = Polar2D(pt, ang + 70.3462, (1.8583 * scl))&lt;br /&gt;
     local pD8 = Polar2D(pt, ang + 72.6460, (2.0954 * scl))&lt;br /&gt;
 &lt;br /&gt;
     PointCircle(pD0)&lt;br /&gt;
     PointCircle(pD1)&lt;br /&gt;
     PointCircle(pD2)&lt;br /&gt;
     PointCircle(pD4)&lt;br /&gt;
     PointCircle(pD7)&lt;br /&gt;
     PointCircle(pD8)&lt;br /&gt;
 &lt;br /&gt;
     local pE0 = Polar2D(pt, ang +  0.0000, (0.7500 * scl))&lt;br /&gt;
     local pE1 = Polar2D(pt, ang + 18.4346, (0.7906 * scl))&lt;br /&gt;
     local pE2 = Polar2D(pt, ang + 33.6901, (0.9014 * scl))&lt;br /&gt;
     local pE3 = Polar2D(pt, ang + 45.0000, (1.0607 * scl))&lt;br /&gt;
     local pE5 = Polar2D(pt, ang + 59.0371, (1.4578 * scl))&lt;br /&gt;
     local pE6 = Polar2D(pt, ang + 63.4349, (1.6771 * scl))&lt;br /&gt;
     local pE7 = Polar2D(pt, ang + 66.4349, (1.9039 * scl))&lt;br /&gt;
     local pE8 = Polar2D(pt, ang + 69.4440, (2.1360 * scl))&lt;br /&gt;
 &lt;br /&gt;
     PointCircle(pE0)&lt;br /&gt;
     PointCircle(pE1)&lt;br /&gt;
     PointCircle(pE2)&lt;br /&gt;
     PointCircle(pE3)&lt;br /&gt;
     PointCircle(pE5)&lt;br /&gt;
     PointCircle(pE6)&lt;br /&gt;
     PointCircle(pE7)&lt;br /&gt;
     PointCircle(pE8)&lt;br /&gt;
 &lt;br /&gt;
     local pF0 = Polar2D(pt, ang +  0.0000, (1.0000 * scl))&lt;br /&gt;
     local pF1 = Polar2D(pt, ang + 14.0360, (1.0308 * scl))&lt;br /&gt;
     local pF2 = Polar2D(pt, ang + 26.5651, (1.1180 * scl))&lt;br /&gt;
     local pF3 = Polar2D(pt, ang + 36.8699, (1.2500 * scl))&lt;br /&gt;
     local pF4 = Polar2D(pt, ang + 45.0000, (1.4142 * scl))&lt;br /&gt;
     local pF5 = Polar2D(pt, ang + 51.3425, (1.6006 * scl))&lt;br /&gt;
     local pF6 = Polar2D(pt, ang + 56.3099, (1.8025 * scl))&lt;br /&gt;
     local pF7 = Polar2D(pt, ang + 60.2551, (2.0156 * scl))&lt;br /&gt;
     local pF8 = Polar2D(pt, ang + 63.4349, (2.2361 * scl))&lt;br /&gt;
 &lt;br /&gt;
     PointCircle(pF0)&lt;br /&gt;
     PointCircle(pF1)&lt;br /&gt;
     PointCircle(pF2)&lt;br /&gt;
     PointCircle(pF3)&lt;br /&gt;
     PointCircle(pF4)&lt;br /&gt;
     PointCircle(pF5)&lt;br /&gt;
     PointCircle(pF6)&lt;br /&gt;
     PointCircle(pF7)&lt;br /&gt;
     PointCircle(pF8)&lt;br /&gt;
 &lt;br /&gt;
     local pG0 = Polar2D(pt, ang +  0.0000, (1.2500 * scl))&lt;br /&gt;
     local pG1 = Polar2D(pt, ang + 11.3099, (1.2748 * scl))&lt;br /&gt;
     local pG2 = Polar2D(pt, ang + 21.8014, (1.3463 * scl))&lt;br /&gt;
     local pG3 = Polar2D(pt, ang + 30.9638, (1.4577 * scl))&lt;br /&gt;
     local pG4 = Polar2D(pt, ang + 38.6598, (1.6008 * scl))&lt;br /&gt;
     local pG5 = Polar2D(pt, ang + 45.0000, (1.7678 * scl))&lt;br /&gt;
     local pG6 = Polar2D(pt, ang + 50.1944, (1.9526 * scl))&lt;br /&gt;
     local pG7 = Polar2D(pt, ang + 54.4623, (2.1506 * scl))&lt;br /&gt;
     local pG8 = Polar2D(pt, ang + 57.9946, (2.3585 * scl))&lt;br /&gt;
     local pG10 = Polar2D(pt,59.0362, (2.9155 * scl))&lt;br /&gt;
 &lt;br /&gt;
     PointCircle(pG0)&lt;br /&gt;
     PointCircle(pG1)&lt;br /&gt;
     PointCircle(pG2)&lt;br /&gt;
     PointCircle(pG3)&lt;br /&gt;
     PointCircle(pG4)&lt;br /&gt;
     PointCircle(pG5)&lt;br /&gt;
     PointCircle(pG6)&lt;br /&gt;
     PointCircle(pG7)&lt;br /&gt;
     PointCircle(pG8)&lt;br /&gt;
     PointCircle(pG10)&lt;br /&gt;
 &lt;br /&gt;
     local pH0  = Polar2D(pt, ang + 0.0000, (1.5000 * scl))&lt;br /&gt;
     local pH10 = Polar2D(pt, 63.4349,      (2.7951 * scl))&lt;br /&gt;
     PointCircle(pH0)&lt;br /&gt;
     PointCircle(pH10)&lt;br /&gt;
     job:Refresh2DView()&lt;br /&gt;
     return true&lt;br /&gt;
   end&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
   -- =========================================================================&lt;br /&gt;
   local function AddGroupToJob(job, group, layer_name)&lt;br /&gt;
      --  create a CadObject to represent the  group&lt;br /&gt;
     local cad_object = CreateCadGroup(group);&lt;br /&gt;
      -- create a layer with passed name if it doesnt already exist&lt;br /&gt;
     local layer = job.LayerManager:GetLayerWithName(layer_name)&lt;br /&gt;
      -- and add our object to it&lt;br /&gt;
     layer:AddObject(cad_object, true)&lt;br /&gt;
     return cad_object&lt;br /&gt;
   end -- end function&lt;br /&gt;
 &lt;br /&gt;
   -- =========================================================================&lt;br /&gt;
     local job = VectricJob()&lt;br /&gt;
     if not job.Exists then&lt;br /&gt;
       DisplayMessageBox(&amp;quot;Error: Not finding a job loaded&amp;quot;)&lt;br /&gt;
       return false&lt;br /&gt;
     end&lt;br /&gt;
     local strlen = string.len(what)&lt;br /&gt;
     local strup = string.upper(what)&lt;br /&gt;
     local x = strlen&lt;br /&gt;
     local i = 1&lt;br /&gt;
     local y = &amp;quot;&amp;quot;&lt;br /&gt;
     local ptx = where&lt;br /&gt;
     group = ContourGroup(true)&lt;br /&gt;
     while i &amp;lt;=  x do&lt;br /&gt;
       y = string.byte(string.sub(strup, i, i))&lt;br /&gt;
       ptx = MonoFont(job, ptx, y, size, lay, ang)&lt;br /&gt;
       i = i + 1&lt;br /&gt;
     end -- while end;&lt;br /&gt;
     AddGroupToJob(job, group, lay)&lt;br /&gt;
     job:Refresh2DView()&lt;br /&gt;
     return true ;&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DrawWriter - Draws Upper and Lower case text on the drawing===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawWriter(what, where, size, lay, ang) -- Draws Upper and Lower case text on the drawing.&lt;br /&gt;
   --[[ How to use:&lt;br /&gt;
   |    local TextMessage = &amp;quot;Your Text Here&amp;quot;&lt;br /&gt;
   |    local TextPt = Point2D(3.5,3.8)&lt;br /&gt;
   |    local TextHight = 0.5&lt;br /&gt;
   |    local TextLayer = &amp;quot;Text Layer&amp;quot;&lt;br /&gt;
   |    local TextAng = 20.0&lt;br /&gt;
   |    DrawWriter(TextMessage, TextPt , TextHight , TextLayer, TextAng)&lt;br /&gt;
   |    -- ==Draw Writer==&lt;br /&gt;
   |    -- Utilizing a provided string of text, the program walks the string and reproduces each letter (parametrically) on the drawing using vectors.&lt;br /&gt;
   function main()&lt;br /&gt;
       -- create a layer with passed name if it doesn't already exist&lt;br /&gt;
     local job = VectricJob()&lt;br /&gt;
     if not job.Exists then&lt;br /&gt;
          DisplayMessageBox(&amp;quot;No job loaded&amp;quot;)&lt;br /&gt;
          return false;&lt;br /&gt;
     end&lt;br /&gt;
     local TextMessage = &amp;quot;Aa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Oo Pp Qq Rr Ss Tt Uu Vv Ww Xx Yy Zz 1 2 3 4 5 6 7 8 9 0 ! @ # $ % &amp;amp; * ( ) { } [ ] ? , . : ; '' ' _ - + = ~ ^ &amp;lt; &amp;gt; |&amp;quot;&lt;br /&gt;
     local TextPt = Point2D(0.1, 2.0)&lt;br /&gt;
     local TextHight = 0.25&lt;br /&gt;
     local TextLayer = &amp;quot;Gadget Text&amp;quot;&lt;br /&gt;
     local TextAng = 10.0&lt;br /&gt;
     DrawWriter(TextMessage, TextPt, TextHight, TextLayer, TextAng)&lt;br /&gt;
     job:Refresh2DView()&lt;br /&gt;
     return true&lt;br /&gt;
   end&lt;br /&gt;
   --]]&lt;br /&gt;
   -- =========================================================================&lt;br /&gt;
   local function Polar2D(pt, ang, dis)&lt;br /&gt;
     return Point2D((pt.X + dis * math.cos(math.rad(ang))), (pt.Y + dis * math.sin(math.rad(ang))))&lt;br /&gt;
   end&lt;br /&gt;
   -- =========================================================================&lt;br /&gt;
   local function MonoFont(job, pt, letter, scl, lay, ang)&lt;br /&gt;
     scl = (scl * 0.5) ;&lt;br /&gt;
     local pA0 = pt ;&lt;br /&gt;
     local pA1  = Polar2D(pt, ang + 90.0000, (0.2500 * scl)) ;  local pA2   = Polar2D(pt, ang + 90.0000, (0.5000 * scl)) ;&lt;br /&gt;
     local pA3  = Polar2D(pt, ang + 90.0000, (0.7500 * scl)) ;  local pA4   = Polar2D(pt, ang + 90.0000, (1.0000 * scl)) ;&lt;br /&gt;
     local pA5  = Polar2D(pt, ang + 90.0000, (1.2500 * scl)) ;  local pA6   = Polar2D(pt, ang + 90.0000, (1.5000 * scl)) ;&lt;br /&gt;
     local pA7  = Polar2D(pt, ang + 90.0000, (1.7500 * scl)) ;  local pA8   = Polar2D(pt, ang + 90.0000, (2.0000 * scl)) ;&lt;br /&gt;
     local pA9  = Polar2D(pt, ang + 90.0000, (2.2500 * scl)) ;  local pA10  = Polar2D(pt, ang + 90.0000, (2.5000 * scl)) ;&lt;br /&gt;
     local pB0  = Polar2D(pt, ang +  0.0000, (0.2500 * scl)) ;  local pB1   = Polar2D(pt, ang + 45.0000, (0.3536 * scl)) ;&lt;br /&gt;
     local pB2  = Polar2D(pt, ang + 63.4352, (0.5590 * scl)) ;  local pB3   = Polar2D(pt, ang + 71.5651, (0.7906 * scl)) ;&lt;br /&gt;
     local pB4  = Polar2D(pt, ang + 75.9638, (1.0308 * scl)) ;  local pB5   = Polar2D(pt, ang + 78.6901, (1.2748 * scl)) ;&lt;br /&gt;
     local pB6  = Polar2D(pt, ang + 80.5376, (1.5207 * scl)) ;  local pB7   = Polar2D(pt, ang + 81.8699, (1.7678 * scl)) ;&lt;br /&gt;
     local pB8  = Polar2D(pt, ang + 82.8750, (2.0156 * scl)) ;  local pB10  = Polar2D(pt, ang + 84.2894, (2.5125 * scl)) ;&lt;br /&gt;
     local pC0  = Polar2D(pt, ang +  0.0000, (0.5000 * scl)) ;  local pC1   = Polar2D(pt, ang + 26.5650, (0.5590 * scl)) ;&lt;br /&gt;
     local pC2  = Polar2D(pt, ang + 45.0000, (0.7071 * scl)) ;  local pC3   = Polar2D(pt, ang + 56.3099, (0.9014 * scl)) ;&lt;br /&gt;
     local pC4  = Polar2D(pt, ang + 63.4342, (1.1180 * scl)) ;  local pC5   = Polar2D(pt, ang + 68.1993, (1.3463 * scl)) ;&lt;br /&gt;
     local pC6  = Polar2D(pt, ang + 71.5650, (1.5811 * scl)) ;  local pC7   = Polar2D(pt, ang + 63.4342, (1.1180 * scl)) ;&lt;br /&gt;
     local pC8  = Polar2D(pt, ang + 75.9640, (2.0616 * scl)) ;  local pC10  = Polar2D(pt, ang + 78.6899, (2.5495 * scl)) ;&lt;br /&gt;
     local pD0  = Polar2D(pt, ang +  0.0000, (0.6250 * scl)) ;  local pD1   = Polar2D(pt, ang + 21.8014, (0.6731 * scl)) ;&lt;br /&gt;
     local pD2  = Polar2D(pt, ang + 33.6901, (0.9014 * scl)) ;  local pD4   = Polar2D(pt, ang + 57.9946, (1.1792 * scl)) ;&lt;br /&gt;
     local pD7  = Polar2D(pt, ang + 70.3462, (1.8583 * scl)) ;  local pD8   = Polar2D(pt, ang + 72.6460, (2.0954 * scl)) ;&lt;br /&gt;
     local pE0  = Polar2D(pt, ang +  0.0000, (0.7500 * scl)) ;  local pE1   = Polar2D(pt, ang + 18.4346, (0.7906 * scl)) ;&lt;br /&gt;
     local pE2  = Polar2D(pt, ang + 33.6901, (0.9014 * scl)) ;  local pE3   = Polar2D(pt, ang + 45.0000, (1.0607 * scl)) ;&lt;br /&gt;
     local pE5  = Polar2D(pt, ang + 59.0371, (1.4578 * scl)) ;  local pE6   = Polar2D(pt, ang + 63.4349, (1.6771 * scl)) ;&lt;br /&gt;
     local pE7  = Polar2D(pt, ang + 66.4349, (1.9039 * scl)) ;  local pE8   = Polar2D(pt, ang + 69.4440, (2.1360 * scl)) ;&lt;br /&gt;
     local pF0  = Polar2D(pt, ang +  0.0000, (1.0000 * scl)) ;  local pF1   = Polar2D(pt, ang + 14.0360, (1.0308 * scl)) ;&lt;br /&gt;
     local pF2  = Polar2D(pt, ang + 26.5651, (1.1180 * scl)) ;  local pF3   = Polar2D(pt, ang + 36.8699, (1.2500 * scl)) ;&lt;br /&gt;
     local pF4  = Polar2D(pt, ang + 45.0000, (1.4142 * scl)) ;  local pF5   = Polar2D(pt, ang + 51.3425, (1.6006 * scl)) ;&lt;br /&gt;
     local pF6  = Polar2D(pt, ang + 56.3099, (1.8025 * scl)) ;  local pF7   = Polar2D(pt, ang + 60.2551, (2.0156 * scl)) ;&lt;br /&gt;
     local pF8  = Polar2D(pt, ang + 63.4349, (2.2361 * scl)) ;  local pG0   = Polar2D(pt, ang +  0.0000, (1.2500 * scl)) ;&lt;br /&gt;
     local pG1  = Polar2D(pt, ang + 11.3099, (1.2748 * scl)) ;  local pG2   = Polar2D(pt, ang + 21.8014, (1.3463 * scl)) ;&lt;br /&gt;
     local pG3  = Polar2D(pt, ang + 30.9638, (1.4577 * scl)) ;  local pG4   = Polar2D(pt, ang + 38.6598, (1.6008 * scl)) ;&lt;br /&gt;
     local pG5  = Polar2D(pt, ang + 45.0000, (1.7678 * scl)) ;  local pG6   = Polar2D(pt, ang + 50.1944, (1.9526 * scl)) ;&lt;br /&gt;
     local pG7  = Polar2D(pt, ang + 54.4623, (2.1506 * scl)) ;  local pG8   = Polar2D(pt, ang + 57.9946, (2.3585 * scl)) ;&lt;br /&gt;
     local pG10 = Polar2D(pt,59.0362, (2.9155 * scl))        ;  local pH0   = Polar2D(pt, ang +  0.0000, (1.5000 * scl)) ;&lt;br /&gt;
     local pH10 = Polar2D(pt,63.4349, (2.7951 * scl))        ;  local layer = job.LayerManager:GetLayerWithName(lay) ;&lt;br /&gt;
     local line = Contour(0.0) ;&lt;br /&gt;
    -- ------------------------------------------------------------------------&lt;br /&gt;
     if letter == 32 then&lt;br /&gt;
       pH0 = pH0&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 33 then&lt;br /&gt;
       line:AppendPoint(pB0) ;  line:LineTo(pE0) ;  line:LineTo(pE2) ;  line:LineTo(pB2) ;  line:LineTo(pB0) ;  group:AddTail(line) ;&lt;br /&gt;
       line = Contour(0.0) line:AppendPoint(pB3) ;  line:LineTo(pE3) ;  line:LineTo(pE8) ;  line:LineTo(pB8) ;  line:LineTo(pB3) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 34 then&lt;br /&gt;
       line:AppendPoint(pA7) ;  line:LineTo(pB10) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pB7) ;  line:LineTo(pC10) ;&lt;br /&gt;
       group:AddTail(line) ;  pH0 = pE0&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 35 then&lt;br /&gt;
       line:AppendPoint(pA2) ;  line:LineTo(pG2) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA6) ;&lt;br /&gt;
       line:LineTo(pG6) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pB0) ;  line:LineTo(pB8) ;  group:AddTail(line) ;&lt;br /&gt;
       line = Contour(0.0) ;  line:AppendPoint(pF0) ;  line:LineTo(pF8) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 36 then&lt;br /&gt;
       line:AppendPoint(pA1) ;  line:LineTo(pB0) ;  line:LineTo(pF0) ;  line:LineTo(pG1) ;  line:LineTo(pG3) ;  line:LineTo(pF4) ;&lt;br /&gt;
       line:LineTo(pB4) ;  line:LineTo(pA5) ;  line:LineTo(pA7) ;  line:LineTo(pB8) ;  line:LineTo(pF8) ;  line:LineTo(pG7) ;  group:AddTail(line) ;&lt;br /&gt;
       line = Contour(0.0) ;  line:AppendPoint(pC0) ;  line:LineTo(pE0) ;  line:LineTo(pE8) ;  line:LineTo(pC8) ;  line:LineTo(pC0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 37 then&lt;br /&gt;
       line:AppendPoint(pC6) ;  line:LineTo(pC8) ;  line:LineTo(pA8) ;  line:LineTo(pA6) ;  line:LineTo(pE6) ;  line:LineTo(pG8) ;&lt;br /&gt;
       line:LineTo(pA0) ;  line:LineTo(pC2) ;  line:LineTo(pG2) ;  line:LineTo(pG0) ;  line:LineTo(pE0) ;  line:LineTo(pE2) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 38 then&lt;br /&gt;
       line:AppendPoint(pG2) ;  line:LineTo(pG1) ;  line:LineTo(pF0) ;  line:LineTo(pB0) ;  line:LineTo(pA1) ;  line:LineTo(pA3) ;&lt;br /&gt;
       line:LineTo(pE6) ;  line:LineTo(pE7) ;  line:LineTo(pD8) ;  line:LineTo(pB8) ;  line:LineTo(pA7) ;  line:LineTo(pA6) ;  line:LineTo(pG0) ;&lt;br /&gt;
       group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 39 then&lt;br /&gt;
       line:AppendPoint(pA7) ;  line:LineTo(pB10) ;  group:AddTail(line) ;  pH0 = pC0&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 40 then&lt;br /&gt;
       line:AppendPoint(pB8) ;  line:LineTo(pA5) ;  line:LineTo(pA3) ;  line:LineTo(pB0) ;  group:AddTail(line) ;  pH0 = pD0&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 41 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pB5) ;  line:LineTo(pB3) ;  line:LineTo(pA0) ;  group:AddTail(line) ;  pH0 = pG0&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 42 then&lt;br /&gt;
       line:AppendPoint(pA2) ;  line:LineTo(pG6) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA6) ;  line:LineTo(pG2) ;&lt;br /&gt;
       group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA4) ;  line:LineTo(pG4) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pD7) ;&lt;br /&gt;
       line:LineTo(pD1) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 43 then&lt;br /&gt;
       line:AppendPoint(pA4) ;  line:LineTo(pG4) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pD1) ;  line:LineTo(pD7) ;&lt;br /&gt;
       group:AddTail(line)&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 44 then&lt;br /&gt;
       line:AppendPoint(pC0) ;  line:LineTo(pE2) ;  line:LineTo(pC2) ;  line:LineTo(pC4) ;  line:LineTo(pF4) ;  line:LineTo(pF2) ;&lt;br /&gt;
       line:LineTo(pD0) ;  line:LineTo(pC0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 45 then&lt;br /&gt;
       line:AppendPoint(pA4) ;  line:LineTo(pG4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 46 then&lt;br /&gt;
       line:AppendPoint(pA1) ;  line:LineTo(pB1) ;  line:LineTo(pB0) ;  line:LineTo(pA0) ;  line:LineTo(pA1) ;  group:AddTail(line) ;  pH0 = pD0 ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 47 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pF8) ;  group:AddTail(line) ;  pH0 = pG0 ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 48 then&lt;br /&gt;
       line:AppendPoint(pB0) ;  line:LineTo(pA2) ;  line:LineTo(pA6) ;  line:LineTo(pB8) ;  line:LineTo(pF8) ;  line:LineTo(pG6) ;&lt;br /&gt;
       line:LineTo(pG2) ;  line:LineTo(pF0) ;  line:LineTo(pB0) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pG8) ;  line:LineTo(pA0) ; group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 49 then&lt;br /&gt;
       line:AppendPoint(pA6) ;  line:LineTo(pD8) ;  line:LineTo(pD0) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA0) ;&lt;br /&gt;
       line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 50 then&lt;br /&gt;
       line:AppendPoint(pA6) ;  line:LineTo(pA7) ;  line:LineTo(pB8) ;  line:LineTo(pF8) ;  line:LineTo(pG7) ;  line:LineTo(pG5) ;&lt;br /&gt;
       line:LineTo(pA2) ;  line:LineTo(pA0) ;  line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 51 then&lt;br /&gt;
       line:AppendPoint(pA7) ;  line:LineTo(pB8) ;  line:LineTo(pF8) ;  line:LineTo(pG7) ;  line:LineTo(pG5) ;  line:LineTo(pF4) ;&lt;br /&gt;
       line:LineTo(pG3) ;  line:LineTo(pG1) ;  line:LineTo(pF0) ;  line:LineTo(pB0) ;  line:LineTo(pA1) ;  group:AddTail(line) ;  line = Contour(0.0) ;&lt;br /&gt;
       line:AppendPoint(pF4) ;  line:LineTo(pB4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 52 then&lt;br /&gt;
       line:AppendPoint(pF0) ;  line:LineTo(pF8) ;  line:LineTo(pA2) ;  line:LineTo(pG2) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 53 then&lt;br /&gt;
       line:AppendPoint(pG8) ;  line:LineTo(pA8) ;  line:LineTo(pA5) ;  line:LineTo(pF4) ;  line:LineTo(pG3) ;  line:LineTo(pG1) ;&lt;br /&gt;
       line:LineTo(pF0) ;  line:LineTo(pB0) ;  line:LineTo(pA1) ;  line:LineTo(pA2) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 54 then&lt;br /&gt;
       line:AppendPoint(pG7) ;  line:LineTo(pF8) ;  line:LineTo(pB8) ;  line:LineTo(pA7) ;  line:LineTo(pA1) ;  line:LineTo(pB0) ;&lt;br /&gt;
       line:LineTo(pF0) ;  line:LineTo(pG1) ;  line:LineTo(pG3) ;  line:LineTo(pF4) ;  line:LineTo(pB4) ;  line:LineTo(pA2) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 55 then&lt;br /&gt;
       line:AppendPoint(pB0) ;  line:LineTo(pG8) ;  line:LineTo(pA8) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 56 then&lt;br /&gt;
       line:AppendPoint(pA1) ;  line:LineTo(pB0) ;  line:LineTo(pF0) ;  line:LineTo(pG1) ;  line:LineTo(pG3) ;  line:LineTo(pF4) ;&lt;br /&gt;
       line:LineTo(pG5) ;  line:LineTo(pG7) ;  line:LineTo(pF8) ;  line:LineTo(pB8) ;  line:LineTo(pA7) ;  line:LineTo(pA5) ;  line:LineTo(pB4) ;&lt;br /&gt;
       line:LineTo(pA3) ;  line:LineTo(pA1) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pB4) ;  line:LineTo(pF4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 57 then&lt;br /&gt;
       line:AppendPoint(pA1) ;  line:LineTo(pB0) ;  line:LineTo(pF0) ;  line:LineTo(pG3) ;  line:LineTo(pG7) ;  line:LineTo(pF8) ;&lt;br /&gt;
       line:LineTo(pB8) ;  line:LineTo(pA7) ;  line:LineTo(pA5) ;  line:LineTo(pB4) ;  line:LineTo(pF4) ;  line:LineTo(pG5) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 58 then&lt;br /&gt;
       line:AppendPoint(pB8) ;  line:LineTo(pA8) ;  line:LineTo(pA7) ;  line:LineTo(pB7) ;  line:LineTo(pB8) ;  line:LineTo(pA8) ;&lt;br /&gt;
       group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA1) ;  line:LineTo(pB1) ;  line:LineTo(pB0) ;  line:LineTo(pA0) ;  line:LineTo(pA1) ;&lt;br /&gt;
       group:AddTail(line) ;  pH0 = pD0 ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 59 then&lt;br /&gt;
       line:AppendPoint(pB8) ;  line:LineTo(pA8) ;  line:LineTo(pA7) ;  line:LineTo(pB7) ;  line:LineTo(pB8) ;  line:LineTo(pA8) ;&lt;br /&gt;
       group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pB3) ;  line:LineTo(pB4) ;  line:LineTo(pA4) ;  line:LineTo(pA3) ;  line:LineTo(pB3) ;&lt;br /&gt;
       line:LineTo(pA0) ;  group:AddTail(line) ;  pH0 = pD0 ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 60 then&lt;br /&gt;
       line:AppendPoint(pF8) ;  line:LineTo(pA4) ;  line:LineTo(pG0) ;  group:AddTail(line)&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 61 then&lt;br /&gt;
       line:AppendPoint(pA2) ;  line:LineTo(pG2) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA6) ;&lt;br /&gt;
       line:LineTo(pG6) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 62 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pF4) ;  line:LineTo(pA0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 63 then&lt;br /&gt;
       line:AppendPoint(pB5) ;  line:LineTo(pA6) ;  line:LineTo(pA7) ;  line:LineTo(pB8) ;  line:LineTo(pE8) ;  line:LineTo(pF7) ;&lt;br /&gt;
       line:LineTo(pF5) ;  line:LineTo(pC3) ;  line:LineTo(pC2) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pB0) ;  line:LineTo(pE0) ;&lt;br /&gt;
       line:LineTo(pE1) ;  line:LineTo(pB1) ;  line:LineTo(pB0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 64 then&lt;br /&gt;
       line:AppendPoint(pG0) ;  line:LineTo(pB0) ;  line:LineTo(pA2) ;  line:LineTo(pA6) ;  line:LineTo(pB8) ;  line:LineTo(pF8) ;&lt;br /&gt;
       line:LineTo(pG6) ;  line:LineTo(pG3) ;  line:LineTo(pE2) ;  line:LineTo(pB2) ;  line:LineTo(pB5) ;  line:LineTo(pE5) ;  line:LineTo(pE2) ;&lt;br /&gt;
       group:AddTail(line)&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 65 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pD8) ;  line:LineTo(pG0) ;  line:LineTo(pF3) ;  line:LineTo(pB3) ;&lt;br /&gt;
       line:LineTo(pA0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 66 then&lt;br /&gt;
       line:AppendPoint(pA4) ;  line:LineTo(pF4) ;  line:LineTo(pG5) ;  line:LineTo(pG7) ;  line:LineTo(pF8) ;  line:LineTo(pA8) ;&lt;br /&gt;
       line:LineTo(pA0) ;  line:LineTo(pF0) ;  line:LineTo(pG1) ;  line:LineTo(pG3) ;  line:LineTo(pF4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 67 then&lt;br /&gt;
       line:AppendPoint(pG2) ;  line:LineTo(pF0) ;  line:LineTo(pB0) ;  line:LineTo(pA2) ;  line:LineTo(pA6) ;  line:LineTo(pB8) ;&lt;br /&gt;
       line:LineTo(pF8) ;  line:LineTo(pG6) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 68 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pF0) ;  line:LineTo(pG2) ;  line:LineTo(pG6) ;  line:LineTo(pF8) ;  line:LineTo(pA8) ;&lt;br /&gt;
       line:LineTo(pA0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 69 then&lt;br /&gt;
       line:AppendPoint(pG0) ;  line:LineTo(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pF8) ;  group:AddTail(line) ;  line = Contour(0.0) ;&lt;br /&gt;
       line:AppendPoint(pA4) ;  line:LineTo(pD4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 70 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pG8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA4) ;&lt;br /&gt;
       line:LineTo(pF4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 71 then&lt;br /&gt;
       line:AppendPoint(pG6) ;  line:LineTo(pG7) ;  line:LineTo(pF8) ;  line:LineTo(pB8) ;  line:LineTo(pA6) ;  line:LineTo(pA2) ;&lt;br /&gt;
       line:LineTo(pB0) ;  line:LineTo(pF0) ;  line:LineTo(pG2) ;  line:LineTo(pG3) ;  line:LineTo(pE3) ;  line:LineTo(pE2) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 72 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pG0) ;  line:LineTo(pG8) ;&lt;br /&gt;
       group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA4) ;  line:LineTo(pG4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 73 then&lt;br /&gt;
       line:AppendPoint(pB0) ;  line:LineTo(pB8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA0) ;  line:LineTo(pC0) ;&lt;br /&gt;
       group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA8) ;  line:LineTo(pC8) ;  group:AddTail(line) ;  pH0 = pE0 ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 74 then&lt;br /&gt;
       line:AppendPoint(pA2) ;  line:LineTo(pB0) ;  line:LineTo(pF0) ;  line:LineTo(pG2) ;  line:LineTo(pG8) ;  line:LineTo(pC8) ;&lt;br /&gt;
       group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 75 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA2) ;  line:LineTo(pG7) ;&lt;br /&gt;
       group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pD4) ;  line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 76 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pA0) ;  line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 77 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pD4) ;  line:LineTo(pG8) ;  line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 78 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pF0) ;  line:LineTo(pF8) ;  group:AddTail(line) ;  pH0 = pG0 ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 79 then&lt;br /&gt;
       line:AppendPoint(pB0) ;  line:LineTo(pA2) ;  line:LineTo(pA6) ;  line:LineTo(pB8) ;  line:LineTo(pF8) ;  line:LineTo(pG6) ;&lt;br /&gt;
       line:LineTo(pG2) ;  line:LineTo(pF0) ;  line:LineTo(pB0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 80 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pF8) ;  line:LineTo(pG7) ;  line:LineTo(pG5) ;  line:LineTo(pF4) ;&lt;br /&gt;
       line:LineTo(pA4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 81 then&lt;br /&gt;
       line:AppendPoint(pB0) ;  line:LineTo(pA2) ;  line:LineTo(pA6) ;  line:LineTo(pB8) ;  line:LineTo(pF8) ;  line:LineTo(pG6) ;&lt;br /&gt;
       line:LineTo(pG2) ;  line:LineTo(pF0) ;  line:LineTo(pB0) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pG0) ;  line:LineTo(pD4) ; group:AddTail(line)&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 82 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pF8) ;  line:LineTo(pG7) ;  line:LineTo(pG5) ;  line:LineTo(pF4) ;&lt;br /&gt;
       line:LineTo(pA4) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pD4) ;  line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 83 then&lt;br /&gt;
       line:AppendPoint(pG5) ;  line:LineTo(pG6) ;  line:LineTo(pF8) ;  line:LineTo(pB8) ;  line:LineTo(pA6) ;  line:LineTo(pA5) ;&lt;br /&gt;
       line:LineTo(pG3) ;  line:LineTo(pG2) ;  line:LineTo(pF0) ;  line:LineTo(pB0) ;  line:LineTo(pA2) ;  line:LineTo(pA3) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 84 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pG8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pD8) ;&lt;br /&gt;
       line:LineTo(pD0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 85 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pA2) ;  line:LineTo(pB0) ;  line:LineTo(pF0) ;  line:LineTo(pG2) ;  line:LineTo(pG8) ;&lt;br /&gt;
       group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 86 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pD0) ;  line:LineTo(pG8) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 87 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pB0) ;  line:LineTo(pD4) ;  line:LineTo(pF0) ;  line:LineTo(pG8) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 88 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pG8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA8) ;&lt;br /&gt;
       line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 89 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pD4) ;  line:LineTo(pG8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pD0) ;&lt;br /&gt;
       line:LineTo(pD4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 90 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pG8) ;  line:LineTo(pA0) ;  line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
 &lt;br /&gt;
     if letter == 91 then&lt;br /&gt;
       line:AppendPoint(pC0) ;  line:LineTo(pB0) ;  line:LineTo(pB8) ;  line:LineTo(pC8) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 92 then&lt;br /&gt;
       line:AppendPoint(pA4) ;  line:LineTo(pG4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 93 then&lt;br /&gt;
       line:AppendPoint(pE0) ;  line:LineTo(pF0) ;  line:LineTo(pF8) ;  line:LineTo(pE8) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 94 then&lt;br /&gt;
       line:AppendPoint(pD8) ;  line:LineTo(pG6) ;  line:LineTo(pG5) ;  line:LineTo(pD7) ;  line:LineTo(pA5) ;  line:LineTo(pA6) ;&lt;br /&gt;
       line:LineTo(pD8) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 95 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pF0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 96 then&lt;br /&gt;
       line:AppendPoint(pA4) ;  line:LineTo(pG4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     -- Start of Lower Case&lt;br /&gt;
     if letter == 97 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pD8) ;  line:LineTo(pG0) ;  line:LineTo(pF3) ;  line:LineTo(pB3) ;&lt;br /&gt;
       line:LineTo(pA0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 98 then&lt;br /&gt;
       line:AppendPoint(pA4) ;  line:LineTo(pF4) ;  line:LineTo(pG5) ;  line:LineTo(pG7) ;  line:LineTo(pF8) ;  line:LineTo(pA8) ;&lt;br /&gt;
       line:LineTo(pA0) ;  line:LineTo(pF0) ;  line:LineTo(pG1) ;  line:LineTo(pG3) ;  line:LineTo(pF4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 99 then&lt;br /&gt;
       line:AppendPoint(pG2) ;  line:LineTo(pF0) ;  line:LineTo(pB0) ;  line:LineTo(pA2) ;  line:LineTo(pA6) ;  line:LineTo(pB8) ;&lt;br /&gt;
       line:LineTo(pF8) ;  line:LineTo(pG6) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 100 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pF0) ;  line:LineTo(pG2) ;  line:LineTo(pG6) ;  line:LineTo(pF8) ;  line:LineTo(pA8) ;&lt;br /&gt;
       line:LineTo(pA0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 101 then&lt;br /&gt;
       line:AppendPoint(pG0) ;  line:LineTo(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pF8) ;  group:AddTail(line) ;  line = Contour(0.0) ;&lt;br /&gt;
       line:AppendPoint(pA4) ;  line:LineTo(pD4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 102 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pG8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA4) ;&lt;br /&gt;
       line:LineTo(pF4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 103 then&lt;br /&gt;
       line:AppendPoint(pG6) ;  line:LineTo(pG7) ;  line:LineTo(pF8) ;  line:LineTo(pB8) ;  line:LineTo(pA6) ;  line:LineTo(pA2) ;&lt;br /&gt;
       line:LineTo(pB0) ;  line:LineTo(pF0) ;  line:LineTo(pG2) ;  line:LineTo(pG3) ;  line:LineTo(pE3) ;  line:LineTo(pE2) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 104 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pG0) ;  line:LineTo(pG8) ;&lt;br /&gt;
       group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA4) ;  line:LineTo(pG4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 105 then&lt;br /&gt;
       line:AppendPoint(pB0) ;  line:LineTo(pB8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA0) ;  line:LineTo(pC0) ;&lt;br /&gt;
       group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA8) ;  line:LineTo(pC8) ;  group:AddTail(line) ;  pH0 = pE0 ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 106 then&lt;br /&gt;
       line:AppendPoint(pA2) ;  line:LineTo(pB0) ;  line:LineTo(pF0) ;  line:LineTo(pG2) ;  line:LineTo(pG8) ;  line:LineTo(pC8) ;&lt;br /&gt;
       group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 107 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA2) ;  line:LineTo(pG7) ;&lt;br /&gt;
       group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pD4) ;  line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 108 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pA0) ;  line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 109 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pD4) ;  line:LineTo(pG8) ;  line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 110 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pF0) ;  line:LineTo(pF8) ;  group:AddTail(line) ;  pH0 = pG0 ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 111 then&lt;br /&gt;
       line:AppendPoint(pB0) ;  line:LineTo(pA2) ;  line:LineTo(pA6) ;  line:LineTo(pB8) ;  line:LineTo(pF8) ;  line:LineTo(pG6) ;&lt;br /&gt;
       line:LineTo(pG2) ;  line:LineTo(pF0) ;  line:LineTo(pB0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 112 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pF8) ;  line:LineTo(pG7) ;  line:LineTo(pG5) ;  line:LineTo(pF4) ;&lt;br /&gt;
       line:LineTo(pA4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 113 then&lt;br /&gt;
       line:AppendPoint(pB0) ;  line:LineTo(pA2) ;  line:LineTo(pA6) ;  line:LineTo(pB8) ;  line:LineTo(pF8) ;  line:LineTo(pG6) ;&lt;br /&gt;
       line:LineTo(pG2) ;  line:LineTo(pF0) ;  line:LineTo(pB0) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pG0) ;  line:LineTo(pD4) ; group:AddTail(line)&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 114 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pF8) ;  line:LineTo(pG7) ;  line:LineTo(pG5) ;  line:LineTo(pF4) ;&lt;br /&gt;
       line:LineTo(pA4) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pD4) ;  line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 115 then&lt;br /&gt;
       line:AppendPoint(pG5) ;  line:LineTo(pG6) ;  line:LineTo(pF8) ;  line:LineTo(pB8) ;  line:LineTo(pA6) ;  line:LineTo(pA5) ;&lt;br /&gt;
       line:LineTo(pG3) ;  line:LineTo(pG2) ;  line:LineTo(pF0) ;  line:LineTo(pB0) ;  line:LineTo(pA2) ;  line:LineTo(pA3) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 116 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pG8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pD8) ;&lt;br /&gt;
       line:LineTo(pD0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 117 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pA2) ;  line:LineTo(pB0) ;  line:LineTo(pF0) ;  line:LineTo(pG2) ;  line:LineTo(pG8) ;&lt;br /&gt;
       group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 118 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pD0) ;  line:LineTo(pG8) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 119 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pB0) ;  line:LineTo(pD4) ;  line:LineTo(pF0) ;  line:LineTo(pG8) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 120 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pG8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA8) ;&lt;br /&gt;
       line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 121 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pD4) ;  line:LineTo(pG8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pD0) ;&lt;br /&gt;
       line:LineTo(pD4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 122 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pG8) ;  line:LineTo(pA0) ;  line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     -- End of Lower Case&lt;br /&gt;
     if letter == 123 then&lt;br /&gt;
       line:AppendPoint(pD0) ;  line:LineTo(pC0) ;  line:LineTo(pB1) ;  line:LineTo(pB2) ;  line:LineTo(pC3) ;  line:LineTo(pA4) ;&lt;br /&gt;
       line:LineTo(pC5) ;  line:LineTo(pB6) ;  line:LineTo(pB7) ;  line:LineTo(pC8) ;  line:LineTo(pD8) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 124 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA10) ;  line:LineTo(pC10) ;  line:LineTo(pC0) ;  line:LineTo(pA0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 125 then&lt;br /&gt;
       line:AppendPoint(pD0) ;  line:LineTo(pE0) ;  line:LineTo(pF1) ;  line:LineTo(pF2) ;  line:LineTo(pE3) ;  line:LineTo(pG4) ;&lt;br /&gt;
       line:LineTo(pE5) ;  line:LineTo(pF6) ;  line:LineTo(pF7) ;  line:LineTo(pE8) ;  line:LineTo(pD8) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 126 then&lt;br /&gt;
       line:AppendPoint(pA2) ;  line:LineTo(pA3) ;  line:LineTo(pB5) ;  line:LineTo(pF3) ;  line:LineTo(pG5) ;&lt;br /&gt;
       line:LineTo(pG4) ;  line:LineTo(pF2) ;  line:LineTo(pB4) ;  line:LineTo(pA2) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     return pH0&lt;br /&gt;
   end -- function end&lt;br /&gt;
 &lt;br /&gt;
   -- =========================================================================&lt;br /&gt;
   local function AddGroupToJob(job, group, layer_name)&lt;br /&gt;
      --  create a CadObject to represent the  group&lt;br /&gt;
     local cad_object = CreateCadGroup(group);&lt;br /&gt;
      -- create a layer with passed name if it doesnt already exist&lt;br /&gt;
     local layer = job.LayerManager:GetLayerWithName(layer_name)&lt;br /&gt;
      -- and add our object to it&lt;br /&gt;
     layer:AddObject(cad_object, true)&lt;br /&gt;
     return cad_object&lt;br /&gt;
   end -- end function&lt;br /&gt;
 &lt;br /&gt;
   -- =========================================================================&lt;br /&gt;
     local job = VectricJob()&lt;br /&gt;
     if not job.Exists then&lt;br /&gt;
       DisplayMessageBox(&amp;quot;Error: Not finding a job loaded&amp;quot;)&lt;br /&gt;
       return false&lt;br /&gt;
     end&lt;br /&gt;
     local strlen = string.len(what)&lt;br /&gt;
     local strup = what&lt;br /&gt;
     local x = strlen&lt;br /&gt;
     local i = 1&lt;br /&gt;
     local y = &amp;quot;&amp;quot;&lt;br /&gt;
     local ptx = where&lt;br /&gt;
     group = ContourGroup(true)&lt;br /&gt;
     while i &amp;lt;=  x do&lt;br /&gt;
       y = string.byte(string.sub(strup, i, i))&lt;br /&gt;
       if (y &amp;gt;= 97) and (y &amp;lt;= 122) then -- Lower case&lt;br /&gt;
         ptx = MonoFont(job, ptx, y, (size * 0.75), lay, ang)&lt;br /&gt;
         ptx = Polar2D(ptx, ang, size * 0.05)&lt;br /&gt;
       else -- Upper case&lt;br /&gt;
         ptx = MonoFont(job, ptx, y, size, lay, ang)&lt;br /&gt;
         ptx = Polar2D(ptx, ang, size * 0.07)&lt;br /&gt;
       end&lt;br /&gt;
       i = i + 1&lt;br /&gt;
     end -- while end;&lt;br /&gt;
     AddGroupToJob(job, group, lay)&lt;br /&gt;
     job:Refresh2DView()&lt;br /&gt;
     return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Holer - Draws two Holes and groups them===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws circles based on a layout.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function Holer(pt, ang, dst, dia, lay)&lt;br /&gt;
       local job = VectricJob()&lt;br /&gt;
       if not job.Exists then&lt;br /&gt;
         DisplayMessageBox(&amp;quot;Error: No job loaded&amp;quot;)&lt;br /&gt;
         return false&lt;br /&gt;
       end&lt;br /&gt;
     --Caller: Holer(ptx, anx, BaseDim.HoleSpace, Milling.ShelfPinRadius, Milling.LNSideShelfPinDrill .. &amp;quot;-Base&amp;quot;)&lt;br /&gt;
       local function AddGroupToJob(job, group, layer_name)&lt;br /&gt;
         local cad_object = CreateCadGroup(group);&lt;br /&gt;
         local layer = job.LayerManager:GetLayerWithName(layer_name)&lt;br /&gt;
         layer:AddObject(cad_object, true)&lt;br /&gt;
         return cad_object&lt;br /&gt;
       end&lt;br /&gt;
     local group = ContourGroup(true)&lt;br /&gt;
     group:AddTail(CreateCircle(pt.x, pt.y, dia, 0.0, 0.0))&lt;br /&gt;
     pt = Polar2D(pt, ang, dst)&lt;br /&gt;
     group:AddTail(CreateCircle(pt.x, pt.y, dia, 0.0, 0.0))&lt;br /&gt;
     AddGroupToJob(job, group, lay)&lt;br /&gt;
     return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Data Export Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
 &lt;br /&gt;
===LogWriter===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
&lt;br /&gt;
Writes a Log items to the log file.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function LogWriter(LogName, xText)&lt;br /&gt;
  -- Adds a new xText Line to a app log file&lt;br /&gt;
  -- local LogName = Door.CSVPath .. &amp;quot;\\&amp;quot; .. Door.RuntimeLog .. &amp;quot;.txt&amp;quot;&lt;br /&gt;
  local fileW = io.open(LogName,  &amp;quot;a&amp;quot;)&lt;br /&gt;
  if fileW then&lt;br /&gt;
    fileW:write(xText .. &amp;quot;\n&amp;quot;)&lt;br /&gt;
    fileW:close()&lt;br /&gt;
  end -- if end&lt;br /&gt;
  Maindialog:UpdateLabelField(&amp;quot;Door.Alert&amp;quot;, &amp;quot;Note: Errors are logged in the CSF file folder.&amp;quot;)&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
===Write_CSV===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
Writes the values to a csv format file.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function Write_CSV(xFilename) -- Writes the values to a csv format file&lt;br /&gt;
 -- Usage: Write_CSV(&amp;quot;C:\\Path\\MyName.csv&amp;quot;)&lt;br /&gt;
 -- Door.CSVPath = dialog:GetTextField(&amp;quot;DoorCSVPath&amp;quot;)&lt;br /&gt;
 -- local filename = Path .. &amp;quot;\\&amp;quot; .. Name .. &amp;quot;.csv&amp;quot;&lt;br /&gt;
  local filename = xFilename&lt;br /&gt;
  local file = io.open(filename, &amp;quot;w&amp;quot;)&lt;br /&gt;
  if file then  -- if the file was opened&lt;br /&gt;
    file:write(&amp;quot;Count,Height,Width\n&amp;quot;)  -- Header Line&lt;br /&gt;
    if Door.Unit then&lt;br /&gt;
      file:write(&amp;quot;1,110,595\n&amp;quot;);    file:write(&amp;quot;1,150,75\n&amp;quot;);     file:write(&amp;quot;1,175,395\n&amp;quot;);     file:write(&amp;quot;1,140,495\n&amp;quot;)&lt;br /&gt;
      file:write(&amp;quot;1,175,445\n&amp;quot;);    file:write(&amp;quot;1,175,595\n&amp;quot;);    file:write(&amp;quot;2,200,100\n&amp;quot;);     file:write(&amp;quot;3,250,125\n&amp;quot;)&lt;br /&gt;
      file:write(&amp;quot;1,300,150\n&amp;quot;);    file:write(&amp;quot;2,350,175\n&amp;quot;);    file:write(&amp;quot;3,400,200\n&amp;quot;);     file:write(&amp;quot;1,450,225\n&amp;quot;)&lt;br /&gt;
      file:write(&amp;quot;2,500,250\n&amp;quot;);    file:write(&amp;quot;3,550,275\n&amp;quot;);    file:write(&amp;quot;1,600,300\n&amp;quot;);     file:write(&amp;quot;2,650,325\n&amp;quot;)&lt;br /&gt;
      file:write(&amp;quot;3,700,350\n&amp;quot;);    file:write(&amp;quot;1,750,375\n&amp;quot;);    file:write(&amp;quot;2,800,400\n&amp;quot;);     file:write(&amp;quot;3,850,425\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;1,900,450\n&amp;quot;);    file:write(&amp;quot;2,950,475\n&amp;quot;);    file:write(&amp;quot;3,1000,500\n&amp;quot;);    file:write(&amp;quot;1,1050,525\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;2,1100,550\n&amp;quot;);   file:write(&amp;quot;3,1150,575\n&amp;quot;);   file:write(&amp;quot;1,1200,600\n&amp;quot;);    file:write(&amp;quot;2,1250,625\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;3,1300,650\n&amp;quot;);   file:write(&amp;quot;1,1350,675\n&amp;quot;);   file:write(&amp;quot;2,1400,700\n&amp;quot;);    file:write(&amp;quot;3,1450,725\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;1,1500,750\n&amp;quot;);   file:write(&amp;quot;2,1550,775\n&amp;quot;);   file:write(&amp;quot;3,1600,800\n&amp;quot;);    file:write(&amp;quot;1,1650,825\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;2,1700,850\n&amp;quot;);   file:write(&amp;quot;3,1750,875\n&amp;quot;);   file:write(&amp;quot;1,1800,900\n&amp;quot;);    file:write(&amp;quot;2,1850,925\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;3,1900,950\n&amp;quot;);   file:write(&amp;quot;1,1950,975\n&amp;quot;);   file:write(&amp;quot;2,2000,1000\n&amp;quot;);   file:write(&amp;quot;3,2050,1025\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;1,2100,1050\n&amp;quot;);  file:write(&amp;quot;2,2150,1075\n&amp;quot;);  file:write(&amp;quot;3,2200,1100\n&amp;quot;);   file:write(&amp;quot;1,2250,1125\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;2,2300,1150\n&amp;quot;);  file:write(&amp;quot;3,2350,1175\n&amp;quot;);  file:write(&amp;quot;1,2400,1200\n&amp;quot;);   file:write(&amp;quot;2,2450,1225\n&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      file:write(&amp;quot;1,04.5000,23.2500\n&amp;quot;);  file:write(&amp;quot;1,06.0000,03.3125\n&amp;quot;);  file:write(&amp;quot;1,06.5000,15.5000\n&amp;quot;);  file:write(&amp;quot;1,05.3750,19.5000\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;1,07.1875,17.5000\n&amp;quot;);  file:write(&amp;quot;1,06.1875,23.5000\n&amp;quot;);  file:write(&amp;quot;2,07.8750,03.8750\n&amp;quot;);  file:write(&amp;quot;3,09.8750,05.0000\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;1,11.7500,05.8750\n&amp;quot;);  file:write(&amp;quot;2,13.7500,06.6750\n&amp;quot;);  file:write(&amp;quot;3,15.7500,07.8750\n&amp;quot;);  file:write(&amp;quot;1,17.1250,08.8250\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;2,19.5000,09.5000\n&amp;quot;);  file:write(&amp;quot;3,21.1250,10.3750\n&amp;quot;);  file:write(&amp;quot;1,23.6250,11.1250\n&amp;quot;);  file:write(&amp;quot;2,25.5000,12.1250\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;3,27.6250,13.7500\n&amp;quot;);  file:write(&amp;quot;1,29.5000,14.7500\n&amp;quot;);  file:write(&amp;quot;2,31.4375,15.7500\n&amp;quot;);  file:write(&amp;quot;3,33.4375,16.7500\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;1,35.4375,17.7500\n&amp;quot;);  file:write(&amp;quot;2,37.4375,18.6250\n&amp;quot;);  file:write(&amp;quot;3,39.3750,19.6250\n&amp;quot;);  file:write(&amp;quot;1,41.3750,20.6250\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;2,43.3750,21.6250\n&amp;quot;);  file:write(&amp;quot;3,45.1875,22.6250\n&amp;quot;);  file:write(&amp;quot;1,47.2500,23.6250\n&amp;quot;);  file:write(&amp;quot;2,49.1875,24.6250\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;3,51.1250,25.5000\n&amp;quot;);  file:write(&amp;quot;1,53.1250,26.5000\n&amp;quot;);  file:write(&amp;quot;2,55.1250,27.5000\n&amp;quot;);  file:write(&amp;quot;3,57.1250,28.5000\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;1,59.1250,29.5000\n&amp;quot;);  file:write(&amp;quot;2,61.2500,30.5000\n&amp;quot;);  file:write(&amp;quot;3,62.9375,31.4375\n&amp;quot;);  file:write(&amp;quot;1,64.9375,32.4375\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;2,66.9375,33.4375\n&amp;quot;);  file:write(&amp;quot;3,68.8125,34.4375\n&amp;quot;);  file:write(&amp;quot;1,70.8750,35.3750\n&amp;quot;);  file:write(&amp;quot;2,72.9375,36.4375\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;3,74.8750,37.4375\n&amp;quot;);  file:write(&amp;quot;1,76.9375,38.3750\n&amp;quot;);  file:write(&amp;quot;2,78.7500,39.3750\n&amp;quot;);  file:write(&amp;quot;3,80.7500,40.3750\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;1,82.6250,41.3750\n&amp;quot;);  file:write(&amp;quot;2,84.6250,42.3750\n&amp;quot;);  file:write(&amp;quot;3,86.6250,43.3750\n&amp;quot;);  file:write(&amp;quot;1,88.5000,44.2500\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;2,90.6250,45.2500\n&amp;quot;);  file:write(&amp;quot;3,92.6250,46.2500\n&amp;quot;);  file:write(&amp;quot;1,94.4375,47.2500\n&amp;quot;);  file:write(&amp;quot;2,95.4375,48.2500\n&amp;quot;)&lt;br /&gt;
    end -- if end&lt;br /&gt;
    file:close() -- closes the open file&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return  true&lt;br /&gt;
end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Text File Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
&lt;br /&gt;
===LengthOfFile===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns file line count&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function LengthOfFile(filename)&lt;br /&gt;
    Returns: number]]&lt;br /&gt;
    local len = 0&lt;br /&gt;
    if FileExists(filename) then&lt;br /&gt;
      local file = io.open(filename)&lt;br /&gt;
      if file then&lt;br /&gt;
      for _ in file:lines() do&lt;br /&gt;
        len = len + 1&lt;br /&gt;
      end&lt;br /&gt;
      file:close()&lt;br /&gt;
    end -- if end&lt;br /&gt;
    end&lt;br /&gt;
    return len&lt;br /&gt;
end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===NameValidater - Checks File Name for Valid Chars===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns file line count&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function NameValidater(FileName)&lt;br /&gt;
    local MyTrue = true&lt;br /&gt;
    local strlen = string.len(FileName)&lt;br /&gt;
    local strup = string.upper(FileName)&lt;br /&gt;
    local i = 1&lt;br /&gt;
    local y = &amp;quot;&amp;quot;&lt;br /&gt;
    while i &amp;lt;=  strlen do&lt;br /&gt;
      y = string.byte(string.sub(strup, i, i))&lt;br /&gt;
      if y == 32 then   --  Space&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
      elseif y == 45 then  -- Dash&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
      elseif y == 127 then  -- Delete&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
      elseif y == 126 then  -- Delete&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
&lt;br /&gt;
       elseif y == 123 then  -- Open brace&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
      elseif y == 124 then  -- Pipe&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
      elseif y == 125 then  -- Close brace&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
&lt;br /&gt;
      elseif  -- Illegal Filename Characters&lt;br /&gt;
      (y == 33) or -- !	Exclamation mark&lt;br /&gt;
      (y == 34) or -- &amp;quot;	Double Quotes&lt;br /&gt;
      (y == 35) or -- #	Hash&lt;br /&gt;
      (y == 36) or -- $	Dollar&lt;br /&gt;
      (y == 37) or -- %	Percent&lt;br /&gt;
      (y == 38) or -- &amp;amp;	Ampersand&lt;br /&gt;
      (y == 39) or -- '	Apostrophe&lt;br /&gt;
      (y == 42) or -- *	Asterisk&lt;br /&gt;
      (y == 43) or -- +	Plus&lt;br /&gt;
      (y == 44) or -- ,	Comma&lt;br /&gt;
      (y == 47) or -- /	Slash&lt;br /&gt;
      (y == 58) or -- :	Colon&lt;br /&gt;
      (y == 59) or -- ;	Semi-colon&lt;br /&gt;
      (y == 60) or -- &amp;lt;	Less than&lt;br /&gt;
      (y == 62) or -- &amp;gt;	Greater than&lt;br /&gt;
      (y == 63) or -- ?	Question mark&lt;br /&gt;
      (y == 64) or -- @	At&lt;br /&gt;
      (y == 92) or -- \	Backslash&lt;br /&gt;
      (y == 96) or -- `	Single Quotes&lt;br /&gt;
      (y == 123) or -- { Open brace&lt;br /&gt;
      (y == 124) or -- | Pipe&lt;br /&gt;
      (y == 125)    -- } Close brace&lt;br /&gt;
      then&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
      elseif (y &amp;lt;= 31) then -- Control Codes&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
      elseif (y &amp;gt;= 48) and (y &amp;lt;= 57) then -- Numbers&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
      elseif (y &amp;gt;= 65) and (y &amp;lt;= 90) then -- Uppercase A to Z&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
      elseif (y &amp;gt;= 97) and (y &amp;lt;= 122) then -- Lowercase A to Z&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
      elseif (y &amp;gt;= 65) and (y &amp;lt;= 90) then -- Uppercase A to Z&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
      end -- if end&lt;br /&gt;
      i = i + 1  end -- while end;&lt;br /&gt;
    return MyTrue&lt;br /&gt;
end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CopyFileFromTo===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
Copy Old File to Newfile&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function CopyFileFromTo(OldFile, NewFile)&lt;br /&gt;
    if FileExists(NewFile) then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;File copy &amp;quot; .. File .. &amp;quot; failed. \n\nFile found at: &amp;quot; .. NewFile  .. &amp;quot;\n&amp;quot; )&lt;br /&gt;
      return false&lt;br /&gt;
    elseif not FileExists(OldFile) then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;File copy of &amp;quot; .. File .. &amp;quot; failed. \n\nFile not found at: &amp;quot; .. OldFile .. &amp;quot;\n&amp;quot; )&lt;br /&gt;
      return false&lt;br /&gt;
    else&lt;br /&gt;
      local fileR = io.open(OldFile)      -- reader file&lt;br /&gt;
      local fileW = io.open(NewFile, &amp;quot;w&amp;quot;) -- writer file&lt;br /&gt;
      if fileR and fileW then  -- if both files are open&lt;br /&gt;
        for Line in fileR:lines() do&lt;br /&gt;
          fileW:write(Line .. &amp;quot;\n&amp;quot;)&lt;br /&gt;
        end -- for end&lt;br /&gt;
      end&lt;br /&gt;
      if fileR then fileR:close() end&lt;br /&gt;
      if fileW then fileW:close() end&lt;br /&gt;
      return true&lt;br /&gt;
    end -- for end&lt;br /&gt;
end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===ValidateName===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns True if the file name is safe to use&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function ValidateName(FileName) &lt;br /&gt;
  local MyTrue = true&lt;br /&gt;
  local strlen = string.len(FileName)&lt;br /&gt;
  local strup = string.upper(FileName)&lt;br /&gt;
  local i = 1&lt;br /&gt;
  local y = &amp;quot;&amp;quot;&lt;br /&gt;
  while i &amp;lt;=  strlen do&lt;br /&gt;
    y = string.byte(string.sub(strup, i, i))&lt;br /&gt;
    if y == 32 then -- Space&lt;br /&gt;
      MyTrue = true&lt;br /&gt;
    elseif y == 45 then -- hyphn&lt;br /&gt;
      MyTrue = true&lt;br /&gt;
    elseif (y &amp;gt;= 48) and (y &amp;lt;= 57) then -- numbers&lt;br /&gt;
      MyTrue = true&lt;br /&gt;
    elseif (y &amp;gt;= 65) and (y &amp;lt;= 90) then -- Uppercase&lt;br /&gt;
      MyTrue = true&lt;br /&gt;
    else&lt;br /&gt;
      MyTrue = false&lt;br /&gt;
      break&lt;br /&gt;
    end -- if end&lt;br /&gt;
    i = i + 1&lt;br /&gt;
  end -- while end&lt;br /&gt;
  return MyTrue&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===FileExists===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns True if file is found&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function FileExists(name)  &lt;br /&gt;
  -- call = ans = FileExists(&amp;quot;sample.txt&amp;quot;)&lt;br /&gt;
    local f=io.open(name,&amp;quot;r&amp;quot;)&lt;br /&gt;
    if f~=nil then io.close(f) return true else io.close(f) return false end&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===FileAccess===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns true if file is available for update.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function FileAccess(FileName) &lt;br /&gt;
    if (not(os.rename(FileName, FileName))) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, FileName, &amp;quot;The Gadget cannot access the &amp;quot;.. FileName ..&lt;br /&gt;
        &amp;quot; The OS has blocked write access. &amp;quot; ..&lt;br /&gt;
        &amp;quot;Verify the full path is correct and No application has the file open. &amp;quot;, &amp;quot;(1405)&amp;quot;)&lt;br /&gt;
        return false&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end -- if end&lt;br /&gt;
end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===IsDir===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns true if path is found&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function IsDir(path)                                  -- &lt;br /&gt;
  local function exists(file)&lt;br /&gt;
    local ok, err, code = os.rename(file, file)&lt;br /&gt;
    if not ok then&lt;br /&gt;
      if code == 13 then&lt;br /&gt;
        return true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    return ok, err&lt;br /&gt;
  end&lt;br /&gt;
  return exists(path..&amp;quot;/&amp;quot;)&lt;br /&gt;
end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Sheetlabel===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns file line count of a txt (assic) file&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function Sheetlabel(Wpt, xTextHeight,  xThickness, xType, YY) -- Constructs sheet label&lt;br /&gt;
  local pt1Text = Point2D()&lt;br /&gt;
  local Pang    = 0.0&lt;br /&gt;
  local Tang    = 0.0&lt;br /&gt;
  if YY then&lt;br /&gt;
    pt1Text = Polar2D(Polar2D(Wpt, 90.0,  YY), 90.0,  6.0 * JimAndi.Cal)&lt;br /&gt;
    Pang = 270.0&lt;br /&gt;
    Tang = 0.0&lt;br /&gt;
  else&lt;br /&gt;
    if Material.Orientation == &amp;quot;V&amp;quot; then&lt;br /&gt;
      pt1Text = Polar2D(Wpt, 90.0, Milling.MaterialBlockWidth + (4.0 * JimAndi.Cal))&lt;br /&gt;
    else&lt;br /&gt;
      pt1Text = Polar2D(Wpt, 90.0,  Milling.MaterialBlockHeight + (4.0 * JimAndi.Cal))&lt;br /&gt;
    end&lt;br /&gt;
    Pang = 270.0&lt;br /&gt;
    Tang = 0.0&lt;br /&gt;
  end&lt;br /&gt;
  DrawWriter(Project.ProgramName, pt1Text, Milling.TextHeight * 3.0, JimAndi.LNDrawNotes, Tang)&lt;br /&gt;
  pt1Text = Polar2D(pt1Text, Pang, Milling.TextHeight * 3.35)&lt;br /&gt;
  DrawWriter(&amp;quot;Cabinet ID: &amp;quot; .. Project.DrawerID, pt1Text, JimAndi.TextHeight * 2.0, JimAndi.LNDrawNotes, Tang)&lt;br /&gt;
  pt1Text = Polar2D(pt1Text, Pang, Milling.TextHeight * 2.75)&lt;br /&gt;
  DrawWriter(&amp;quot;Cabinet Name: &amp;quot; .. Project.CabinetName, pt1Text, JimAndi.TextHeight * 2.0, JimAndi.LNDrawNotes, Tang)&lt;br /&gt;
  pt1Text = Polar2D(pt1Text, Pang, Milling.TextHeight * 2.75)&lt;br /&gt;
  if xThickness then&lt;br /&gt;
    DrawWriter(&amp;quot;Material: &amp;quot; .. xThickness .. &amp;quot; &amp;quot; .. xType, pt1Text, JimAndi.TextHeight * 2.0, JimAndi.LNDrawNotes, Tang)&lt;br /&gt;
  end -- if end&lt;br /&gt;
end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DiskRights===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns true if you have write access to path.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function DiskRights(path)                             -- &lt;br /&gt;
  local xx = io.open(path, &amp;quot;w&amp;quot;)&lt;br /&gt;
  if xx == nil then&lt;br /&gt;
      io.close()&lt;br /&gt;
      return false&lt;br /&gt;
  else&lt;br /&gt;
      xx:close()&lt;br /&gt;
      return true&lt;br /&gt;
  end&lt;br /&gt;
end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Geometry Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
&lt;br /&gt;
===SheetNew===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
&lt;br /&gt;
Adds a new sheet to the drawing&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function SheetNew()                                     -- Adds a new sheet to the drawing&lt;br /&gt;
  if GetVersion() &amp;gt;= 10.5 then then&lt;br /&gt;
    local layer_manager = Milling.job.LayerManager&lt;br /&gt;
    -- get current sheet count - note sheet 0 the default sheet counts as one sheet&lt;br /&gt;
    local orig_num_sheets = layer_manager.NumberOfSheets&lt;br /&gt;
    -- get current active sheet index&lt;br /&gt;
    local orig_active_sheet_index = layer_manager.ActiveSheetIndex&lt;br /&gt;
    -- set active sheet to last sheet&lt;br /&gt;
    local num_sheets = layer_manager.NumberOfSheets&lt;br /&gt;
    layer_manager.ActiveSheetIndex = num_sheets - 1&lt;br /&gt;
    -- Add a new sheet&lt;br /&gt;
    layer_manager:AddNewSheet()&lt;br /&gt;
    -- set active sheet to last sheet we just added&lt;br /&gt;
    num_sheets = layer_manager.NumberOfSheets&lt;br /&gt;
    layer_manager.ActiveSheetIndex = num_sheets - 1&lt;br /&gt;
    Milling.job:Refresh2DView()&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetDiameterAndCentre===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function GetDiameterAndCentre(cadcontour, point2d)&lt;br /&gt;
  local contour = cadcontour:GetContour()&lt;br /&gt;
  local arc = contour:GetFirstSpan()&lt;br /&gt;
  local point3d = Point3D();&lt;br /&gt;
  arc = CastSpanToArcSpan(arc)&lt;br /&gt;
  local diameter = arc:RadiusAndCentre(point3d) * 2.0&lt;br /&gt;
  point2d = Point2D(point3d.x, point3d.y)&lt;br /&gt;
  -- MessageBox(&amp;quot;Diameter = &amp;quot; .. diameter)&lt;br /&gt;
  return diameter, point2d&lt;br /&gt;
end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===IsCircle===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function IsCircle(cadcontour)                           -- Returns True if conture is a circle&lt;br /&gt;
  local contour = cadcontour:GetContour()&lt;br /&gt;
  -- Does it consist only of arcs?&lt;br /&gt;
  if contour.ContainsBeziers then&lt;br /&gt;
    return false&lt;br /&gt;
  end&lt;br /&gt;
  if not contour.ContainsArcs then&lt;br /&gt;
    return false&lt;br /&gt;
  end&lt;br /&gt;
  -- Does is contain 4 contours?&lt;br /&gt;
  if contour.Count ~= 4 then&lt;br /&gt;
    return false&lt;br /&gt;
  end&lt;br /&gt;
  -- Check the arcs end and initial points make a square.&lt;br /&gt;
  local arcs = {}&lt;br /&gt;
  local count = 1;&lt;br /&gt;
  local pos = contour:GetHeadPosition()&lt;br /&gt;
  local object&lt;br /&gt;
  while pos ~= nil do&lt;br /&gt;
    object, pos = contour:GetNext(pos)&lt;br /&gt;
    arcs[count] = object&lt;br /&gt;
    count = count + 1&lt;br /&gt;
  end&lt;br /&gt;
  local x_1 =(arcs[1]).StartPoint2D.x&lt;br /&gt;
  local y_1 =(arcs[1]).StartPoint2D.y&lt;br /&gt;
  local x_3 =(arcs[3]).StartPoint2D.x&lt;br /&gt;
  local y_3 =(arcs[3]).StartPoint2D.y&lt;br /&gt;
  local x_2 =(arcs[2]).StartPoint2D.x&lt;br /&gt;
  local y_2 =(arcs[2]).StartPoint2D.y&lt;br /&gt;
  local x_4 =(arcs[4]).StartPoint2D.x&lt;br /&gt;
  local y_4 =(arcs[4]).StartPoint2D.y&lt;br /&gt;
  local horizontal_distance = (x_1 - x_3)*(x_1 - x_3) + (y_1 - y_3)*(y_1 - y_3)&lt;br /&gt;
  local vertical_distance = (x_4 - x_2)*(x_4 - x_2) + (y_2 - y_4)*(y_2 - y_4)&lt;br /&gt;
  if math.abs(horizontal_distance - vertical_distance) &amp;gt; 0.04 then&lt;br /&gt;
    return false&lt;br /&gt;
  end&lt;br /&gt;
  -- Check the bulge factor is 90&lt;br /&gt;
  local bulge = 0;&lt;br /&gt;
  for _, arc_span in ipairs(arcs) do&lt;br /&gt;
    bulge = CastSpanToArcSpan(arc_span).Bulge;&lt;br /&gt;
    if math.abs(math.abs(bulge)  - g_bulge90) &amp;gt; 0.04 then&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  return true&lt;br /&gt;
end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===SheetSet===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function SheetSet(Name)                    -- Move focus to a named sheet&lt;br /&gt;
  local job = VectricJob()&lt;br /&gt;
  local sheet_manager = job.SheetManager&lt;br /&gt;
  local sheet_ids = sheet_manager:GetSheetIds()&lt;br /&gt;
  for id in sheet_ids do&lt;br /&gt;
    if(sheet_manager:GetSheetName(id) == Name) then&lt;br /&gt;
    sheet_manager.ActiveSheetId = id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===SheetNextSize===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function SheetNextSize(X, Y)               -- Make New Sheet to size (x, y)&lt;br /&gt;
  if X == nil then&lt;br /&gt;
    X = Milling.MaterialBlockWidth&lt;br /&gt;
  else&lt;br /&gt;
    X = X + (2 * Milling.Cal)&lt;br /&gt;
  end&lt;br /&gt;
  if Y == nil then&lt;br /&gt;
    Y = Milling.MaterialBlockHeight&lt;br /&gt;
  else&lt;br /&gt;
    Y = Y + (2 * Milling.Cal)&lt;br /&gt;
  end&lt;br /&gt;
  Milling.Sheet = Milling.Sheet + 1&lt;br /&gt;
  local sheet_manager = Milling.job.SheetManager&lt;br /&gt;
  local sheet_ids = sheet_manager:GetSheetIds()&lt;br /&gt;
  for id in sheet_ids do&lt;br /&gt;
    if(sheet_manager:GetSheetName(id) == &amp;quot;Sheet 1&amp;quot;) then&lt;br /&gt;
     sheet_manager:CreateSheets(1, id, Box2D(Point2D(0, 0), Point2D(X, Y)))&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  SheetSet(&amp;quot;Sheet &amp;quot; .. tostring(Milling.Sheet))&lt;br /&gt;
  return true&lt;br /&gt;
end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetPolarAngle===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function GetPolarAngle(Start, Corner, End)           -- Returns the Polar Angle&lt;br /&gt;
  local function GetPolarDirection(point1, point2)   &lt;br /&gt;
    local ang = math.abs(math.deg(math.atan((point2.Y - point1.Y) / (point2.X - point1.X))))&lt;br /&gt;
    if point1.X &amp;lt; point2.X then&lt;br /&gt;
      if point1.Y &amp;lt; point2.Y then&lt;br /&gt;
        ang = ang + 0.0&lt;br /&gt;
      else&lt;br /&gt;
        ang = 360.0 - ang&lt;br /&gt;
      end -- if end&lt;br /&gt;
    else&lt;br /&gt;
      if point1.Y &amp;lt; point2.Y then&lt;br /&gt;
        ang = 180.0 - ang&lt;br /&gt;
      else&lt;br /&gt;
        ang = ang + 180.0&lt;br /&gt;
      end -- if end&lt;br /&gt;
    end -- if end&lt;br /&gt;
    if ang &amp;gt;=360 then&lt;br /&gt;
      ang = ang -360.0&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return ang&lt;br /&gt;
  end -- function end&lt;br /&gt;
  return  math.abs(GetPolarDirection(Corner, Start) - GetPolarDirection(Corner, End))&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetOrientation===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function GetOrientation(point1, point2)                 -- Orientation of left, right, up or down&lt;br /&gt;
  if DecimalPlaces(point1.X,8) == DecimalPlaces(point2.X,8) then&lt;br /&gt;
    if point1.Y &amp;lt; point2.Y then&lt;br /&gt;
      return 90.0&lt;br /&gt;
    else&lt;br /&gt;
      return 270.0&lt;br /&gt;
    end&lt;br /&gt;
  elseif DecimalPlaces(point1.Y,8) == DecimalPlaces(point2.Y,8) then&lt;br /&gt;
    if point1.X &amp;lt; point2.X then&lt;br /&gt;
      return 0.0&lt;br /&gt;
    else&lt;br /&gt;
      return 180.0&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    return nil&lt;br /&gt;
  end&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetPolarDirection===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function GetPolarDirection(point1, point2)              -- Retuens and amgle from two points&lt;br /&gt;
  local ang = math.abs(math.deg(math.atan((point2.Y - point1.Y) / (point2.X - point1.X))))&lt;br /&gt;
  if point1.X &amp;lt; point2.X then&lt;br /&gt;
    if point1.Y &amp;lt; point2.Y then&lt;br /&gt;
      ang = ang + 0.0&lt;br /&gt;
    else&lt;br /&gt;
      ang = 360.0 - ang&lt;br /&gt;
    end -- if end&lt;br /&gt;
  else&lt;br /&gt;
    if point1.Y &amp;lt; point2.Y then&lt;br /&gt;
      ang = 180.0 - ang&lt;br /&gt;
    else&lt;br /&gt;
      ang = ang + 180.0&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- if end&lt;br /&gt;
  if ang &amp;gt;=360 then&lt;br /&gt;
    ang = ang -360.0&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return ang&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CenterArc===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function CenterArc(A, B, RadiusD)                       -- Returns 2DPoint from Arc point and Radius&lt;br /&gt;
  local radius = ((tonumber(RadiusD) or 0) * g_var.scl)&lt;br /&gt;
  local horda = (A - B).Length&lt;br /&gt;
  if math.abs(radius) &amp;lt; (horda / 2) and radius ~= 0 then&lt;br /&gt;
--D(&amp;quot;Too small radius &amp;quot; .. radius .. &amp;quot;\nreplaced by the smallest possible &amp;quot; .. (horda / 2))&lt;br /&gt;
    radius = (horda / 2)&lt;br /&gt;
  end&lt;br /&gt;
  return Point2D(((A.x + B.x) / 2 + (B.y - A.y) * math.sqrt(math.abs(radius) ^ 2 - (horda / 2) ^ 2) / horda), ((A.y + B.y) / 2 + (A.x - B.x) * math.sqrt(math.abs(radius) ^ 2 - (horda / 2) ^ 2) / horda))&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Polar2D===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
&lt;br /&gt;
The Polar2D function will calculate a new point in space based on a Point of reference, Angle of direction, and Projected distance. Returns 2DPoint from Known Point, Angle direction, and Projected distance.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function Polar2D(pt, ang, dis)                        &lt;br /&gt;
-- The Polar2D function will calculate a new point in space based on a Point of reference, Angle of direction, and Projected distance.&lt;br /&gt;
-- ::''Returns a 2Dpoint(x, y)''&lt;br /&gt;
  return Point2D((pt.X + dis * math.cos(math.rad(ang))), (pt.Y + dis * math.sin(math.rad(ang))))&lt;br /&gt;
end -- End Function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetDistance===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
&lt;br /&gt;
Returns Double from two Points&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function GetDistance(objA, objB)                        -- Returns Double from two Points&lt;br /&gt;
  local xDist = objB.x - objA.x&lt;br /&gt;
  local yDist = objB.y - objA.y&lt;br /&gt;
  return math.sqrt((xDist ^ 2) + (yDist ^ 2))&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetAngle===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  -- ===========================================================]]&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;function GetAngle(point1, point2)&lt;br /&gt;
  local ang = math.abs(math.deg(math.atan((point2.Y - point1.Y) / (point2.X - point1.X))))&lt;br /&gt;
  if point1.X &amp;lt; point2.X then&lt;br /&gt;
    if point1.Y &amp;lt; point2.Y then&lt;br /&gt;
      ang = ang + 0.0&lt;br /&gt;
    else&lt;br /&gt;
      ang = 360.0 - ang&lt;br /&gt;
    end -- if end&lt;br /&gt;
  else&lt;br /&gt;
    if point1.Y &amp;lt; point2.Y then&lt;br /&gt;
      ang = 180.0 - ang&lt;br /&gt;
    else&lt;br /&gt;
      ang = ang + 180.0&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- if end&lt;br /&gt;
  if ang &amp;gt;=360.0 then&lt;br /&gt;
    ang = ang -360.0&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return ang&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Arc2Bulge===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  -- ===========================================================]]&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;function Arc2Bulge(p1, p2, Rad)                         -- Returns the Bulge factor for an arc&lt;br /&gt;
  local chord = math.sqrt(((p2.x - p1.x) ^ 2) + ((p2.y - p1.y) ^ 2))&lt;br /&gt;
  local seg = (Rad - (0.5 * (math.sqrt((4.0 * Rad^2) - chord^2))))&lt;br /&gt;
  local bulge = (2 * seg) / chord&lt;br /&gt;
  return bulge&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===TrigIt===&lt;br /&gt;
Calculates Right Angle&lt;br /&gt;
&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function TrigIt()                                       -- Calculates Right Angle&lt;br /&gt;
-- ==Trig Function==&lt;br /&gt;
-- VECTRIC LUA SCRIPT&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
-- Gadgets are an entirely optional add-in to Vectric's core software products.&lt;br /&gt;
-- They are provided 'as-is', without any express or implied warranty, and you&lt;br /&gt;
--   make use of them entirely at your own risk.&lt;br /&gt;
-- In no event will the author(s) or Vectric Ltd. be held liable for any damages&lt;br /&gt;
--   arising from their use.&lt;br /&gt;
-- Permission is granted to anyone to use this software for any purpose,&lt;br /&gt;
-- including commercial applications, and to alter it and redistribute it freely,&lt;br /&gt;
-- subject to the following restrictions:&lt;br /&gt;
-- 1. The origin of this software must not be misrepresented; you must not&lt;br /&gt;
--    claim that you wrote the original software.&lt;br /&gt;
-- 2. If you use this software in a product, an acknowledgement in the product&lt;br /&gt;
--    documentation would be appreciated but is not required.&lt;br /&gt;
-- 3. Altered source versions must be plainly marked as such, and must not be&lt;br /&gt;
--    misrepresented as being the original software.&lt;br /&gt;
-- 4. This notice may not be removed or altered from any source distribution.&lt;br /&gt;
--&lt;br /&gt;
-- Right Triangle TrigFunction is written by Jim Anderson of Houston Texas 2020&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
-- Code Debugger&lt;br /&gt;
-- require(&amp;quot;mobdebug&amp;quot;).start()&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
-- Global Variables --&lt;br /&gt;
    Trig = {}&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
  function TrigTest() -- Test the All Right Angle&lt;br /&gt;
    TrigClear()&lt;br /&gt;
    Trig.A  =  0.0&lt;br /&gt;
    Trig.B  =  0.0&lt;br /&gt;
    Trig.C  = 90.0&lt;br /&gt;
    Trig.Opp =  3.0  -- Rise  or (B2C)&lt;br /&gt;
    Trig.Adj =  4.0  -- Base  or (A2C)&lt;br /&gt;
    Trig.Hyp =  0.0  -- Slope or (A2B)&lt;br /&gt;
    Trig.Slope =  0.0&lt;br /&gt;
    Trig.Area =  0.0&lt;br /&gt;
    Trig.OutRadius =  0.0&lt;br /&gt;
    Trig.InRadius =  0.0&lt;br /&gt;
    Trig.Parameter =  0.0&lt;br /&gt;
    TrigIt()&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Test 1: \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.A  =  &amp;quot; .. tostring(Trig.A) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.B  =  &amp;quot; .. tostring(Trig.B) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.C  =  &amp;quot; .. tostring(Trig.C) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Opp = * &amp;quot; .. tostring(Trig.Opp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Adj = * &amp;quot; .. tostring(Trig.Adj) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Hyp =  &amp;quot; .. tostring(Trig.Hyp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Slope =  &amp;quot; .. tostring(Trig.Slope) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Area =  &amp;quot; .. tostring(Trig.Area) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Parameter =  &amp;quot; .. tostring(Trig.Parameter) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.OutRadius =  &amp;quot; .. tostring(Trig.OutRadius) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.InRadius =  &amp;quot; .. tostring(Trig.InRadius) .. &amp;quot; \n&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    -- =====================================================]]&lt;br /&gt;
    TrigClear()&lt;br /&gt;
    Trig.A  =  0.0&lt;br /&gt;
    Trig.B  =  0.0&lt;br /&gt;
    Trig.C  = 90.0&lt;br /&gt;
    Trig.Opp =  0.0  -- Rise  or (B2C)&lt;br /&gt;
    Trig.Adj =  4.0  -- Base  or (A2C)&lt;br /&gt;
    Trig.Hyp =  5.0  -- Slope or (A2B)&lt;br /&gt;
    Trig.Slope =  0.0&lt;br /&gt;
    Trig.Area =  0.0&lt;br /&gt;
    Trig.OutRadius =  0.0&lt;br /&gt;
    Trig.InRadius =  0.0&lt;br /&gt;
    Trig.Parameter =  0.0&lt;br /&gt;
    TrigIt()&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Test 2: \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.A  =  &amp;quot; .. tostring(Trig.A) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.B  =  &amp;quot; .. tostring(Trig.B) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.C  =  &amp;quot; .. tostring(Trig.C) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Opp = * &amp;quot; .. tostring(Trig.Opp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Adj = * &amp;quot; .. tostring(Trig.Adj) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Hyp =  &amp;quot; .. tostring(Trig.Hyp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Slope =  &amp;quot; .. tostring(Trig.Slope) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Area =  &amp;quot; .. tostring(Trig.Area) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Parameter =  &amp;quot; .. tostring(Trig.Parameter) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.OutRadius =  &amp;quot; .. tostring(Trig.OutRadius) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.InRadius =  &amp;quot; .. tostring(Trig.InRadius) .. &amp;quot; \n&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    -- =====================================================]]&lt;br /&gt;
    TrigClear()&lt;br /&gt;
    Trig.A  =  0.0&lt;br /&gt;
    Trig.B  =  0.0&lt;br /&gt;
    Trig.C  = 90.0&lt;br /&gt;
    Trig.Opp =  3.0  -- Rise  or (B2C)&lt;br /&gt;
    Trig.Adj =  0.0  -- Base  or (A2C)&lt;br /&gt;
    Trig.Hyp =  5.0  -- Slope or (A2B)&lt;br /&gt;
    Trig.Slope =  0.0&lt;br /&gt;
    Trig.Area =  0.0&lt;br /&gt;
    Trig.OutRadius =  0.0&lt;br /&gt;
    Trig.InRadius =  0.0&lt;br /&gt;
    Trig.Parameter =  0.0&lt;br /&gt;
    TrigIt()&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Test 3: \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.A  =  &amp;quot; .. tostring(Trig.A) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.B  =  &amp;quot; .. tostring(Trig.B) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.C  =  &amp;quot; .. tostring(Trig.C) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Opp = * &amp;quot; .. tostring(Trig.Opp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Adj =  &amp;quot; .. tostring(Trig.Adj) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Hyp = * &amp;quot; .. tostring(Trig.Hyp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Slope =  &amp;quot; .. tostring(Trig.Slope) .. &amp;quot; on 12 inch \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Area =  &amp;quot; .. tostring(Trig.Area) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Parameter =  &amp;quot; .. tostring(Trig.Parameter) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.OutRadius =  &amp;quot; .. tostring(Trig.OutRadius) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.InRadius =  &amp;quot; .. tostring(Trig.InRadius) .. &amp;quot; \n&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    -- =====================================================]]&lt;br /&gt;
    TrigClear()&lt;br /&gt;
    Trig.A  =  36.86897645844&lt;br /&gt;
    Trig.B  =  0.0&lt;br /&gt;
    Trig.C  = 90.0&lt;br /&gt;
    Trig.Opp =  3.0  -- Rise  or (B2C)&lt;br /&gt;
    Trig.Adj =  0.0  -- Base  or (A2C)&lt;br /&gt;
    Trig.Hyp =  0.0  -- Slope or (A2B)&lt;br /&gt;
    Trig.Slope =  0.0&lt;br /&gt;
    Trig.Area =  0.0&lt;br /&gt;
    Trig.OutRadius =  0.0&lt;br /&gt;
    Trig.InRadius =  0.0&lt;br /&gt;
    Trig.Parameter =  0.0&lt;br /&gt;
    TrigIt()&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Test 4: \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.A  = * &amp;quot; .. tostring(Trig.A) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.B  =  &amp;quot; .. tostring(Trig.B) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.C  =  &amp;quot; .. tostring(Trig.C) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Opp = * &amp;quot; .. tostring(Trig.Opp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Adj =  &amp;quot; .. tostring(Trig.Adj) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Hyp =  &amp;quot; .. tostring(Trig.Hyp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Slope =  &amp;quot; .. tostring(Trig.Slope) .. &amp;quot; on 12 inch \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Area =  &amp;quot; .. tostring(Trig.Area) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Parameter =  &amp;quot; .. tostring(Trig.Parameter) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.OutRadius =  &amp;quot; .. tostring(Trig.OutRadius) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.InRadius =  &amp;quot; .. tostring(Trig.InRadius) .. &amp;quot; \n&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    -- =====================================================]]&lt;br /&gt;
    TrigClear()&lt;br /&gt;
    Trig.A  =  36.86897645844&lt;br /&gt;
    Trig.B  =  0.0&lt;br /&gt;
    Trig.C  = 90.0&lt;br /&gt;
    Trig.Opp =  0.0  -- Rise  or (B2C)&lt;br /&gt;
    Trig.Adj =  4.0  -- Base  or (A2C)&lt;br /&gt;
    Trig.Hyp =  0.0  -- Slope or (A2B)&lt;br /&gt;
    Trig.Slope =  0.0&lt;br /&gt;
    Trig.Area =  0.0&lt;br /&gt;
    Trig.OutRadius =  0.0&lt;br /&gt;
    Trig.InRadius =  0.0&lt;br /&gt;
    Trig.Parameter =  0.0&lt;br /&gt;
    TrigIt()&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Test 5: \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.A  = * &amp;quot; .. tostring(Trig.A) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.B  =  &amp;quot; .. tostring(Trig.B) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.C  =  &amp;quot; .. tostring(Trig.C) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Opp =  &amp;quot; .. tostring(Trig.Opp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Adj = * &amp;quot; .. tostring(Trig.Adj) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Hyp =  &amp;quot; .. tostring(Trig.Hyp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Slope =  &amp;quot; .. tostring(Trig.Slope) .. &amp;quot; on 12 inch \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Area =  &amp;quot; .. tostring(Trig.Area) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Parameter =  &amp;quot; .. tostring(Trig.Parameter) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.OutRadius =  &amp;quot; .. tostring(Trig.OutRadius) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.InRadius =  &amp;quot; .. tostring(Trig.InRadius) .. &amp;quot; \n&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    -- =====================================================]]&lt;br /&gt;
    TrigClear()&lt;br /&gt;
    Trig.A  =  36.86897645844&lt;br /&gt;
    Trig.B  =  0.0&lt;br /&gt;
    Trig.C  = 90.0&lt;br /&gt;
    Trig.Opp =  0.0  -- Rise  or (B2C)&lt;br /&gt;
    Trig.Adj =  0.0  -- Base  or (A2C)&lt;br /&gt;
    Trig.Hyp =  5.0  -- Slope or (A2B)&lt;br /&gt;
    Trig.Slope =  0.0&lt;br /&gt;
    Trig.Area =  0.0&lt;br /&gt;
    Trig.OutRadius =  0.0&lt;br /&gt;
    Trig.InRadius =  0.0&lt;br /&gt;
    Trig.Parameter =  0.0&lt;br /&gt;
    TrigIt()&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Test 6: \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.A  = * &amp;quot; .. tostring(Trig.A) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.B  =  &amp;quot; .. tostring(Trig.B) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.C  =  &amp;quot; .. tostring(Trig.C) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Opp =  &amp;quot; .. tostring(Trig.Opp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Adj =  &amp;quot; .. tostring(Trig.Adj) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Hyp = * &amp;quot; .. tostring(Trig.Hyp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Slope =  &amp;quot; .. tostring(Trig.Slope) .. &amp;quot; on 12 inch \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Area =  &amp;quot; .. tostring(Trig.Area) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Parameter =  &amp;quot; .. tostring(Trig.Parameter) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.OutRadius =  &amp;quot; .. tostring(Trig.OutRadius) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.InRadius =  &amp;quot; .. tostring(Trig.InRadius) .. &amp;quot; \n&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    TrigClear()&lt;br /&gt;
    Trig.A  =  0.0&lt;br /&gt;
    Trig.B  =  0.0&lt;br /&gt;
    Trig.C  = 90.0&lt;br /&gt;
    Trig.Opp =  3.0  -- Rise  or (B2C)&lt;br /&gt;
    Trig.Adj =  0.0  -- Base  or (A2C)&lt;br /&gt;
    Trig.Hyp =  0.0  -- Slope or (A2B)&lt;br /&gt;
    Trig.Slope =  9.0&lt;br /&gt;
    Trig.Area =  0.0&lt;br /&gt;
    Trig.OutRadius =  0.0&lt;br /&gt;
    Trig.InRadius =  0.0&lt;br /&gt;
    Trig.Parameter =  0.0&lt;br /&gt;
    TrigIt()&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Test 7: \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.A  =  &amp;quot; .. tostring(Trig.A) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.B  =  &amp;quot; .. tostring(Trig.B) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.C  =  &amp;quot; .. tostring(Trig.C) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Opp = * &amp;quot; .. tostring(Trig.Opp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Adj =  &amp;quot; .. tostring(Trig.Adj) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Hyp =  &amp;quot; .. tostring(Trig.Hyp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Slope = * &amp;quot; .. tostring(Trig.Slope) .. &amp;quot; on 12 inch \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Parameter =  &amp;quot; .. tostring(Trig.Parameter) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Area =  &amp;quot; .. tostring(Trig.Area) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Parameter =  &amp;quot; .. tostring(Trig.Parameter) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Circumscribing =  &amp;quot; .. tostring(Trig.Circumscribing) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Inscribing =  &amp;quot; .. tostring(Trig.Inscribing) .. &amp;quot; \n&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    -- =====================================================]]&lt;br /&gt;
    TrigClear()&lt;br /&gt;
    Trig.A  =  0.0&lt;br /&gt;
    Trig.B  =  0.0&lt;br /&gt;
    Trig.C  = 90.0&lt;br /&gt;
    Trig.Opp =  0.0  -- Rise  or (B2C)&lt;br /&gt;
    Trig.Adj =  0.0  -- Base  or (A2C)&lt;br /&gt;
    Trig.Hyp =  0.0  -- Slope or (A2B)&lt;br /&gt;
    Trig.Slope =  9.0&lt;br /&gt;
    Trig.Area =  0.0&lt;br /&gt;
    Trig.OutRadius =  0.0&lt;br /&gt;
    Trig.InRadius =  0.0&lt;br /&gt;
    Trig.Parameter =  0.0&lt;br /&gt;
    TrigIt()&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Test Error: \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.A  =  &amp;quot; .. tostring(Trig.A) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.B  =  &amp;quot; .. tostring(Trig.B) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.C  =  &amp;quot; .. tostring(Trig.C) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.Opp = * &amp;quot; .. tostring(Trig.Opp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.Adj =  &amp;quot; .. tostring(Trig.Adj) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.Hyp =  &amp;quot; .. tostring(Trig.Hyp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.Slope = * &amp;quot; .. tostring(Trig.Slope) .. &amp;quot; on 12 inch \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.Parameter =  &amp;quot; .. tostring(Trig.Parameter) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.Area =  &amp;quot; .. tostring(Trig.Area) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.Parameter =  &amp;quot; .. tostring(Trig.Parameter) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.Circumscribing =  &amp;quot; .. tostring(Trig.Circumscribing) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.Inscribing =  &amp;quot; .. tostring(Trig.Inscribing) .. &amp;quot; \n&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end --&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
  function TrigClear()   -- Clears and resets Trig Table&lt;br /&gt;
    Trig.A  =  0.0&lt;br /&gt;
    Trig.B  =  0.0&lt;br /&gt;
    Trig.C  = 90.0&lt;br /&gt;
    Trig.Opp =  0.0  -- Rise  or (B2C)&lt;br /&gt;
    Trig.Adj =  0.0  -- Base  or (A2C)&lt;br /&gt;
    Trig.Hyp =  0.0  -- Slope or (A2B)&lt;br /&gt;
    Trig.Slope =  0.0&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
      local function BSA()&lt;br /&gt;
        Trig.B  = (Trig.C - Trig.A)&lt;br /&gt;
        Trig.Slope = math.tan(math.rad(Trig.A)) * 12.0&lt;br /&gt;
        Trig.Area =  (Trig.Opp * Trig.Adj) * 0.5&lt;br /&gt;
        Trig.Inscribing = ((Trig.Opp + Trig.Adj) - Trig.Hyp) * 0.5&lt;br /&gt;
        Trig.Circumscribing =  Trig.Hyp * 0.5&lt;br /&gt;
        Trig.Parameter = Trig.Opp + Trig.Adj + Trig.Hyp&lt;br /&gt;
      end&lt;br /&gt;
      if Trig.A == 0.0 and Trig.B &amp;gt; 0.0 and Trig.Slope == 0.0 then&lt;br /&gt;
        Trig.A = Trig.C - Trig.B&lt;br /&gt;
      elseif Trig.A == 0.0 and Trig.B == 0.0 and Trig.Slope &amp;gt; 0.0 then&lt;br /&gt;
        Trig.A = math.deg(math.atan(Trig.Slope / 12.0))&lt;br /&gt;
      end -- if end&lt;br /&gt;
-- test 4&lt;br /&gt;
      if (Trig.A &amp;gt; 0.0) and (Trig.Opp &amp;gt;  0.0) then -- A and Rise or (B2C)&lt;br /&gt;
        Trig.Adj =  Trig.Opp / (math.tan(math.rad(Trig.A)))&lt;br /&gt;
        Trig.Hyp = math.sqrt((Trig.Opp * Trig.Opp ) + ( Trig.Adj * Trig.Adj))&lt;br /&gt;
        BSA()&lt;br /&gt;
        return true&lt;br /&gt;
      -- test 6&lt;br /&gt;
      elseif (Trig.A &amp;gt; 0.0) and (Trig.Hyp &amp;gt;  0.0)  then -- A and Slope or (A2B)&lt;br /&gt;
        Trig.Adj = math.cos(math.rad(Trig.A)) * Trig.Hyp&lt;br /&gt;
        Trig.Opp = math.sqrt((Trig.Hyp * Trig.Hyp ) - ( Trig.Adj * Trig.Adj))&lt;br /&gt;
        BSA()&lt;br /&gt;
        return true&lt;br /&gt;
      -- test 5&lt;br /&gt;
      elseif (Trig.A &amp;gt; 0.0) and (Trig.Adj &amp;gt;  0.0)  then -- A and Base or (A2C)&lt;br /&gt;
        Trig.Opp = math.tan(math.rad(Trig.A)) * Trig.Adj&lt;br /&gt;
        Trig.Hyp = math.sqrt((Trig.Opp * Trig.Opp ) + ( Trig.Adj * Trig.Adj))&lt;br /&gt;
        BSA()&lt;br /&gt;
        return true&lt;br /&gt;
        -- test 1&lt;br /&gt;
      elseif (Trig.Opp &amp;gt;  0.0) and (Trig.Adj &amp;gt;  0.0) then -- Rise and Base&lt;br /&gt;
        Trig.Hyp = math.sqrt((Trig.Opp * Trig.Opp ) + ( Trig.Adj * Trig.Adj))&lt;br /&gt;
        Trig.A  = math.deg(math.atan(Trig.Opp / Trig.Adj))&lt;br /&gt;
        BSA()&lt;br /&gt;
        return true&lt;br /&gt;
      elseif (Trig.Adj &amp;gt;  0.0) and (Trig.Hyp &amp;gt;  0.0) then -- Rise and Slope&lt;br /&gt;
-- test 2&lt;br /&gt;
        Trig.Opp = math.sqrt((Trig.Hyp * Trig.Hyp ) - ( Trig.Adj * Trig.Adj))&lt;br /&gt;
        Trig.A  = math.deg(math.atan(Trig.Opp / Trig.Adj))&lt;br /&gt;
        BSA()&lt;br /&gt;
        return true&lt;br /&gt;
      elseif (Trig.Opp &amp;gt;  0.0) and (Trig.Hyp &amp;gt;  0.0) then -- Base and Slope&lt;br /&gt;
-- test 3&lt;br /&gt;
        Trig.Adj = math.sqrt((Trig.Hyp * Trig.Hyp ) - ( Trig.Opp * Trig.Opp))&lt;br /&gt;
        Trig.A  = math.deg(math.atan(Trig.Opp / Trig.Adj))&lt;br /&gt;
        BSA()&lt;br /&gt;
        return true&lt;br /&gt;
      else&lt;br /&gt;
        DisplayMessageBox(&amp;quot;Error: Trig Values did not match requirements: \n&amp;quot; ..&lt;br /&gt;
                          &amp;quot; Trig.A  =  &amp;quot; .. tostring(Trig.A) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
                          &amp;quot; Trig.B  =  &amp;quot; .. tostring(Trig.B) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
                          &amp;quot; Trig.C  =  &amp;quot; .. tostring(Trig.C) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
                          &amp;quot; Trig.Opp =  &amp;quot; .. tostring(Trig.Opp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
                          &amp;quot; Trig.Adj =  &amp;quot; .. tostring(Trig.Adj) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
                          &amp;quot; Trig.Hyp =  &amp;quot; .. tostring(Trig.Hyp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
                          &amp;quot; Trig.Slope =  &amp;quot; .. tostring(Trig.Slope) .. &amp;quot; on 12 inch \n&amp;quot; ..&lt;br /&gt;
                          &amp;quot; Trig.Area =  &amp;quot; .. tostring(Trig.Area) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
                          &amp;quot; Trig.Parameter =  &amp;quot; .. tostring(Trig.Parameter) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
                          &amp;quot; Trig.OutRadius =  &amp;quot; .. tostring(Trig.OutRadius) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
                          &amp;quot; Trig.InRadius =  &amp;quot; .. tostring(Trig.InRadius) .. &amp;quot; \n&amp;quot;&lt;br /&gt;
                          )&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
    end -- function end&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
end -- Geometry Tools end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==INI File Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
These functions manipulate the INI files for the storage and retrieval of data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===INI_NameStrip===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Convert string to the correct data type.&lt;br /&gt;
&lt;br /&gt;
Local Words = NameStrip(&amp;quot;KPSDFKSPSK - 34598923&amp;quot;, &amp;quot;-&amp;quot;) -- returns &amp;quot;KPSDFKSPSK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Source Code'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function INI_NameStrip(str, var)&lt;br /&gt;
    if &amp;quot;&amp;quot; == str then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error in string&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      if string.find(str, var) then&lt;br /&gt;
        local j = assert(string.find(str, var) - 1)&lt;br /&gt;
        return All_Trim(string.sub(str, 1, j))&lt;br /&gt;
      else&lt;br /&gt;
        return str&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_HeadStrip===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Convert string to the correct data type.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  function INI_HeadStrip(str, var)                            -- convert string to the correct data type&lt;br /&gt;
-- Local Words = HeadStrip(&amp;quot;LastName23 = Smith&amp;quot;, &amp;quot;=&amp;quot;) -- returns &amp;quot;Smith&amp;quot;&lt;br /&gt;
    if &amp;quot;&amp;quot; == str then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error in string&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      if string.find(str, var) then&lt;br /&gt;
        local j = assert(string.find(str, var) + 1)&lt;br /&gt;
        return All_Trim(string.sub(str, j))&lt;br /&gt;
      else&lt;br /&gt;
        return str&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_AreDupGroups===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Checks if there are duplicate groups.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function INI_AreDupGroups(xPath, xFile)&lt;br /&gt;
    local GroupNames = {}&lt;br /&gt;
    local CleanNames = {}&lt;br /&gt;
    local DupGroups  = {}&lt;br /&gt;
      GroupNames = INI_ReadGroups(xFile, aName)&lt;br /&gt;
      CleanNames = RemoveDups(GroupNames)&lt;br /&gt;
    if TableLength(GroupNames) == TableLength(CleanNames)then&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_FixDupGroups===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Find and fix duplicate groups&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_FixDupGroups(xPath, xFile)&lt;br /&gt;
    local GroupNames = {}&lt;br /&gt;
    local CleanNames = {}&lt;br /&gt;
    local DupGroups  = {}&lt;br /&gt;
      GroupNames = INI_ReadGroups(xFile, aName)&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_DeleteGroup===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Deletes only the first find of xGroup&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_DeleteGroup(xPath, xFile, xGroup)&lt;br /&gt;
-- Deletes old ini (.bak) file&lt;br /&gt;
-- Copy's the .ini to a backup (.bak) new file&lt;br /&gt;
-- Reads the new backup file and writes a new file to the xGroup value&lt;br /&gt;
-- Stops Writing lines until next Group is found&lt;br /&gt;
-- Writes to end of file&lt;br /&gt;
-- Call: DeleteGroup(&amp;quot;C:\\Users\\James\\OneDrive\\Documents\\DoorGadget\\Clients\\Marcin&amp;quot;, &amp;quot;ProjectList&amp;quot;, &amp;quot;Boston&amp;quot;)&lt;br /&gt;
    local OfileName = xPath .. &amp;quot;\\&amp;quot; .. xFile .. &amp;quot;.bak&amp;quot;&lt;br /&gt;
    if FileExists(OfileName) then&lt;br /&gt;
      os.remove(OfileName)&lt;br /&gt;
    end&lt;br /&gt;
    local NfileName = xPath .. &amp;quot;\\&amp;quot; .. xFile .. &amp;quot;.ini&amp;quot;&lt;br /&gt;
--    os.rename(NfileName, OfileName) -- makes backup copy file&lt;br /&gt;
    if CopyFileFromTo(NfileName, OfileName) then&lt;br /&gt;
      local fileR   = io.open(OfileName)&lt;br /&gt;
      local fileW   = io.open(NfileName,  &amp;quot;w&amp;quot;)&lt;br /&gt;
      local groups  = false&lt;br /&gt;
      local writit  = true&lt;br /&gt;
      local MyTxt   = &amp;quot;&amp;quot;&lt;br /&gt;
      local txt = &amp;quot;&amp;quot;&lt;br /&gt;
      if fileR and fileW then  -- files are open&lt;br /&gt;
        for Line in fileR:lines() do  -- read each line of the backup file&lt;br /&gt;
          txt = Line  -- copy line from file to txt&lt;br /&gt;
          if All_Trim(Line) == &amp;quot;[&amp;quot; .. All_Trim(xGroup) ..  MyTxt .. &amp;quot;]&amp;quot; then  -- look for a match&lt;br /&gt;
            groups = true&lt;br /&gt;
            txt = &amp;quot;&amp;quot;&lt;br /&gt;
          end -- if end&lt;br /&gt;
          if groups and MyTxt == &amp;quot;&amp;quot; then  -- if group is true turn off the write function&lt;br /&gt;
            writit = false&lt;br /&gt;
            if &amp;quot;[&amp;quot; == string.sub(All_Trim(txt), 1, 1) then  -- turns write function on if next group is found&lt;br /&gt;
              groups = false&lt;br /&gt;
              xGroup = &amp;quot;-&amp;quot;&lt;br /&gt;
              writit = true&lt;br /&gt;
              MyTxt   = &amp;quot;--&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              writit = false&lt;br /&gt;
            end -- if end&lt;br /&gt;
          end -- if end&lt;br /&gt;
          if writit then&lt;br /&gt;
            fileW:write(txt .. &amp;quot;\n&amp;quot;)&lt;br /&gt;
            txt = &amp;quot;&amp;quot;&lt;br /&gt;
          end -- if end&lt;br /&gt;
        end -- for end&lt;br /&gt;
        os.remove(OfileName)&lt;br /&gt;
      end -- if end&lt;br /&gt;
      if fileR then fileR:close() end&lt;br /&gt;
      if fileW then fileW:close() end&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_RenameGroup===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Renames a group&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_RenameGroup(xOldGroup, xNewGroup)&lt;br /&gt;
--Deletes old ini Hardware.bak file&lt;br /&gt;
--Copys the ini file to a backup copy file&lt;br /&gt;
--Reads the backup file and writes a new ini file to the xGroup&lt;br /&gt;
--Writes new file with new group  to the new ini file&lt;br /&gt;
  local NfileName = Project.AppPath .. &amp;quot;\\&amp;quot; .. &amp;quot;EasyDrawerHardware&amp;quot; .. &amp;quot;.ini&amp;quot;&lt;br /&gt;
  local OfileName = Project.AppPath .. &amp;quot;\\&amp;quot; .. &amp;quot;EasyDrawerHardware&amp;quot; .. &amp;quot;.bak&amp;quot;&lt;br /&gt;
  os.remove(OfileName)&lt;br /&gt;
  CopyFileFromTo(NfileName, OfileName) -- makes backup file&lt;br /&gt;
  local fileR = io.open(OfileName)&lt;br /&gt;
  local fileW = io.open(NfileName, &amp;quot;w&amp;quot;)&lt;br /&gt;
  if fileR and fileW then&lt;br /&gt;
    local groups = false&lt;br /&gt;
    local txt = &amp;quot;&amp;quot;&lt;br /&gt;
    for Line in fileR:lines() do&lt;br /&gt;
      if All_Trim(Line) == &amp;quot;[&amp;quot; .. All_Trim(xOldGroup) .. txt .. &amp;quot;]&amp;quot; then -- Group&lt;br /&gt;
        fileW:write(xNewGroup .. &amp;quot;\n&amp;quot;)&lt;br /&gt;
        txt = &amp;quot;-&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
        fileW:write(Line .. &amp;quot;\n&amp;quot;)&lt;br /&gt;
      end -- if end&lt;br /&gt;
    end -- for end&lt;br /&gt;
    fileR:close()&lt;br /&gt;
    fileW:close()&lt;br /&gt;
    os.remove(OfileName)&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_DeleteItem===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Deleates a group&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_DeleteItem(xPath, xFile, xGroup, xItem)&lt;br /&gt;
-- Deletes old ini (.bak) file&lt;br /&gt;
-- Copys the .ini to a backup (.bak) new file&lt;br /&gt;
-- Reads the new backup file and writes a new file to the xGroup value&lt;br /&gt;
-- Stops Writing lines until next Group is found&lt;br /&gt;
-- Writes to end of file&lt;br /&gt;
-- DeleteGroup(&amp;quot;C:\\Users\\James\\OneDrive\\Documents\\DoorGadget\\Clients\\Marcin&amp;quot;, &amp;quot;ProjectList&amp;quot;, &amp;quot;Boston&amp;quot;)&lt;br /&gt;
  local NfileName = xPath .. &amp;quot;\\&amp;quot; .. xFile .. &amp;quot;.ini&amp;quot;&lt;br /&gt;
  local OfileName = xPath .. &amp;quot;\\&amp;quot; .. xFile .. &amp;quot;.bak&amp;quot;&lt;br /&gt;
  os.remove(OfileName)&lt;br /&gt;
  CopyFileFromTo(NfileName, OfileName) -- makes backup copy file&lt;br /&gt;
  local fileR = io.open(OfileName)&lt;br /&gt;
  local fileW = io.open(NfileName,  &amp;quot;w&amp;quot;)&lt;br /&gt;
  if fileR and fileW then&lt;br /&gt;
    local groups = false&lt;br /&gt;
    local writit = true&lt;br /&gt;
    local txt = &amp;quot;&amp;quot;&lt;br /&gt;
    for Line in fileR:lines() do&lt;br /&gt;
      txt = Line&lt;br /&gt;
      if All_Trim(Line) == &amp;quot;[&amp;quot; .. All_Trim(xGroup) .. &amp;quot;]&amp;quot; then&lt;br /&gt;
        groups = true&lt;br /&gt;
      end -- if end&lt;br /&gt;
      if groups then&lt;br /&gt;
  -- ===================&lt;br /&gt;
        if xItem == string.sub(Line, 1, string.len(xItem))  then  -- Item&lt;br /&gt;
          writit = false&lt;br /&gt;
          groups = false&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- if end&lt;br /&gt;
  -- ===================&lt;br /&gt;
      if writit then&lt;br /&gt;
        fileW:write(txt .. &amp;quot;\n&amp;quot;)&lt;br /&gt;
      end -- if end&lt;br /&gt;
      writit = true&lt;br /&gt;
    end -- for end&lt;br /&gt;
    os.remove(OfileName)&lt;br /&gt;
    fileR:close()&lt;br /&gt;
    fileW:close()&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_ValidateGroup===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Reads INI file and returns true if group is found&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_ValidateGroup(xFile, xGroup)&lt;br /&gt;
  -- Reads INI file and returns true if the group is found&lt;br /&gt;
  local fileR = io.open(xFile)&lt;br /&gt;
  local group = false&lt;br /&gt;
  for Line in fileR:lines() do&lt;br /&gt;
    if string.upper(All_Trim(Line)) == &amp;quot;[&amp;quot; .. string.upper(All_Trim(xGroup)) .. &amp;quot;]&amp;quot; then  -- Group&lt;br /&gt;
    group = true&lt;br /&gt;
    break&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- for end&lt;br /&gt;
  fileR:close()&lt;br /&gt;
  return group&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_ValidateItem===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Reads INI file and returns true if group and item is found&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_ValidateItem(xFile, xGroup, xItem)&lt;br /&gt;
    local fileR = io.open(xFile)&lt;br /&gt;
    if fileR then&lt;br /&gt;
      local group = false&lt;br /&gt;
      local item = false&lt;br /&gt;
      local ItemLen = string.len(xItem)&lt;br /&gt;
      for Line in fileR:lines() do&lt;br /&gt;
        if All_Trim(Line) == &amp;quot;[&amp;quot; ..  string.upper(All_Trim(xGroup)) .. &amp;quot;]&amp;quot; then  -- Group&lt;br /&gt;
        group = true&lt;br /&gt;
        end -- if end&lt;br /&gt;
        if group then&lt;br /&gt;
          if string.upper(xItem) == string.upper(string.sub(Line, 1, string.len(xItem)))  then  -- Item&lt;br /&gt;
            item = true&lt;br /&gt;
            break&lt;br /&gt;
          end -- if end&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- for end&lt;br /&gt;
      fileR:close()&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return group&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_StrValue===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Reads INI file and returns string value&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_StrValue(str, ty)&lt;br /&gt;
-- Convert string to the correct data type&lt;br /&gt;
    if nil == str then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error in Ini file - looking for a &amp;quot; .. ty .. &amp;quot; value&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      if &amp;quot;&amp;quot; == All_Trim(str) then&lt;br /&gt;
        DisplayMessageBox(&amp;quot;Error in Ini file - looking for a &amp;quot; .. ty .. &amp;quot; value&amp;quot;)&lt;br /&gt;
      else&lt;br /&gt;
        local j = (string.find(str, &amp;quot;=&amp;quot;) + 1)&lt;br /&gt;
        if ty == &amp;quot;D&amp;quot; then -- Double&lt;br /&gt;
          return tonumber(string.sub(str, j))&lt;br /&gt;
        end -- if end&lt;br /&gt;
        if ty == &amp;quot;I&amp;quot; then  -- Intiger&lt;br /&gt;
          return math.floor(tonumber(string.sub(str, j)))&lt;br /&gt;
        end -- if end&lt;br /&gt;
        if ty == &amp;quot;S&amp;quot; then  -- String&lt;br /&gt;
          return All_Trim(string.sub(str, j))&lt;br /&gt;
        end -- if end&lt;br /&gt;
        if ty == &amp;quot;B&amp;quot; then  -- Bool&lt;br /&gt;
          if &amp;quot;TRUE&amp;quot; == All_Trim(string.sub(str, j)) then&lt;br /&gt;
            return true&lt;br /&gt;
          else&lt;br /&gt;
            return false&lt;br /&gt;
          end -- if end&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- if end&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return nil&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_GetValue===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Reads INI file and returns value&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_GetValue(xPath, FileName, GroupName, ItemName, ValueType)&lt;br /&gt;
    -- ==INI_GetValue(xPath, FileName, GroupName, ItemName, ValueType)==&lt;br /&gt;
    -- Returns a value from a file, group, and Item&lt;br /&gt;
    -- Usage: XX.YY = GetIniValue(&amp;quot;C:/temp&amp;quot;, &amp;quot;ScrewDia&amp;quot;, &amp;quot;[Screws]&amp;quot;, &amp;quot;Diameter&amp;quot;, &amp;quot;D&amp;quot;)&lt;br /&gt;
    local filenameR = xPath .. &amp;quot;\\&amp;quot; .. FileName .. &amp;quot;.ini&amp;quot;&lt;br /&gt;
    local FL = LengthOfFile(filenameR)&lt;br /&gt;
    local file = io.open(filenameR, &amp;quot;r&amp;quot;)&lt;br /&gt;
    local dat = &amp;quot;.&amp;quot;&lt;br /&gt;
    local ItemNameLen = string.len(ItemName)&lt;br /&gt;
    if file then&lt;br /&gt;
      while (FL &amp;gt;= 1) do&lt;br /&gt;
        dat = string.upper(All_Trim(file:read()))&lt;br /&gt;
        if dat == &amp;quot;[&amp;quot; .. string.upper(GroupName) .. &amp;quot;]&amp;quot; then&lt;br /&gt;
          break&lt;br /&gt;
        else&lt;br /&gt;
          FL = FL - 1&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- while end&lt;br /&gt;
      while (FL &amp;gt;= 1) do&lt;br /&gt;
        dat = string.upper(All_Trim(file:read()))&lt;br /&gt;
        if string.upper(ItemName) == string.sub(dat, 1, ItemNameLen)  then&lt;br /&gt;
          break&lt;br /&gt;
        else&lt;br /&gt;
          FL = FL - 1&lt;br /&gt;
          if FL == 0 then&lt;br /&gt;
            dat = &amp;quot;Error - item not  found&amp;quot;&lt;br /&gt;
            break&lt;br /&gt;
          end -- if end&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- while end&lt;br /&gt;
      file:close()-- closes the open file&lt;br /&gt;
    end -- if end&lt;br /&gt;
    local XX = StrIniValue(dat, ValueType)&lt;br /&gt;
    return XX&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_GetIDFor===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Reads INI file and returns ID for a value&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_GetIDFor(xPath, FileName, GroupName, ItemValue)&lt;br /&gt;
    -- == INI_GetIDFor(xPath, FileName, GroupName, ItemValue) ==&lt;br /&gt;
    -- Returns a ItemID from a file, group, and ItemValue&lt;br /&gt;
    -- Usage: XX.YY = INI_GetIDFor(&amp;quot;C:/temp&amp;quot;, &amp;quot;UserList&amp;quot;, &amp;quot;[Users]&amp;quot;, &amp;quot;Anderson&amp;quot;)&lt;br /&gt;
    -- returns: &amp;quot;UserLastName22&amp;quot;&lt;br /&gt;
    local filenameR = xPath .. &amp;quot;\\&amp;quot; .. FileName .. &amp;quot;.ini&amp;quot;&lt;br /&gt;
    local FL = LengthOfFile(filenameR)&lt;br /&gt;
    local file = io.open(filenameR, &amp;quot;r&amp;quot;)&lt;br /&gt;
    if file then&lt;br /&gt;
      local dat = &amp;quot;.&amp;quot;&lt;br /&gt;
      local ItemValueLen = string.len(ItemValue)&lt;br /&gt;
      while (FL &amp;gt;= 1) do&lt;br /&gt;
        dat = string.upper(All_Trim(file:read()))&lt;br /&gt;
        if dat == &amp;quot;[&amp;quot; .. string.upper(GroupName) .. &amp;quot;]&amp;quot; then&lt;br /&gt;
          break&lt;br /&gt;
        else&lt;br /&gt;
          FL = FL - 1&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- while end&lt;br /&gt;
      while (FL &amp;gt;= 1) do&lt;br /&gt;
        dat = string.upper(All_Trim(file:read()))&lt;br /&gt;
        if string.upper(ItemValue) == HeadStrip(dat, &amp;quot;=&amp;quot;)  then&lt;br /&gt;
          break&lt;br /&gt;
        else&lt;br /&gt;
          FL = FL - 1&lt;br /&gt;
          if FL == 0 then&lt;br /&gt;
            dat = &amp;quot;Error - item not  found&amp;quot;&lt;br /&gt;
            break&lt;br /&gt;
          end -- if end&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- while end&lt;br /&gt;
      file:close()-- closes the open file&lt;br /&gt;
    end -- if end&lt;br /&gt;
    local XX = NameStrip(dat, &amp;quot;=&amp;quot;)&lt;br /&gt;
    return XX&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_ReadGroups===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Reads INI file group and returns true if found&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_ReadGroups(xFile, aName)&lt;br /&gt;
  --[[Reads INI and returns a list contain the [Headers] as Array&lt;br /&gt;
  IniFile = {} Global variables&lt;br /&gt;
  xPath = script_path&lt;br /&gt;
  ]]&lt;br /&gt;
    local filename = xFile&lt;br /&gt;
    local file = io.open(filename, &amp;quot;r&amp;quot;)&lt;br /&gt;
    if file then&lt;br /&gt;
      local fLength = (LengthOfFile(filename) - 1)&lt;br /&gt;
      local dat = All_Trim(file:read())&lt;br /&gt;
      while (fLength &amp;gt;= 1) do&lt;br /&gt;
        if &amp;quot;[&amp;quot; == string.sub(dat, 1, 1) then&lt;br /&gt;
          table.insert (aName, string.sub(dat, 2, -2))&lt;br /&gt;
        end&lt;br /&gt;
        dat = file:read()&lt;br /&gt;
        if dat then&lt;br /&gt;
          dat = All_Trim(dat)&lt;br /&gt;
        else&lt;br /&gt;
          file:close()-- closes the open file&lt;br /&gt;
          return true&lt;br /&gt;
        end&lt;br /&gt;
        fLength = fLength - 1&lt;br /&gt;
      end -- while&lt;br /&gt;
    end -- if&lt;br /&gt;
     if file then file:close() end&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_ProjectHeaderReader===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Reads INI file group and returns the INI Header values of a ini file and uploads to &amp;quot;IniFile&amp;quot; Array&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_ProjectHeaderReader(xPath)&lt;br /&gt;
    local filename = xPath .. &amp;quot;/CabinetProjects.ini&amp;quot;&lt;br /&gt;
    local file = io.open(filename, &amp;quot;r&amp;quot;)&lt;br /&gt;
    if file then&lt;br /&gt;
      local Cabing = (LengthOfFile(filename) - 1)&lt;br /&gt;
      local dat = All_Trim(file:read())&lt;br /&gt;
      while (Cabing &amp;gt;= 1) do&lt;br /&gt;
        if &amp;quot;[&amp;quot; == string.sub(dat, 1, 1) then&lt;br /&gt;
          table.insert (Projects, string.sub(dat, 2, -2))&lt;br /&gt;
        end&lt;br /&gt;
        dat = file:read()&lt;br /&gt;
        if dat then&lt;br /&gt;
          dat = All_Trim(dat)&lt;br /&gt;
        else&lt;br /&gt;
          return true&lt;br /&gt;
        end&lt;br /&gt;
        Cabing = Cabing - 1&lt;br /&gt;
      end&lt;br /&gt;
      file:close()&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_AddNewProject===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Appends a New Project to CabinetProjectQuestion.ini&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_AddNewProject(xPath, xGroup)&lt;br /&gt;
    local filename = xPath .. &amp;quot;/ProjectList.ini&amp;quot;&lt;br /&gt;
    local file = io.open(filename, &amp;quot;a&amp;quot;)&lt;br /&gt;
    if file then&lt;br /&gt;
      file:write(&amp;quot;[&amp;quot; .. All_Trim(xGroup) .. &amp;quot;] \n&amp;quot;)&lt;br /&gt;
      file:write(&amp;quot;load_date = &amp;quot; .. StartDate(true) .. &amp;quot; \n&amp;quot;)&lt;br /&gt;
      file:write(&amp;quot;#====================================== \n&amp;quot;)&lt;br /&gt;
      file:close()-- closes the open file&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_StdHeaderReader===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Gets the INI Header values of a ini file and uploads to &amp;quot;IniFile&amp;quot; Array&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_StdHeaderReader(xPath, Fname)&lt;br /&gt;
    local filename = xPath .. &amp;quot;\\&amp;quot; .. Fname .. &amp;quot;.ini&amp;quot;&lt;br /&gt;
    local file = io.open(filename, &amp;quot;r&amp;quot;)&lt;br /&gt;
    if file then&lt;br /&gt;
      local WallMilling = (LengthOfFile(filename) - 1)&lt;br /&gt;
      local dat = All_Trim(file:read())&lt;br /&gt;
      while (WallMilling &amp;gt;= 0) do&lt;br /&gt;
        if &amp;quot;[&amp;quot; == string.sub(dat, 1, 1) then&lt;br /&gt;
          table.insert (IniFile, string.sub(dat, 2, -2))&lt;br /&gt;
        end -- if end&lt;br /&gt;
        dat = file:read()&lt;br /&gt;
        if dat then&lt;br /&gt;
          dat = All_Trim(dat)&lt;br /&gt;
        else&lt;br /&gt;
          return true&lt;br /&gt;
        end -- if end&lt;br /&gt;
        WallMilling = WallMilling - 1&lt;br /&gt;
      end -- while end&lt;br /&gt;
      file:close()&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_ReadProjectinfo===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Reads an ini files group and sets the table.names&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_ReadProjectinfo(Table, xPath, xGroup, xFile)&lt;br /&gt;
    Table.ProjectContactEmail       = GetIniValue(xPath, xFile, xGroup, &amp;quot;ProjectQuestion.ProjectContactEmail&amp;quot;, &amp;quot;S&amp;quot;)&lt;br /&gt;
    Table.ProjectContactName        = GetIniValue(xPath, xFile, xGroup, &amp;quot;ProjectQuestion.ProjectContactName&amp;quot;, &amp;quot;S&amp;quot;)&lt;br /&gt;
    Table.ProjectContactPhoneNumber = GetIniValue(xPath, xFile, xGroup, &amp;quot;ProjectQuestion.ProjectContactPhoneNumber&amp;quot;, &amp;quot;S&amp;quot;)&lt;br /&gt;
    Table.ProjectName               = GetIniValue(xPath, xFile, xGroup, &amp;quot;ProjectQuestion.ProjectName&amp;quot;, &amp;quot;S&amp;quot;)&lt;br /&gt;
    Table.ProjectPath               = GetIniValue(xPath, xFile, xGroup, &amp;quot;ProjectQuestion.ProjectPath&amp;quot;, &amp;quot;S&amp;quot;)&lt;br /&gt;
    Table.StartDate                 = GetIniValue(xPath, xFile, xGroup, &amp;quot;ProjectQuestion.StartDate&amp;quot;, &amp;quot;S&amp;quot;)&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_UpdateItem===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Deletes old ini (.bak) file&lt;br /&gt;
&lt;br /&gt;
Copys the .ini to a backup (.bak) new file&lt;br /&gt;
&lt;br /&gt;
Reads the new backup file and writes a new file to the xGroup&lt;br /&gt;
&lt;br /&gt;
Writes new xValue for the for the xItem&lt;br /&gt;
&lt;br /&gt;
Reads and writes a new file to end of file&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_UpdateItem(xPath, xFile, xGroup, xItem, xValue)&lt;br /&gt;
    local NfileName = xPath .. &amp;quot;\\&amp;quot; .. xFile .. &amp;quot;.ini&amp;quot;&lt;br /&gt;
    local OfileName = xPath .. &amp;quot;\\&amp;quot; .. xFile .. &amp;quot;.bak&amp;quot;&lt;br /&gt;
    os.remove(OfileName)&lt;br /&gt;
    if CopyFileFromTo(NfileName, OfileName) then-- makes backup file&lt;br /&gt;
      local fileR = io.open(OfileName)&lt;br /&gt;
      local fileW = io.open(NfileName,  &amp;quot;w&amp;quot;)&lt;br /&gt;
      if fileR and fileW then&lt;br /&gt;
        local groups = false&lt;br /&gt;
        local txt = &amp;quot;&amp;quot;&lt;br /&gt;
        for Line in fileR:lines() do&lt;br /&gt;
          txt = Line&lt;br /&gt;
          if All_Trim(Line) == &amp;quot;[&amp;quot; .. All_Trim(xGroup) .. &amp;quot;]&amp;quot; then -- Group&lt;br /&gt;
            groups = true&lt;br /&gt;
          end -- if end&lt;br /&gt;
          if xItem == string.sub(Line, 1, string.len(xItem))  then  -- Item&lt;br /&gt;
            if groups then&lt;br /&gt;
              txt = xItem .. &amp;quot; = &amp;quot; .. xValue&lt;br /&gt;
              groups = false&lt;br /&gt;
            end -- if end&lt;br /&gt;
          end -- if end&lt;br /&gt;
          fileW:write(txt .. &amp;quot;\n&amp;quot;)&lt;br /&gt;
          txt = &amp;quot;&amp;quot;&lt;br /&gt;
        end -- for end&lt;br /&gt;
        os.remove(OfileName)&lt;br /&gt;
        fileR:close()&lt;br /&gt;
        fileW:close()&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_ReadProject===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Reads the ini file for project data&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_ReadProject(xPath, xFile, xGroup)&lt;br /&gt;
  -- Milling = {}&lt;br /&gt;
    Milling.LayerNameBackPocket          = GetIniValue(xPath, xFile, xGroup, &amp;quot;Milling.LayerNameBackPocket&amp;quot;, &amp;quot;S&amp;quot;)&lt;br /&gt;
    Milling.LayerNameTopBottomCenterDado = GetIniValue(xPath, xFile, xGroup, &amp;quot;Milling.LayerNameTopBottomCenterDado&amp;quot;, &amp;quot;S&amp;quot;)&lt;br /&gt;
    Milling.LayerNameDrawNotes           = GetIniValue(xPath, xFile, xGroup, &amp;quot;Milling.LayerNameDrawNotes&amp;quot;, &amp;quot;S&amp;quot;)&lt;br /&gt;
    Milling.LayerNameDrawFaceFrame       = GetIniValue(xPath, xFile, xGroup, &amp;quot;Milling.LayerNameDrawFaceFrame&amp;quot;, &amp;quot;S&amp;quot;)&lt;br /&gt;
    Milling.BackPocketDepthWall          = GetIniValue(xPath, xFile, xGroup, &amp;quot;Milling.BackPocketDepthWall&amp;quot;, &amp;quot;N&amp;quot;)&lt;br /&gt;
    Milling.BlindDadoSetbackWall         = GetIniValue(xPath, xFile, xGroup, &amp;quot;Milling.BlindDadoSetbackWall&amp;quot;, &amp;quot;N&amp;quot;)&lt;br /&gt;
    Milling.CabDepthWall                 = GetIniValue(xPath, xFile, xGroup, &amp;quot;Milling.CabDepthWall&amp;quot;, &amp;quot;N&amp;quot;)&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_TestDeleteDups===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Reads the ini file for dups and deletes&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_TestDeleteDups()&lt;br /&gt;
    --[[ Requires 3 global variables&lt;br /&gt;
    clean  = {}&lt;br /&gt;
    dups   = {}&lt;br /&gt;
    Names  = {}&lt;br /&gt;
    ]]&lt;br /&gt;
    local myPath = &amp;quot;C:\\Users\\CNC\\Documents\\test&amp;quot;&lt;br /&gt;
    local myName = &amp;quot;Tester&amp;quot;&lt;br /&gt;
    local myfile = &amp;quot;C:\\Users\\CNC\\Documents\\test\\Tester.ini&amp;quot;&lt;br /&gt;
    INI_ReadGroups(myfile, Names)&lt;br /&gt;
    FindDups(Names, dups, clean)&lt;br /&gt;
    for i,v in ipairs(dups) do&lt;br /&gt;
      INI_DeleteGroup(myPath, myName, v)&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Data Import Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is used to import data to a gadget.&lt;br /&gt;
&lt;br /&gt;
===Read_CSV===&lt;br /&gt;
Reads a CSV file based on header and format (Requires modifications per usage)&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function Read_CSV(xFile, Header)&lt;br /&gt;
  --Read_CSV(Door.CSVFile, true)&lt;br /&gt;
  local fileR = io.open(xFile)&lt;br /&gt;
  local xLine = &amp;quot;&amp;quot;&lt;br /&gt;
  local result = {}&lt;br /&gt;
  if fileR then&lt;br /&gt;
    for Line in fileR:lines() do&lt;br /&gt;
      xLine = Line&lt;br /&gt;
      if Header then&lt;br /&gt;
        Header = false&lt;br /&gt;
      else&lt;br /&gt;
        xLine = All_Trim(Line)&lt;br /&gt;
        for match in (xLine..&amp;quot;,&amp;quot;):gmatch(&amp;quot;(.-)&amp;quot;..&amp;quot;,&amp;quot;) do&lt;br /&gt;
          table.insert(result, match)&lt;br /&gt;
        end -- for end&lt;br /&gt;
        Door.Count     = tonumber(result[1])&lt;br /&gt;
        Door.Height    = tonumber(result[2])&lt;br /&gt;
        Door.Width     = tonumber(result[3])&lt;br /&gt;
&lt;br /&gt;
        result = {}&lt;br /&gt;
        while Door.Count &amp;gt; 0 do&lt;br /&gt;
          if      Door.Style == StyleA.Name then&lt;br /&gt;
            DoorStyleA()&lt;br /&gt;
          elseif  Door.Style == StyleB.Name then&lt;br /&gt;
            DoorStyleB()&lt;br /&gt;
          elseif  Door.Style == StyleC.Name then&lt;br /&gt;
            DoorStyleC()&lt;br /&gt;
          elseif  Door.Style == StyleE.Name then&lt;br /&gt;
            DoorStyleE()&lt;br /&gt;
          elseif  Door.Style == StyleF.Name then&lt;br /&gt;
            DoorStyleF()&lt;br /&gt;
          elseif  Door.Style == StyleG.Name then&lt;br /&gt;
            DoorStyleG()&lt;br /&gt;
          else&lt;br /&gt;
            DisplayMessageBox(&amp;quot;No Style Select!&amp;quot;)&lt;br /&gt;
          end --if end&lt;br /&gt;
          Door.Count =  Door.Count - 1&lt;br /&gt;
        end -- for end&lt;br /&gt;
      end --if end&lt;br /&gt;
      Door.Record = Door.Record + 1&lt;br /&gt;
      MyProgressBar:SetPercentProgress(ProgressAmount(Door.Record))&lt;br /&gt;
    end --for end&lt;br /&gt;
  end --if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Job Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function ValidJob()&lt;br /&gt;
  -- A better error message&lt;br /&gt;
    local job = VectricJob()&lt;br /&gt;
    if not job.Exists then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error: Cannot run Gadget, no drawing found \n&amp;quot; ..&lt;br /&gt;
                        &amp;quot;Please create a new file (drawing) and \n&amp;quot; ..&lt;br /&gt;
                        &amp;quot;specify the material dimensions \n&amp;quot;&lt;br /&gt;
      )&lt;br /&gt;
      return false&lt;br /&gt;
    else&lt;br /&gt;
      return true&lt;br /&gt;
    end  -- if end&lt;br /&gt;
  end -- ValidJob end&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===MoveSetectedVectors===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function MoveSetectedVectors(job, NewBasePoint)&lt;br /&gt;
    local Selection = job.Selection&lt;br /&gt;
    if Selection.IsEmpty then&lt;br /&gt;
      MessageBox(&amp;quot;LayoutImportedVectors: No vectors selected!&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    local MySelection = Selection:GetBoundingBox();&lt;br /&gt;
    if not NewBasePoint then&lt;br /&gt;
      NewBasePoint = Point2D(0,0)&lt;br /&gt;
    end&lt;br /&gt;
    local MyNewLocatioin = BasePoint - MySelection.BLC&lt;br /&gt;
    local Txform = TranslationMatrix2D(MyNewLocatioin)&lt;br /&gt;
    Selection:Transform(Txform)&lt;br /&gt;
    return true&lt;br /&gt;
  end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===FixPath===&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function FixPath(path)                                -- Lua Returns a fixed path&lt;br /&gt;
    return path:gsub(&amp;quot;%\\&amp;quot;, &amp;quot;/&amp;quot;)&lt;br /&gt;
  end -- function end&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
  function FixPath(myPath) {                            -- JavaScript Tool Returns a fixed path&lt;br /&gt;
    /* myPath  = &amp;quot;C:\\User\\Bob\\Home\\Drawings&amp;quot;; */&lt;br /&gt;
    /* NewPath = &amp;quot;C:/User/Bob/Home/Drawings&amp;quot;; */&lt;br /&gt;
    var NewPath = &amp;quot;&amp;quot;;&lt;br /&gt;
    var myLetter = &amp;quot;&amp;quot;;&lt;br /&gt;
    var CheckPathLen = myPath.length;&lt;br /&gt;
    for (let i = 0; i &amp;lt; myPath.length; i++) {&lt;br /&gt;
      myLetter = myPath.charAt(i)&lt;br /&gt;
      if myLetter.charCodeAt(0) == 92 {&lt;br /&gt;
        NewPath = NewPath + &amp;quot;/&amp;quot;;&lt;br /&gt;
      } else {&lt;br /&gt;
        NewPath = NewPath + myLetter;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    return NewPath;&lt;br /&gt;
  }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===RotateSetectedVectors===&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function RotateSetectedVectors(job, NewBasePoint, NewAngle)&lt;br /&gt;
    local Selection = job.Selection&lt;br /&gt;
    if not NewBasePoint then&lt;br /&gt;
      NewBasePoint = Point2D(0,0)&lt;br /&gt;
    end -- if end&lt;br /&gt;
    if not NewAngle then&lt;br /&gt;
      NewAngle = 0.0&lt;br /&gt;
    end -- if end&lt;br /&gt;
    if Selection.IsEmpty then&lt;br /&gt;
      MessageBox(&amp;quot;Error: Rotation function: No vectors selected!&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    local MySelection = Selection:GetBoundingBox();&lt;br /&gt;
    local MyNewLocatioin = BasePoint - MySelection.BLC&lt;br /&gt;
    local Txform = RotationMatrix2D(NewBasePoint, NewAngle)&lt;br /&gt;
    Selection:Transform(Txform)&lt;br /&gt;
    return true&lt;br /&gt;
  end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetUnits===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function GetUnits(UTable)                               -- returns Drawing Units data&lt;br /&gt;
    local mtl_block = MaterialBlock()&lt;br /&gt;
    if mtl_block.InMM then&lt;br /&gt;
      UTable.Units  = &amp;quot;Drawing Units: mm&amp;quot;&lt;br /&gt;
      UTable.Unit = true&lt;br /&gt;
      UTable.UnitCheck = {&amp;quot;metric&amp;quot;, &amp;quot;kilometer&amp;quot;, &amp;quot;kilometers&amp;quot;, &amp;quot;kh&amp;quot;, &amp;quot;meter&amp;quot;, &amp;quot;meters&amp;quot;, &amp;quot;m&amp;quot;, &amp;quot;decimeter&amp;quot;, &amp;quot;decimeters&amp;quot;, &amp;quot;dm&amp;quot;, &amp;quot;centimeter&amp;quot;, &amp;quot;centimeters&amp;quot;, &amp;quot;cm&amp;quot;, &amp;quot;millimeter&amp;quot;, &amp;quot;millimeters&amp;quot;, &amp;quot;mm&amp;quot;}&lt;br /&gt;
      UTable.Cal = 25.4&lt;br /&gt;
    else&lt;br /&gt;
      UTable.Units  = &amp;quot;Drawing Units: inches&amp;quot;&lt;br /&gt;
      UTable.Unit = false&lt;br /&gt;
      UTable.UnitCheck = {&amp;quot;imperial&amp;quot;, &amp;quot;miles&amp;quot;, &amp;quot;mile&amp;quot;, &amp;quot;mi&amp;quot;, &amp;quot;yards&amp;quot;, &amp;quot;yard&amp;quot;, &amp;quot;yd&amp;quot;, &amp;quot;feet&amp;quot;, &amp;quot;foot&amp;quot;, &amp;quot;ft&amp;quot;, &amp;quot;inches&amp;quot;, &amp;quot;inch&amp;quot;, &amp;quot;in&amp;quot;, &amp;quot;fractions&amp;quot;, &amp;quot;fraction&amp;quot;}&lt;br /&gt;
      UTable.Cal = 1.0&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
  end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CheckTheUnits===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function CheckTheUnits(UTable, Value)                     -- Checks if the unit of messure in of drawing units&lt;br /&gt;
  local goodtogo = false&lt;br /&gt;
  for i=1, #UTable.UnitCheck  do&lt;br /&gt;
    if string.upper(Value) == string.upper(UTable.UnitCheck[i]) then&lt;br /&gt;
      goodtogo = true&lt;br /&gt;
      break&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- for end&lt;br /&gt;
  if goodtogo then&lt;br /&gt;
    return true&lt;br /&gt;
  else&lt;br /&gt;
    return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetMatlBlk===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function GetMatlBlk(Table)&lt;br /&gt;
    local mtl_block = MaterialBlock()&lt;br /&gt;
    if mtl_block.InMM then&lt;br /&gt;
      Table.Units = &amp;quot;Drawing Units: mm&amp;quot;&lt;br /&gt;
      Table.Unit = true&lt;br /&gt;
    else&lt;br /&gt;
      Table.Units = &amp;quot;Drawing Units: inches&amp;quot;&lt;br /&gt;
      Table.Unit = false&lt;br /&gt;
    end&lt;br /&gt;
    if mtl_block.Width&amp;gt; mtl_block.Height then&lt;br /&gt;
      Table.MaterialThickness = mtl_block.Height&lt;br /&gt;
      Table.MaterialLength = mtl_block.Width&lt;br /&gt;
      Table.Orantation = &amp;quot;H&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      Table.MaterialThickness = mtl_block.Width&lt;br /&gt;
      Table.MaterialLength = mtl_block.Height&lt;br /&gt;
      Table.Orantation = &amp;quot;V&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    Table.FrontThickness = Dovetail.MaterialThickness&lt;br /&gt;
    Table.SideThickness = Dovetail.MaterialThickness&lt;br /&gt;
    if mtl_block.Height == mtl_block.Width then&lt;br /&gt;
        MessageBox(&amp;quot;Error! Material block cannot square&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
  end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetBoxJointMaterialSettings===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function GetBoxJointMaterialSettings(Table)&lt;br /&gt;
    local mtl_block = MaterialBlock()&lt;br /&gt;
    --local units&lt;br /&gt;
    if mtl_block.InMM then&lt;br /&gt;
      Table.Units = &amp;quot;Drawing Units: mm&amp;quot;&lt;br /&gt;
      Table.Unit = true&lt;br /&gt;
    else&lt;br /&gt;
      Table.Units = &amp;quot;Drawing Units: inches&amp;quot;&lt;br /&gt;
      Table.Unit = false&lt;br /&gt;
    end&lt;br /&gt;
    if mtl_block.Width &amp;gt; mtl_block.Height then&lt;br /&gt;
      Table.MaterialThickness = mtl_block.Height&lt;br /&gt;
      Table.MaterialLength = mtl_block.Width&lt;br /&gt;
      Table.Orantation = &amp;quot;H&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      Table.MaterialThickness = mtl_block.Width&lt;br /&gt;
      Table.MaterialLength = mtl_block.Height&lt;br /&gt;
      Table.Orantation = &amp;quot;V&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    if mtl_block.Height == mtl_block.Width then&lt;br /&gt;
      MessageBox(&amp;quot;Error! Material block cannot square&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    -- Display material XY origin&lt;br /&gt;
    local xy_origin_text = &amp;quot;invalid&amp;quot;&lt;br /&gt;
    local xy_origin = mtl_block.XYOrigin&lt;br /&gt;
    if  xy_origin == MaterialBlock.BLC then&lt;br /&gt;
        Table.xy_origin_text = &amp;quot;Bottom Left Corner&amp;quot;&lt;br /&gt;
      if Table.Orantation == &amp;quot;V&amp;quot; then&lt;br /&gt;
        Table.Direction1 = 90.0&lt;br /&gt;
        Table.Direction2 = 0.0&lt;br /&gt;
        Table.Direction3 = 270.0&lt;br /&gt;
        Table.Direction4 = 180.0&lt;br /&gt;
        Table.Bulge = 1.0&lt;br /&gt;
      else&lt;br /&gt;
        Table.Direction1 = 0.0&lt;br /&gt;
        Table.Direction2 = 90.0&lt;br /&gt;
        Table.Direction3 = 180.0&lt;br /&gt;
        Table.Direction4 = 270.0&lt;br /&gt;
        Table.Bulge = -1.0&lt;br /&gt;
      end&lt;br /&gt;
    elseif xy_origin == MaterialBlock.BRC then&lt;br /&gt;
      Table.xy_origin_text = &amp;quot;Bottom Right Corner&amp;quot;&lt;br /&gt;
      if Table.Orantation == &amp;quot;V&amp;quot; then&lt;br /&gt;
        Table.Direction1 = 90.0&lt;br /&gt;
        Table.Direction2 = 180.0&lt;br /&gt;
        Table.Direction3 = 270.0&lt;br /&gt;
        Table.Direction4 = 0.0&lt;br /&gt;
        Table.Bulge = -1.0&lt;br /&gt;
      else&lt;br /&gt;
        Table.Direction1 = 180.0&lt;br /&gt;
        Table.Direction2 = 90.0&lt;br /&gt;
        Table.Direction3 = 0.0&lt;br /&gt;
        Table.Direction4 = 270.0&lt;br /&gt;
        Table.Bulge = 1.0&lt;br /&gt;
      end&lt;br /&gt;
    elseif xy_origin == MaterialBlock.TRC then&lt;br /&gt;
      Table.xy_origin_text = &amp;quot;Top Right Corner&amp;quot;&lt;br /&gt;
      if Table.Orantation == &amp;quot;V&amp;quot; then&lt;br /&gt;
        Table.Direction1 = 270.0&lt;br /&gt;
        Table.Direction2 = 180.0&lt;br /&gt;
        Table.Direction3 = 90.0&lt;br /&gt;
        Table.Direction4 = 0.0&lt;br /&gt;
        Table.Bulge = 1.0&lt;br /&gt;
      else&lt;br /&gt;
        Table.Direction1 = 180.0&lt;br /&gt;
        Table.Direction2 = 270.0&lt;br /&gt;
        Table.Direction3 = 0.0&lt;br /&gt;
        Table.Direction4 = 90.0&lt;br /&gt;
        Table.Bulge = -1.0&lt;br /&gt;
      end&lt;br /&gt;
    elseif xy_origin == MaterialBlock.TLC then&lt;br /&gt;
      Table.xy_origin_text = &amp;quot;Top Left Corner&amp;quot;&lt;br /&gt;
      if Table.Orantation == &amp;quot;V&amp;quot; then&lt;br /&gt;
        Table.Direction1 = 270.0&lt;br /&gt;
        Table.Direction2 = 0.0&lt;br /&gt;
        Table.Direction3 = 90.0&lt;br /&gt;
        Table.Direction4 = 180.0&lt;br /&gt;
        Table.Bulge = -1.0&lt;br /&gt;
      else&lt;br /&gt;
        Table.Direction1 = 0.0&lt;br /&gt;
        Table.Direction2 = 270.0&lt;br /&gt;
        Table.Direction3 = 180.0&lt;br /&gt;
        Table.Direction4 = 90.0&lt;br /&gt;
        Table.Bulge = 1.0&lt;br /&gt;
      end&lt;br /&gt;
    elseif xy_origin == MaterialBlock.CENTRE then  -- NOTE: English spelling for Centre!&lt;br /&gt;
      Table.xy_origin_text = &amp;quot;Center&amp;quot;&lt;br /&gt;
      if Table.Orantation == &amp;quot;V&amp;quot; then&lt;br /&gt;
        Table.Direction1 = 0.0&lt;br /&gt;
        Table.Direction2 = 0.0&lt;br /&gt;
        Table.Direction3 = 0.0&lt;br /&gt;
        Table.Direction4 = 0.0&lt;br /&gt;
        Table.Bulge = 1.0&lt;br /&gt;
      else&lt;br /&gt;
        Table.Direction1 = 0.0&lt;br /&gt;
        Table.Direction2 = 0.0&lt;br /&gt;
        Table.Direction3 = 0.0&lt;br /&gt;
        Table.Direction4 = 0.0&lt;br /&gt;
        Table.Bulge = -1.0&lt;br /&gt;
      end&lt;br /&gt;
        MessageBox(&amp;quot;Error! &amp;quot; .. xy_origin_text .. &amp;quot; Must be set at a corner of the Material&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
        Table.xy_origin_text = &amp;quot;Unknown XY origin value!&amp;quot;&lt;br /&gt;
        MessageBox(&amp;quot;Error! &amp;quot; .. xy_origin_text .. &amp;quot; Must be set at a corner of the Material&amp;quot;)&lt;br /&gt;
      if Table.Orantation == &amp;quot;V&amp;quot; then&lt;br /&gt;
        Table.Direction1 = 0&lt;br /&gt;
        Table.Direction2 = 0&lt;br /&gt;
        Table.Direction3 = 0&lt;br /&gt;
        Table.Direction4 = 0&lt;br /&gt;
      else&lt;br /&gt;
        Table.Direction1 = 0&lt;br /&gt;
        Table.Direction2 = 0&lt;br /&gt;
        Table.Direction3 = 0&lt;br /&gt;
        Table.Direction4 = 0&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    -- Setup Fingers and Gaps&lt;br /&gt;
    Table.NoFingers0 = 1 + (Rounder(BoxJoint.MaterialLength / BoxJoint.MaterialThickness, 0))&lt;br /&gt;
    Table.NoFingers2 = Rounder(BoxJoint.NoFingers0 / 2, 0)&lt;br /&gt;
    Table.FingerSize = BoxJoint.MaterialLength /  BoxJoint.NoFingers0&lt;br /&gt;
    Table.NoFingers1 = BoxJoint.NoFingers0 - BoxJoint.NoFingers2&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetMaterialSettings===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function GetMaterialSettings(Table)&lt;br /&gt;
  local MaterialBlock = MaterialBlock()&lt;br /&gt;
  Table.MaterialBlockThickness = MaterialBlock.Thickness&lt;br /&gt;
  Table.xy_origin = MaterialBlock.XYOrigin&lt;br /&gt;
  if MaterialBlock.InMM then&lt;br /&gt;
    Table.Units  = &amp;quot;Drawing Units: mm&amp;quot;&lt;br /&gt;
    Table.Unit = true&lt;br /&gt;
    Table.Cal = 25.4&lt;br /&gt;
  else&lt;br /&gt;
    Table.Units  = &amp;quot;Drawing Units: inches&amp;quot;&lt;br /&gt;
    Table.Unit = false&lt;br /&gt;
    Table.Cal = 1.0&lt;br /&gt;
  end&lt;br /&gt;
  --local units&lt;br /&gt;
	if MaterialBlock.Width &amp;gt; MaterialBlock.Height then&lt;br /&gt;
    Table.Orantation = &amp;quot;H&amp;quot; -- Horizontal&lt;br /&gt;
	elseif MaterialBlock.Width &amp;lt; MaterialBlock.Height then&lt;br /&gt;
    Table.Orantation = &amp;quot;V&amp;quot;  -- Vertical&lt;br /&gt;
  else&lt;br /&gt;
    Table.Orantation = &amp;quot;S&amp;quot; -- Squair&lt;br /&gt;
	end&lt;br /&gt;
  if Table.xy_origin == MaterialBlock.BLC then&lt;br /&gt;
    Table.XYorigin = &amp;quot;Bottom Left Corner&amp;quot;&lt;br /&gt;
  elseif Table.xy_origin == MaterialBlock.BRC then&lt;br /&gt;
    Table.XYorigin = &amp;quot;Bottom Right Corner&amp;quot;&lt;br /&gt;
  elseif Table.xy_origin == MaterialBlock.TRC then&lt;br /&gt;
    Table.XYorigin = &amp;quot;Top Right Corner&amp;quot;&lt;br /&gt;
  else&lt;br /&gt;
    Table.XYorigin = &amp;quot;Top Left Corner&amp;quot;&lt;br /&gt;
  end -- if end&lt;br /&gt;
  Table.UnitDisplay  = &amp;quot;Note: Units: (&amp;quot; .. Table.Units ..&amp;quot;)&amp;quot;&lt;br /&gt;
  return true&lt;br /&gt;
end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===IsSingleSided===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function IsSingleSided(Table)&lt;br /&gt;
    local SingleSided = Table.job.IsSingleSided&lt;br /&gt;
    if not SingleSided then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error: Job must be a single sided job&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end  -- if end&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===IsDoubleSided===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function IsDoubleSided(Table)&lt;br /&gt;
  if not Table.job.IsDoubleSided then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Error: Job must be a Double Sided Project&amp;quot;)&lt;br /&gt;
    return false&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end  -- if end&lt;br /&gt;
end-- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===ShowSetting===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function ShowSetting(Table)&lt;br /&gt;
  local name = &amp;quot;&amp;quot;&lt;br /&gt;
      DisplayMessageBox(&lt;br /&gt;
    name .. &amp;quot; MaterialThickness = &amp;quot; .. tostring(Table.MaterialThickness) ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    name .. &amp;quot; BottleRad         = &amp;quot; .. tostring(Table.BottleRad)         ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    name .. &amp;quot; SideLenght        = &amp;quot; .. tostring(Table.SideLenght)        ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    name .. &amp;quot; SideHight         = &amp;quot; .. tostring(Table.SideHight)         ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    name .. &amp;quot; EndLenght         = &amp;quot; .. tostring(Table.EndLenght)         ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    name .. &amp;quot; EndHight          = &amp;quot; .. tostring(Table.EndHight)          ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    name .. &amp;quot; TopLenght         = &amp;quot; .. tostring(Table.TopLenght)         ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    name .. &amp;quot; TopWidht          = &amp;quot; .. tostring(Table.TopWidht)          ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    name .. &amp;quot; HandleLenght      = &amp;quot; .. tostring(Table.HandleLenght)      ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    name .. &amp;quot; HandleWidht       = &amp;quot; .. tostring(Table.HandleWidht)       ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    name .. &amp;quot; HandleRad         = &amp;quot; .. tostring(Table.HandleRad)         ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    name .. &amp;quot; MillingBitRad     = &amp;quot; .. tostring(Table.MillingBitRad)     ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    &amp;quot;\n&amp;quot;)&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===MakeLayers===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function MakeLayers()&lt;br /&gt;
  local Red, Green, Blue = 0, 0, 0&lt;br /&gt;
  local function GetColor(str) -- returns color value for a Color Name&lt;br /&gt;
    local sx = str&lt;br /&gt;
    local Red = 0&lt;br /&gt;
    local Green = 0&lt;br /&gt;
    local Blue = 0&lt;br /&gt;
    local Colors = {}&lt;br /&gt;
    Colors.Black = &amp;quot;0,0,0&amp;quot;&lt;br /&gt;
    Colors.Red = &amp;quot;255,0,0&amp;quot;&lt;br /&gt;
    Colors.Blue = &amp;quot;0,0,255&amp;quot;&lt;br /&gt;
    Colors.Yellow = &amp;quot;255,255,0&amp;quot;&lt;br /&gt;
    Colors.Cyan = &amp;quot;0,255,255&amp;quot;&lt;br /&gt;
    Colors.Magenta = &amp;quot;255,0,255&amp;quot;&lt;br /&gt;
    Colors.Green = &amp;quot;0,128,0&amp;quot;&lt;br /&gt;
    if &amp;quot;&amp;quot; == str then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error: Empty string passed&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      str = Colors[str]&lt;br /&gt;
      if &amp;quot;string&amp;quot; == type(str) then&lt;br /&gt;
        if string.find(str, &amp;quot;,&amp;quot;) then&lt;br /&gt;
          Red   = tonumber(string.sub(str, 1, assert(string.find(str, &amp;quot;,&amp;quot;) - 1)))&lt;br /&gt;
          str  = string.sub(str, assert(string.find(str, &amp;quot;,&amp;quot;) + 1))&lt;br /&gt;
          Green = tonumber(string.sub(str, 1, assert(string.find(str, &amp;quot;,&amp;quot;) - 1)))&lt;br /&gt;
          Blue  = tonumber(string.sub(str, assert(string.find(str, &amp;quot;,&amp;quot;) + 1)))&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        DisplayMessageBox(&amp;quot;Error: Color &amp;quot; .. sx .. &amp;quot; not Found&amp;quot; )&lt;br /&gt;
        Red = 0&lt;br /&gt;
        Green = 0&lt;br /&gt;
        Blue = 0&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    return Red, Green, Blue&lt;br /&gt;
  end&lt;br /&gt;
  local layer = Milling.job.LayerManager:GetLayerWithName(Milling.LNBackPocket)&lt;br /&gt;
        Red, Green, Blue = GetColor(Milling.LNBackPocketColor)&lt;br /&gt;
        layer:SetColor (Red, Green, Blue)&lt;br /&gt;
        layer = Milling.job.LayerManager:GetLayerWithName(Milling.LNBackProfile)&lt;br /&gt;
        Red, Green, Blue = GetColor(Milling.LNBackProfileColor)&lt;br /&gt;
        layer:SetColor (Red, Green, Blue)&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===MyLayerClear===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function MyLayerClear(LayerName)&lt;br /&gt;
  local Mylayer = Milling.job.LayerManager:GetLayerWithName(LayerName)&lt;br /&gt;
     if Mylayer.IsEmpty then&lt;br /&gt;
        Milling.job.LayerManager:RemoveLayer(Mylayer)&lt;br /&gt;
     end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===LayerClear===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function LayerClear()                       --  calling MyLayerClear&lt;br /&gt;
  MyLayerClear(Milling.LNBackPocket  .. &amp;quot;-Wall&amp;quot;)&lt;br /&gt;
  MyLayerClear(Milling.LNBackPocket  .. &amp;quot;-Base&amp;quot;)&lt;br /&gt;
  MyLayerClear(Milling.LNBackProfile .. &amp;quot;-Wall&amp;quot;)&lt;br /&gt;
  MyLayerClear(Milling.LNBackProfile .. &amp;quot;-Base&amp;quot;)&lt;br /&gt;
  MyLayerClear(&amp;quot;PartLabels&amp;quot;)&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Logic and Test Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
These functions are named as per there function or action.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CheckNumber===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function CheckNumber(num)&lt;br /&gt;
  if type(num) == &amp;quot;number&amp;quot; then&lt;br /&gt;
    return true&lt;br /&gt;
  else&lt;br /&gt;
   return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===AboveZero===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function AboveZero(num)&lt;br /&gt;
  if (type(num) == &amp;quot;number&amp;quot;) and (num &amp;gt; 0.0)then&lt;br /&gt;
    return true&lt;br /&gt;
  else&lt;br /&gt;
   return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
end -- function end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===IsNumber()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function IsNumber(Val)                     --Return true if Val is number&lt;br /&gt;
    if tonumber(x) ~= nil then&lt;br /&gt;
      return true&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return false&lt;br /&gt;
  end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===IsEven()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function IsEven(IsEven_Number)             -- Returns True/False if number is even&lt;br /&gt;
    if (IsEven_Number % 2 == 0) then&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===IsOdd()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function IsOdd(IsOdd_Number)                          -- Returns True/False if number is odd&lt;br /&gt;
    if(IsOdd_Number%2 == 0) then&lt;br /&gt;
      return false&lt;br /&gt;
    end -- end if&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===IsNegative()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function IsNegative(x)                     -- Returns True/False if number is a negative number  &lt;br /&gt;
  if x &amp;gt;=0.0 then&lt;br /&gt;
    return false&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end -- if end&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
===IsAllNumber()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function IsAllNumber(str)                  -- Returns True/False if finds all numbers in string&lt;br /&gt;
  local out = true                                     &lt;br /&gt;
  local let = &amp;quot;&amp;quot;&lt;br /&gt;
  for i = 1, #str do&lt;br /&gt;
    let = str:byte(i)&lt;br /&gt;
    if (let ~= 48) and (let ~= 49) and (let ~= 50) and (let ~= 51) and&lt;br /&gt;
       (let ~= 52) and (let ~= 53) and (let ~= 54) and (let ~= 55) and&lt;br /&gt;
       (let ~= 56) and (let ~= 57) and (let ~= 46) then&lt;br /&gt;
      out = false&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- for end&lt;br /&gt;
  return out        -- send out the return&lt;br /&gt;
end  -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===NonNumber()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function NonNumber(Val)                    -- Return true if val is not number&lt;br /&gt;
    if tonumber(x) ~= nil then&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return true&lt;br /&gt;
  end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===NumberType()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function NumberType(Val)                   -- Return true if val is not number&lt;br /&gt;
    if math.type(x) == &amp;quot;integer&amp;quot; then&lt;br /&gt;
      return &amp;quot;integer&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      return &amp;quot;float&amp;quot;&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Math Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===ArcSegment()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function ArcSegment(p1, p2, Rad)                       -- Returns the Arc Segment&lt;br /&gt;
  local chord = math.sqrt(((p2.x - p1.x) ^ 2) + ((p2.y - p1.y) ^ 2))&lt;br /&gt;
  local segment = (Rad - (0.5 * (math.sqrt((4.0 * Rad^2) - chord^2))))&lt;br /&gt;
  return segment&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===D(x) Doubles x===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function D(x)                                           -- Returns double the value&lt;br /&gt;
  return x * 2.0&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===H(x) Halfs x===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function H(x)                                           -- Returns half the value&lt;br /&gt;
  return x * 0.5&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===C(x) Returns x by scale===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function C(x)                                           -- Returns scale value&lt;br /&gt;
  return x * Project.Cal&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===ChordSag2Radius()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function ChordSag2Radius (Chr, Seg)                     -- Returns the Rad from Chord and Seg&lt;br /&gt;
  local rad = ((((Chr * Chr)/(Seg * 4)) + Seg) / 2.0)&lt;br /&gt;
  return rad&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===RadSag2Chord()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function RadSag2Chord(Rad, Seg)                         -- Returns the Chord from Rad and Seg&lt;br /&gt;
  local Ang = 2 * math.acos(1 - (Seg/Rad))&lt;br /&gt;
  local Chord = (2 * Rad) * math.sin(Ang * 0.5)&lt;br /&gt;
  return Chord&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===RadChord2Segment()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function RadChord2Segment (Rad, Chord)       -- Returns the Arc Segment from Rad and Chord&lt;br /&gt;
  local segment = (Rad - (0.5 * (math.sqrt((4.0 * Rad^2) - Chord^2))))&lt;br /&gt;
  return segment&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===RoundTo()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function RoundTo(Num, Per)                   -- Returns the number from&lt;br /&gt;
  local Head = Num &amp;lt; 0 and math.ceil(Num) or math.floor(Num)&lt;br /&gt;
  local Tail = Num - Head&lt;br /&gt;
  local Value = Head + tonumber(string.sub(tostring(Tail), 1, Per + 2))&lt;br /&gt;
  return Value&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Round()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function Round(x)&lt;br /&gt;
  return x&amp;gt;=0 and math.floor(x+0.5) or math.ceil(x-0.5)&lt;br /&gt;
end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DecimalPlaces()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DecimalPlaces(Dnum, Plac)&lt;br /&gt;
  return tonumber(string.sub(tostring(Dnum)  .. &amp;quot;000000000000000000000000000000000000&amp;quot;,1, string.len(tostring(math.floor(Dnum))) + 1 + Plac))&lt;br /&gt;
end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===ToInteger()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function ToInteger( x )&lt;br /&gt;
    local num = tonumber( x )&lt;br /&gt;
    return num &amp;lt; 0 and math.ceil( num ) or math.floor( num )&lt;br /&gt;
end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===TrigIt===&lt;br /&gt;
Finds all 5 properties of a triangle&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function TrigIt(A, B, AB, AC, BC)&lt;br /&gt;
-- Sub Function to help other functions&lt;br /&gt;
-- Call = A, B, AB, AC, BC = Trig(A, B, AB, AC, BC)&lt;br /&gt;
-- C is the corner, A = small ang and B is the big angle&lt;br /&gt;
-- returns all values&lt;br /&gt;
-- A, B = angles&lt;br /&gt;
-- C = 90.0 Deg&lt;br /&gt;
-- B to C (BC) is Run - Base - adjacent&lt;br /&gt;
-- A to C (AC) is Rise - Height - opposite&lt;br /&gt;
-- A to B (AB) is Slope - hypotenuse&lt;br /&gt;
    if (B &amp;gt; 0.0) and (A == 0.0) then&lt;br /&gt;
      A = math.deg(math.rad(90) - math.rad(B))&lt;br /&gt;
    end&lt;br /&gt;
    if (A &amp;gt; 0.0) and (B == 0.0) then&lt;br /&gt;
      B = math.deg(math.rad(90) - math.rad(A))&lt;br /&gt;
    end&lt;br /&gt;
    if  (AC &amp;gt; 0.0) and (BC &amp;gt; 0.0) then&lt;br /&gt;
      AB = math.sqrt((AC ^ 2) + (BC ^ 2))&lt;br /&gt;
      A = math.deg(math.atan(BC/AC))&lt;br /&gt;
      B = math.deg(math.rad(90) - math.rad(A))&lt;br /&gt;
    elseif (AB &amp;gt; 0.0) and (BC &amp;gt; 0.0) then&lt;br /&gt;
      AB = math.sqrt((AB ^ 2) - (BC ^ 2))&lt;br /&gt;
      A = math.deg(math.atan(BC/AC))&lt;br /&gt;
      B = math.deg(math.rad(90) - math.rad(A))&lt;br /&gt;
    elseif (AB &amp;gt; 0.0) and (AC &amp;gt; 0.0) then&lt;br /&gt;
      AB = math.sqrt((AB ^ 2) - (AC ^ 2))&lt;br /&gt;
      A = math.deg(math.atan(BC/AC))&lt;br /&gt;
      B = math.deg(math.rad(90) - math.rad(A))&lt;br /&gt;
    elseif (A &amp;gt; 0.0) and (AC &amp;gt; 0.0) then&lt;br /&gt;
      AB = AC / math.cos(math.rad(A))&lt;br /&gt;
      BC = AB * math.sin(math.rad(A))&lt;br /&gt;
    elseif (A &amp;gt; 0.0) and (BC &amp;gt; 0.0) then&lt;br /&gt;
      AB = BC / math.sin(math.rad(A))&lt;br /&gt;
      AC = AB * math.cos(math.rad(A))&lt;br /&gt;
    elseif (A &amp;gt; 0.0) and (AB &amp;gt; 0.0) then&lt;br /&gt;
      BC = AB * math.sin(math.rad(A))&lt;br /&gt;
      AC = AB * math.cos(math.rad(A))&lt;br /&gt;
    else&lt;br /&gt;
      MessageBox(&amp;quot;Error: No Missing Value&amp;quot;)&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return A, B, AB, AC, BC&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Registry Read and Write Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DocVarChk()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DocVarChk(Name, Value)&lt;br /&gt;
  local job = VectricJob()&lt;br /&gt;
  local document_variable_list = job.DocumentVariables&lt;br /&gt;
  return document_variable_list:DocumentVariableExists(Name)&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DocVarGet()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DocVarGet(Name)&lt;br /&gt;
  local job = VectricJob()&lt;br /&gt;
  local document_variable_list = job.DocumentVariables&lt;br /&gt;
  return document_variable_list:GetDocumentVariable(Name, 0.0)&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DocVarSet()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DocVarSet(Name, Value)&lt;br /&gt;
  local job = VectricJob()&lt;br /&gt;
  local document_variable_list = job.DocumentVariables&lt;br /&gt;
  return document_variable_list:SetDocumentVariable(Name, Value)&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===RegistryReadMaterial()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function RegistryReadMaterial()                -- Read from Registry Material values for LUA Bit&lt;br /&gt;
  local RegistryRead              = Registry(&amp;quot;Material&amp;quot;)&lt;br /&gt;
  Milling.SafeZGap                = Rounder(RegistryRead:GetString(&amp;quot;SafeZGap&amp;quot;,              &amp;quot;0.500&amp;quot;), 4)&lt;br /&gt;
  Milling.StartZGap               = Rounder(RegistryRead:GetString(&amp;quot;StartZGap&amp;quot;,             &amp;quot;0.500&amp;quot;), 4)&lt;br /&gt;
  Milling.HomeX                   = Rounder(RegistryRead:GetString(&amp;quot;HomeX&amp;quot;,                 &amp;quot;0.000&amp;quot;), 4)&lt;br /&gt;
  Milling.HomeY                   = Rounder(RegistryRead:GetString(&amp;quot;HomeY&amp;quot;,                 &amp;quot;0.000&amp;quot;), 4)&lt;br /&gt;
  Milling.HomeZGap                = Rounder(RegistryRead:GetString(&amp;quot;HomeZGap&amp;quot;,              &amp;quot;0.750&amp;quot;), 4)&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===RegistryLastTenFiles()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function RegistryLastTenFiles(FileName)        -- Adds to the top ten Log file list&lt;br /&gt;
  local Registry = Registry(RegName)&lt;br /&gt;
  LogFile.File10 = Registry:GetString(&amp;quot;LogFile.File09&amp;quot;, &amp;quot;No Log Yet&amp;quot; )&lt;br /&gt;
  LogFile.File09 = Registry:GetString(&amp;quot;LogFile.File08&amp;quot;, &amp;quot;No Log Yet&amp;quot; )&lt;br /&gt;
  LogFile.File08 = Registry:GetString(&amp;quot;LogFile.File07&amp;quot;, &amp;quot;No Log Yet&amp;quot; )&lt;br /&gt;
  LogFile.File07 = Registry:GetString(&amp;quot;LogFile.File06&amp;quot;, &amp;quot;No Log Yet&amp;quot; )&lt;br /&gt;
  LogFile.File06 = Registry:GetString(&amp;quot;LogFile.File05&amp;quot;, &amp;quot;No Log Yet&amp;quot; )&lt;br /&gt;
  LogFile.File05 = Registry:GetString(&amp;quot;LogFile.File04&amp;quot;, &amp;quot;No Log Yet&amp;quot; )&lt;br /&gt;
  LogFile.File04 = Registry:GetString(&amp;quot;LogFile.File03&amp;quot;, &amp;quot;No Log Yet&amp;quot; )&lt;br /&gt;
  LogFile.File03 = Registry:GetString(&amp;quot;LogFile.File02&amp;quot;, &amp;quot;No Log Yet&amp;quot; )&lt;br /&gt;
  LogFile.File02 = Registry:GetString(&amp;quot;LogFile.File01&amp;quot;, &amp;quot;No Log Yet&amp;quot; )&lt;br /&gt;
  LogFile.File01 = FileName&lt;br /&gt;
  return FileName&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===RegistryRead()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function RegistryRead()                        -- Read from Registry values&lt;br /&gt;
  local RegistryRead = Registry(&amp;quot;RegName&amp;quot;)&lt;br /&gt;
  local Yes_No       = RegistryRead:GetBool(&amp;quot;BaseDim.Yes_No&amp;quot;, ture)&lt;br /&gt;
  local CabHeight    = RegistryRead:GetDouble(&amp;quot;BaseDim.CabHeight&amp;quot;, 35.500)&lt;br /&gt;
  local CabCount     = RegistryRead:GetInt(&amp;quot;BaseDim.CabCount&amp;quot;, 36)&lt;br /&gt;
  local Name         = RegistryRead:GetString(&amp;quot;BaseDim.Name&amp;quot;, &amp;quot;Words&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  Milling.MillTool1.FeedRate                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool1.FeedRate&amp;quot;,              30.000)&lt;br /&gt;
  Milling.MillTool1.InMM                    = RegistryRead:GetBool(&amp;quot;Milling.MillTool1.InMM &amp;quot;,                   false)&lt;br /&gt;
  Milling.MillTool1.Name                    = RegistryRead:GetString(&amp;quot;Milling.MillTool1.Name&amp;quot;,                  &amp;quot;No Tool Selected&amp;quot;)&lt;br /&gt;
  Milling.MillTool1.BitType                 = RegistryRead:GetString(&amp;quot;Milling.MillTool1.BitType&amp;quot;,               &amp;quot;END_MILL&amp;quot;) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
  Milling.MillTool1.RateUnits               = RegistryRead:GetInt(&amp;quot;Milling.MillTool1.RateUnits&amp;quot;,                4)&lt;br /&gt;
  Milling.MillTool1.SpindleSpeed            = RegistryRead:GetInt(&amp;quot;Milling.MillTool1.SpindleSpeed&amp;quot;,             20000)&lt;br /&gt;
  Milling.MillTool1.ToolNumber              = RegistryRead:GetInt(&amp;quot;Milling.MillTool1.ToolNumber&amp;quot;,               1)&lt;br /&gt;
  Milling.MillTool1.Stepdown                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool1.Stepdown&amp;quot;,              0.2000)&lt;br /&gt;
  Milling.MillTool1.Stepover                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool1.Stepover&amp;quot;,              0.0825)&lt;br /&gt;
  Milling.MillTool1.ToolDia                 = RegistryRead:GetDouble(&amp;quot;Milling.MillTool1.ToolDia&amp;quot;,               0.1250)&lt;br /&gt;
  Milling.MillTool1.PlungeRate              = RegistryRead:GetDouble(&amp;quot;Milling.MillTool1.PlungeRate&amp;quot;,            15.000)&lt;br /&gt;
&lt;br /&gt;
  Milling.MillTool2.FeedRate                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool2.FeedRate&amp;quot;,              30.000)&lt;br /&gt;
  Milling.MillTool2.InMM                    = RegistryRead:GetBool(&amp;quot;Milling.MillTool2.InMM &amp;quot;,                   false)&lt;br /&gt;
  Milling.MillTool2.Name                    = RegistryRead:GetString(&amp;quot;Milling.MillTool2.Name&amp;quot;,                  &amp;quot;No Tool Selected&amp;quot;)&lt;br /&gt;
  Milling.MillTool2.BitType                 = RegistryRead:GetString(&amp;quot;Milling.MillTool2.BitType&amp;quot;,               &amp;quot;BALL_NOSE&amp;quot;) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
  Milling.MillTool2.RateUnits               = RegistryRead:GetInt(&amp;quot;Milling.MillTool2.RateUnits&amp;quot;,                4)&lt;br /&gt;
  Milling.MillTool2.SpindleSpeed            = RegistryRead:GetInt(&amp;quot;Milling.MillTool2.SpindleSpeed&amp;quot;,             20000)&lt;br /&gt;
  Milling.MillTool2.ToolNumber              = RegistryRead:GetInt(&amp;quot;Milling.MillTool2.ToolNumber&amp;quot;,               2)&lt;br /&gt;
  Milling.MillTool2.Stepdown                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool2.Stepdown&amp;quot;,              0.2000)&lt;br /&gt;
  Milling.MillTool2.Stepover                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool2.Stepover&amp;quot;,              0.0825)&lt;br /&gt;
  Milling.MillTool2.ToolDia                 = RegistryRead:GetDouble(&amp;quot;Milling.MillTool2.ToolDia&amp;quot;,               0.1250)&lt;br /&gt;
  Milling.MillTool2.PlungeRate              = RegistryRead:GetDouble(&amp;quot;Milling.MillTool2.PlungeRate&amp;quot;,            15.000)&lt;br /&gt;
&lt;br /&gt;
  Milling.MillTool3.FeedRate                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool3.FeedRate&amp;quot;,              30.000)&lt;br /&gt;
  Milling.MillTool3.InMM                    = RegistryRead:GetBool(&amp;quot;Milling.MillTool3.InMM&amp;quot;,                    false)&lt;br /&gt;
  Milling.MillTool3.Name                    = RegistryRead:GetString(&amp;quot;Milling.MillTool3.Name&amp;quot;,                  &amp;quot;No Tool Selected&amp;quot;)&lt;br /&gt;
  Milling.MillTool3.BitType                 = RegistryRead:GetString(&amp;quot;Milling.MillTool3.BitType&amp;quot;,               &amp;quot;END_MILL&amp;quot;)  -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
  Milling.MillTool3.RateUnits               = RegistryRead:GetInt(&amp;quot;Milling.MillTool3.RateUnits&amp;quot;,                4)&lt;br /&gt;
  Milling.MillTool3.SpindleSpeed            = RegistryRead:GetInt(&amp;quot;Milling.MillTool3.SpindleSpeed&amp;quot;,             20000)&lt;br /&gt;
  Milling.MillTool3.ToolNumber              = RegistryRead:GetInt(&amp;quot;Milling.MillTool3.ToolNumber&amp;quot;,               3)&lt;br /&gt;
  Milling.MillTool3.Stepdown                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool3.Stepdown&amp;quot;,              0.2000)&lt;br /&gt;
  Milling.MillTool3.Stepover                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool3.Stepover&amp;quot;,              0.0825)&lt;br /&gt;
  Milling.MillTool3.ToolDia                 = RegistryRead:GetDouble(&amp;quot;Milling.MillTool3.ToolDia&amp;quot;,               0.1250)&lt;br /&gt;
  Milling.MillTool3.PlungeRate              = RegistryRead:GetDouble(&amp;quot;Milling.MillTool3.PlungeRate&amp;quot;,            15.000)&lt;br /&gt;
&lt;br /&gt;
  Milling.MillTool4.FeedRate                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool4.FeedRate&amp;quot;,              30.000)&lt;br /&gt;
  Milling.MillTool4.InMM                    = RegistryRead:GetBool(&amp;quot;Milling.MillTool4.InMM &amp;quot;,                   false)&lt;br /&gt;
  Milling.MillTool4.Name                    = RegistryRead:GetString(&amp;quot;Milling.MillTool4.Name&amp;quot;,                  &amp;quot;No Tool Selected&amp;quot;)&lt;br /&gt;
  Milling.MillTool4.PlungeRate              = RegistryRead:GetDouble(&amp;quot;Milling.MillTool4.PlungeRate&amp;quot;,            15.000)&lt;br /&gt;
  Milling.MillTool4.RateUnits               = RegistryRead:GetInt(&amp;quot;Milling.MillTool4.RateUnits&amp;quot;,                4)&lt;br /&gt;
  Milling.MillTool4.SpindleSpeed            = RegistryRead:GetInt(&amp;quot;Milling.MillTool4.SpindleSpeed&amp;quot;,             20000)&lt;br /&gt;
  Milling.MillTool4.Stepdown                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool4.Stepdown&amp;quot;,              0.2000)&lt;br /&gt;
  Milling.MillTool4.Stepover                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool4.Stepover&amp;quot;,              0.0825)&lt;br /&gt;
  Milling.MillTool4.ToolDia                 = RegistryRead:GetDouble(&amp;quot;Milling.MillTool4.ToolDia&amp;quot;,               0.1250)&lt;br /&gt;
  Milling.MillTool4.ToolNumber              = RegistryRead:GetInt(&amp;quot;Milling.MillTool4.ToolNumber&amp;quot;,               5)&lt;br /&gt;
&lt;br /&gt;
  Milling.MillTool5.FeedRate                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool5.FeedRate&amp;quot;,              30.000)&lt;br /&gt;
  Milling.MillTool5.InMM                    = RegistryRead:GetBool(&amp;quot;Milling.MillTool5.InMM &amp;quot;,                   false)&lt;br /&gt;
  Milling.MillTool5.Name                    = RegistryRead:GetString(&amp;quot;Milling.MillTool5.Name&amp;quot;,                  &amp;quot;No Tool Selected&amp;quot;)&lt;br /&gt;
  Milling.MillTool5.PlungeRate              = RegistryRead:GetDouble(&amp;quot;Milling.MillTool5.PlungeRate&amp;quot;,            15.000)&lt;br /&gt;
  Milling.MillTool5.RateUnits               = RegistryRead:GetInt(&amp;quot;Milling.MillTool5.RateUnits&amp;quot;,                4)&lt;br /&gt;
  Milling.MillTool5.SpindleSpeed            = RegistryRead:GetInt(&amp;quot;Milling.MillTool5.SpindleSpeed&amp;quot;,             20000)&lt;br /&gt;
  Milling.MillTool5.Stepdown                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool5.Stepdown&amp;quot;,              0.2000)&lt;br /&gt;
  Milling.MillTool5.Stepover                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool5.Stepover&amp;quot;,              0.0825)&lt;br /&gt;
  Milling.MillTool5.ToolDia                 = RegistryRead:GetDouble(&amp;quot;Milling.MillTool5.ToolDia&amp;quot;,               0.1250)&lt;br /&gt;
  Milling.MillTool5.ToolNumber              = RegistryRead:GetInt(&amp;quot;Milling.MillTool5.ToolNumber&amp;quot;,               6)&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===RegistryWrite()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function RegistryWrite()                       -- Write to Registry values&lt;br /&gt;
  local RegistryWrite = Registry(&amp;quot;RegName&amp;quot;)&lt;br /&gt;
  local RegValue&lt;br /&gt;
  RegValue = RegistryWrite:SetBool(&amp;quot;ProjectQuestion.CabinetName&amp;quot;, true)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;BaseDim.CabDepth&amp;quot;, 23.0000)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;BaseDim.CabHeight&amp;quot;, 35)&lt;br /&gt;
  RegValue = RegistryWrite:SetString(&amp;quot;BaseDim.CabLength&amp;quot;, &amp;quot;Words&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool1.FeedRate&amp;quot; ,     Milling.MillTool1.FeedRate)&lt;br /&gt;
  RegValue = RegistryWrite:SetBool(&amp;quot;Milling.MillTool1.InMM&amp;quot;,            Milling.MillTool1.InMM)&lt;br /&gt;
  RegValue = RegistryWrite:SetString(&amp;quot;Milling.MillTool1.Name&amp;quot;,          Milling.MillTool1.Name)&lt;br /&gt;
  RegValue = RegistryWrite:SetString(&amp;quot;Milling.MillTool1.BitType&amp;quot;,       Milling.MillTool1.BitType)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool1.PlungeRate&amp;quot; ,   Milling.MillTool1.PlungeRate)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool1.RateUnits&amp;quot;,        Milling.MillTool1.RateUnits)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool1.SpindleSpeed&amp;quot;,     Milling.MillTool1.SpindleSpeed)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool1.Stepdown&amp;quot; ,     Milling.MillTool1.Stepdown)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool1.Stepover&amp;quot; ,     Milling.MillTool1.Stepover)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool1.ToolDia&amp;quot; ,      Milling.MillTool1.ToolDia)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool1.ToolNumber&amp;quot;,       Milling.MillTool1.ToolNumber)&lt;br /&gt;
&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool2.FeedRate&amp;quot; ,     Milling.MillTool2.FeedRate)&lt;br /&gt;
  RegValue = RegistryWrite:SetBool(&amp;quot;Milling.MillTool2.InMM&amp;quot;,            Milling.MillTool2.InMM)&lt;br /&gt;
  RegValue = RegistryWrite:SetString(&amp;quot;Milling.MillTool2.Name&amp;quot;,          Milling.MillTool2.Name)&lt;br /&gt;
  RegValue = RegistryWrite:SetString(&amp;quot;Milling.MillTool2.BitType&amp;quot;,       Milling.MillTool2.BitType)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool2.PlungeRate&amp;quot; ,   Milling.MillTool2.PlungeRate)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool2.RateUnits&amp;quot;,        Milling.MillTool2.RateUnits)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool2.SpindleSpeed&amp;quot;,     Milling.MillTool2.SpindleSpeed)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool2.Stepdown&amp;quot; ,     Milling.MillTool2.Stepdown)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool2.Stepover&amp;quot; ,     Milling.MillTool2.Stepover)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool2.ToolDia&amp;quot; ,      Milling.MillTool2.ToolDia)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool2.ToolNumber&amp;quot;,       Milling.MillTool2.ToolNumber)&lt;br /&gt;
&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool3.FeedRate&amp;quot; ,     Milling.MillTool3.FeedRate)&lt;br /&gt;
  RegValue = RegistryWrite:SetBool(&amp;quot;Milling.MillTool3.InMM&amp;quot;,            Milling.MillTool3.InMM)&lt;br /&gt;
  RegValue = RegistryWrite:SetString(&amp;quot;Milling.MillTool3.Name&amp;quot;,          Milling.MillTool3.Name)&lt;br /&gt;
  RegValue = RegistryWrite:SetString(&amp;quot;Milling.MillTool3.BitType&amp;quot;,       Milling.MillTool3.BitType)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool3.PlungeRate&amp;quot;,    Milling.MillTool3.PlungeRate)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool3.RateUnits&amp;quot;,        Milling.MillTool3.RateUnits)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool3.SpindleSpeed&amp;quot;,     Milling.MillTool3.SpindleSpeed)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool3.Stepdown&amp;quot; ,     Milling.MillTool3.Stepdown)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool3.Stepover&amp;quot; ,     Milling.MillTool3.Stepover)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool3.ToolDia&amp;quot; ,      Milling.MillTool3.ToolDia)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool3.ToolNumber&amp;quot;,       Milling.MillTool3.ToolNumber)&lt;br /&gt;
&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool4.FeedRate&amp;quot; ,     Milling.MillTool4.FeedRate)&lt;br /&gt;
  RegValue = RegistryWrite:SetBool(&amp;quot;Milling.MillTool4.InMM&amp;quot;,            Milling.MillTool4.InMM)&lt;br /&gt;
  RegValue = RegistryWrite:SetString(&amp;quot;Milling.MillTool4.Name&amp;quot;,          Milling.MillTool4.Name)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool4.PlungeRate&amp;quot; ,   Milling.MillTool4.PlungeRate)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool4.RateUnits&amp;quot;,        Milling.MillTool4.RateUnits)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool4.SpindleSpeed&amp;quot;,     Milling.MillTool4.SpindleSpeed)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool4.Stepdown&amp;quot; ,     Milling.MillTool4.Stepdown)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool4.Stepover&amp;quot; ,     Milling.MillTool4.Stepover)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool4.ToolDia&amp;quot; ,      Milling.MillTool4.ToolDia)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool4.ToolNumber&amp;quot;,       Milling.MillTool4.ToolNumber)&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===REG_CheckRegistryBool()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function REG_CheckRegistryBool()               -- Checks Registry for Bool values&lt;br /&gt;
  local RegistryRead = Registry(&amp;quot;RegName&amp;quot;)&lt;br /&gt;
  if RegistryRead:BoolExists(&amp;quot;ProjectQuestion.Runtool&amp;quot;) then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Alert: The Runtool value is saved.&amp;quot;)&lt;br /&gt;
  else&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Alert: The Runtool value is not saved.&amp;quot;)&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===REG_CheckRegistryDouble()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function REG_CheckRegistryDouble()             -- Checks Registry for Double values&lt;br /&gt;
  local RegistryRead = Registry(&amp;quot;RegName&amp;quot;)&lt;br /&gt;
  if RegistryRead:DoubleExists(&amp;quot;ProjectQuestion.ProjectCost&amp;quot;) then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Alert: The project cost is saved.&amp;quot;)&lt;br /&gt;
  else&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Alert: The Project Cost is not saved.&amp;quot;)&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===REG_CheckRegistryInt()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function REG_CheckRegistryInt()                -- Checks Registry for Int values&lt;br /&gt;
  local RegistryRead = Registry(&amp;quot;RegName&amp;quot;)&lt;br /&gt;
  if RegistryRead:IntExists(&amp;quot;ProjectQuestion.ProjectCount&amp;quot;) then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Alert: The Project Count is saved.&amp;quot;)&lt;br /&gt;
  else&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Alert: The Project Count is not saved.&amp;quot;)&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===REG_CheckRegistryString()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function REG_CheckRegistryString()             -- Checks Registry for String values&lt;br /&gt;
  local RegistryRead = Registry(&amp;quot;RegName&amp;quot;)&lt;br /&gt;
  if RegistryRead:StringExists(&amp;quot;ProjectQuestion.ProjectPath&amp;quot;) then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Alert: The Project path is saved.&amp;quot;)&lt;br /&gt;
  else&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Alert: The Project path is not saved.&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==String Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===StringToArraySplit===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function StringToArraySplit(s, delimiter)&lt;br /&gt;
--[[&lt;br /&gt;
split_string = StringToArraySplit(&amp;quot;Hello World,Jim,Bill,Tom&amp;quot;, &amp;quot;,&amp;quot;)&lt;br /&gt;
Returns = array&lt;br /&gt;
-- split_string[1] = &amp;quot;Hello World,)&lt;br /&gt;
-- split_string[2] = &amp;quot;Jim&amp;quot;&lt;br /&gt;
]]&lt;br /&gt;
  result = {};&lt;br /&gt;
  for match in (s..delimiter):gmatch(&amp;quot;(.-)&amp;quot;..delimiter) do&lt;br /&gt;
      table.insert(result, match)&lt;br /&gt;
  end&lt;br /&gt;
  return result&lt;br /&gt;
end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===WrapString===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
function WrapString(Str, Wid)                           -- wraps text at the nearest space and puts a return char in the space location&lt;br /&gt;
  --[[  How to use:&lt;br /&gt;
  Call WrapString(string, Number)&lt;br /&gt;
 WrapString(&amp;quot;Jim is a tall man that lives in Texas. He was raised in North East Texas on 1000 acres from 1970 to 1982. This is a man that knows numbers of great people from a round the world.&amp;quot;, 40)&lt;br /&gt;
 returns &amp;quot;Jim is a tall man that lives in Texas.\n&lt;br /&gt;
          He was raised in North East Texas on\n&lt;br /&gt;
          1000 acres from 1970 to 1982. This is a man\n&lt;br /&gt;
          that knows numbers of great people from\n&lt;br /&gt;
          a round the world.&amp;quot;&lt;br /&gt;
 ]]&lt;br /&gt;
  local Wider = Wid&lt;br /&gt;
  local Posx = string.len(Str)&lt;br /&gt;
  local StrLen = string.len(Str)&lt;br /&gt;
  local pt = 0&lt;br /&gt;
  local function FindSpace(MyStr)&lt;br /&gt;
  local Pos = string.len(MyStr)&lt;br /&gt;
  local str = MyStr&lt;br /&gt;
    if string.find(MyStr, &amp;quot; &amp;quot;) ~= nil then&lt;br /&gt;
      while Pos&amp;gt;0 do&lt;br /&gt;
        Pos = Pos - 1&lt;br /&gt;
          if (string.byte(string.sub(str,-1)) == 32) then&lt;br /&gt;
            break&lt;br /&gt;
          else&lt;br /&gt;
            str = string.sub(str, 1, Pos)&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return Pos&lt;br /&gt;
  end&lt;br /&gt;
  if StrLen &amp;gt; Wider then&lt;br /&gt;
    while Wider &amp;lt; Posx do&lt;br /&gt;
      pt = FindSpace(string.sub(Str,1, Wider))&lt;br /&gt;
      Str = string.sub(Str, 1, pt) .. &amp;quot;\n&amp;quot; ..  string.sub(Str, pt +2)&lt;br /&gt;
      Wider = Wider + Wid&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  return Str&lt;br /&gt;
end -- function end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CleanString===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
function CleanString(inStr)                         -- Check for ascii letters below 127&lt;br /&gt;
  local outStr, str1 = &amp;quot;&amp;quot;&lt;br /&gt;
  local inStrLen = string.len(inStr)&lt;br /&gt;
  for i = 1, inStrLen ,1 do&lt;br /&gt;
    str1 = string.sub(inStr, i, i)&lt;br /&gt;
    if string.byte(str1) &amp;lt;= 127 then&lt;br /&gt;
     outStr=outStr .. str1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  return outStr&lt;br /&gt;
end -- function end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetDiameterAndCentre===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
function CheckString(YourStr)                          -- Check string for specal bite chars for HTML&lt;br /&gt;
  local function FindLetter(TheStr, TestChar)&lt;br /&gt;
    local outStr = false&lt;br /&gt;
    local strChar = &amp;quot;&amp;quot;&lt;br /&gt;
    local TheStrLen = string.len(TheStr)&lt;br /&gt;
    for i = 1, TheStrLen ,1 do&lt;br /&gt;
      strChar = string.sub(TheStr, i, i)&lt;br /&gt;
      if string.byte(strChar) == string.byte(TestChar) then&lt;br /&gt;
        outStr = true&lt;br /&gt;
        break&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    return outStr&lt;br /&gt;
  end -- function end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetDiameterAndCentre===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  local StrTest = false&lt;br /&gt;
  StrTest = SwitchLetter(YourStr,  &amp;quot;&amp;amp;&amp;quot;)  -- Non frendly File Name letters&lt;br /&gt;
  StrTest = SwitchLetter(YourStr,  &amp;quot;#&amp;quot;)&lt;br /&gt;
  StrTest = SwitchLetter(YourStr,  &amp;quot;@&amp;quot;)&lt;br /&gt;
  StrTest = SwitchLetter(YourStr,  &amp;quot;^&amp;quot;)&lt;br /&gt;
  StrTest = SwitchLetter(YourStr,  &amp;quot;$&amp;quot;)&lt;br /&gt;
    return outStr&lt;br /&gt;
end -- function end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===MakeHTMLReady()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
function MakeHTMLReady(MyStr)                          -- fix's string with special bite chars for HTML&lt;br /&gt;
  local function SwitchLetter(MyStr, MyChar, NewStr)&lt;br /&gt;
  local outStr, str1 = &amp;quot;&amp;quot;&lt;br /&gt;
  local inStrLen = string.len(MyStr)&lt;br /&gt;
  for i = 1, inStrLen ,1 do&lt;br /&gt;
    str1 = string.sub(MyStr, i, i)&lt;br /&gt;
    if string.byte(str1) == string.byte(MyChar) then&lt;br /&gt;
     outStr=outStr .. NewStr&lt;br /&gt;
     else&lt;br /&gt;
         outStr=outStr .. str1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  return outStr&lt;br /&gt;
end -- function end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===SwitchLetterTest===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function SwitchLetterTest(MyStr)&lt;br /&gt;
  local outStr = &amp;quot;&amp;quot;&lt;br /&gt;
  outStr = SwitchLetter(MyStr, &amp;quot;!&amp;quot;,	&amp;quot;&amp;amp;#33;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;#&amp;quot;,	&amp;quot;&amp;amp;#35;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;$&amp;quot;,	&amp;quot;&amp;amp;#36;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;%&amp;quot;,	&amp;quot;&amp;amp;#37;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;&amp;amp;&amp;quot;,	&amp;quot;&amp;amp;#38;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;'&amp;quot;,	&amp;quot;&amp;amp;#39;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;(&amp;quot;,	&amp;quot;&amp;amp;#40;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;)&amp;quot;,	&amp;quot;&amp;amp;#41;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;*&amp;quot;,	&amp;quot;&amp;amp;#42;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;+&amp;quot;,	&amp;quot;&amp;amp;#43;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;,&amp;quot;,	&amp;quot;&amp;amp;#44;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;-&amp;quot;,	&amp;quot;&amp;amp;#45;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;.&amp;quot;,	&amp;quot;&amp;amp;#46;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;/&amp;quot;,	&amp;quot;&amp;amp;#47;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;:&amp;quot;,	&amp;quot;&amp;amp;#58;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;;&amp;quot;,	&amp;quot;&amp;amp;#59;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;&amp;lt;&amp;quot;,	&amp;quot;&amp;amp;#60;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;=&amp;quot;,	&amp;quot;&amp;amp;#61;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;&amp;gt;&amp;quot;,	&amp;quot;&amp;amp;#62;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;?&amp;quot;,	&amp;quot;&amp;amp;#63;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;@&amp;quot;,	&amp;quot;&amp;amp;#64;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;[&amp;quot;,	&amp;quot;&amp;amp;#91;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;]&amp;quot;,	&amp;quot;&amp;amp;#93;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;^&amp;quot;,	&amp;quot;&amp;amp;#94;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;_&amp;quot;,	&amp;quot;&amp;amp;#95;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;`&amp;quot;,	&amp;quot;&amp;amp;#96;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;{&amp;quot;,	&amp;quot;&amp;amp;#123&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;|&amp;quot;,	&amp;quot;&amp;amp;#124&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;}&amp;quot;,	&amp;quot;&amp;amp;#125&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;~&amp;quot;,	&amp;quot;&amp;amp;#126&amp;quot;)&lt;br /&gt;
    return outStr&lt;br /&gt;
end -- function end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===SwitchLetter()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function SwitchLetter(MyStr, MyChar, NewStr)            -- swwap a leter for another letter&lt;br /&gt;
  local outStr, str1 = &amp;quot;&amp;quot;&lt;br /&gt;
  local inStrLen = string.len(MyStr)&lt;br /&gt;
  for i = 1, inStrLen ,1 do&lt;br /&gt;
    str1 = string.sub(MyStr, i, i)&lt;br /&gt;
    if string.byte(str1) == string.byte(MyChar) then&lt;br /&gt;
     outStr=outStr .. NewStr&lt;br /&gt;
     else&lt;br /&gt;
         outStr=outStr .. str1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  return outStr&lt;br /&gt;
end -- function end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===PadC===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function PadC(str, lenth)                        -- Adds spaces to front and back to center text in lenth&lt;br /&gt;
-- Local Word = PadC(&amp;quot;K&amp;quot;, 12) -- returns &amp;quot;     K      &amp;quot;&lt;br /&gt;
  if type(str) ~= &amp;quot;string&amp;quot; then&lt;br /&gt;
    str = tostring(str)&lt;br /&gt;
  end&lt;br /&gt;
  if string.len(str) &amp;lt; lenth then&lt;br /&gt;
  local a = math.floor(lenth - string.len(str) * 0.5) - 2&lt;br /&gt;
  local b = math.ceil(lenth - string.len(str) * 0.5) - 2&lt;br /&gt;
  --print (&amp;quot;a = &amp;quot; .. a)&lt;br /&gt;
  for _ = 1, a, 1 do&lt;br /&gt;
    str =  &amp;quot; &amp;quot; .. str&lt;br /&gt;
  end&lt;br /&gt;
  for _ = 1, b, 1 do&lt;br /&gt;
    str =  str .. &amp;quot; &amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  --print (&amp;quot;str len = &amp;quot; .. #str)&lt;br /&gt;
  end&lt;br /&gt;
  return str&lt;br /&gt;
end -- function end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===PadR()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function PadR(str, len)                        -- Adds spaces to Back of string&lt;br /&gt;
-- Local Word = Pad(&amp;quot;KPSDFKSPSK&amp;quot;, 12) -- returns &amp;quot;KPSDFKSPSK  &amp;quot;&lt;br /&gt;
  if type(str) ~= &amp;quot;string&amp;quot; then&lt;br /&gt;
    str = tostring(str)&lt;br /&gt;
  end&lt;br /&gt;
  while string.len(str) &amp;lt; len do&lt;br /&gt;
    str = str .. &amp;quot; &amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  return str&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===PadL()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function PadL(str, len)              -- Adds spaces to Front of string&lt;br /&gt;
-- Local Word = Pad(&amp;quot;KPSDFKSPSK&amp;quot;, 12) -- returns &amp;quot;  KPSDFKSPSK&amp;quot;&lt;br /&gt;
  if type(str) ~= &amp;quot;string&amp;quot; then&lt;br /&gt;
    str = tostring(str)&lt;br /&gt;
  end&lt;br /&gt;
  while string.len(str) &amp;lt; len do&lt;br /&gt;
    str = &amp;quot; &amp;quot; .. str&lt;br /&gt;
  end&lt;br /&gt;
  return str&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===NumberPad()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function NumberPad(str, front, back) -- Adds spaces to front and zeros to the back of string&lt;br /&gt;
  local mychar&lt;br /&gt;
  local  a,b,c,d = 0,0,0,0&lt;br /&gt;
  local x,y,z = &amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;&lt;br /&gt;
  if type(str) ~= &amp;quot;string&amp;quot; then&lt;br /&gt;
    str = tostring(str)&lt;br /&gt;
  end&lt;br /&gt;
  c = string.len(str)&lt;br /&gt;
  for i = 1, c, 1 do&lt;br /&gt;
    mychar = string.byte(string.sub(str, i,i))&lt;br /&gt;
    if mychar == 46 then&lt;br /&gt;
      b = i&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
--  print(&amp;quot;b = &amp;quot; .. b)&lt;br /&gt;
  if b == 0 then&lt;br /&gt;
    str = str .. &amp;quot;.&amp;quot;&lt;br /&gt;
    c = c + 1&lt;br /&gt;
    b = c&lt;br /&gt;
  end -- if loc&lt;br /&gt;
  x = string.sub(str, 1, b-1)&lt;br /&gt;
  y = string.sub(str, b+1)&lt;br /&gt;
  a = c - b&lt;br /&gt;
  a = #x&lt;br /&gt;
  d = #y&lt;br /&gt;
  if a &amp;lt; front then&lt;br /&gt;
    front = front - (a - 1)&lt;br /&gt;
    for _ = 1, front -1 do&lt;br /&gt;
      x = &amp;quot; &amp;quot; .. x&lt;br /&gt;
    end -- end for front&lt;br /&gt;
  end&lt;br /&gt;
  back = back - (c - b)&lt;br /&gt;
  for i = 1, back  do&lt;br /&gt;
    y = y .. &amp;quot;0&amp;quot;&lt;br /&gt;
  end -- end for back&lt;br /&gt;
  str =   x .. &amp;quot;.&amp;quot; .. y&lt;br /&gt;
  return str&lt;br /&gt;
end -- function end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===All_Trim()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function All_Trim(s)                           -- Trims spaces off both ends of a string&lt;br /&gt;
  return s:match( &amp;quot;^%s*(.-)%s*$&amp;quot; )&lt;br /&gt;
end -- function end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===MakeProperCase()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function MakeProperCase(str)&lt;br /&gt;
  local str=string.gsub(string.lower(str),&amp;quot;^(%w)&amp;quot;, string.upper)&lt;br /&gt;
  return string.gsub(str,&amp;quot;([^%w]%w)&amp;quot;, string.upper)&lt;br /&gt;
end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===ifT()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function ifT(x)                                -- Converts Boolean True or False to String &amp;quot;Yes&amp;quot; or &amp;quot;No&amp;quot;&lt;br /&gt;
-- ===ifT(x)===&lt;br /&gt;
  if x then&lt;br /&gt;
    return &amp;quot;Yes&amp;quot;&lt;br /&gt;
  else&lt;br /&gt;
    return &amp;quot;No&amp;quot;&lt;br /&gt;
  end-- if end&lt;br /&gt;
end -- function end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===ifY()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function ifY(x)                                -- Converts String &amp;quot;Yes&amp;quot; or &amp;quot;No&amp;quot; to Boolean True or False&lt;br /&gt;
-- ===ifY(x)===&lt;br /&gt;
  if string.upper(x) == &amp;quot;YES&amp;quot; then&lt;br /&gt;
    return true&lt;br /&gt;
  else&lt;br /&gt;
    return false&lt;br /&gt;
  end-- if end&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Seed Documents== &lt;br /&gt;
[https://jimandi.com/SDK/index.php/JimAndi_Toolbox (top)]&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;-- =====================================================]]&lt;br /&gt;
╔═╗╔═╗╔═╗╔╦╗  ╔═╗╦ ╦╔╗╔╔═╗╔╦╗╦╔═╗╔╗╔&lt;br /&gt;
╚═╗║╣ ║╣  ║║  ╠╣ ║ ║║║║║   ║ ║║ ║║║║&lt;br /&gt;
╚═╝╚═╝╚═╝═╩╝  ╚  ╚═╝╝╚╝╚═╝ ╩ ╩╚═╝╝╚╝&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
  -- VECTRIC LUA SCRIPT&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
-- Gadgets are an entirely optional add-in to Vectric's core software products.&lt;br /&gt;
-- They are provided 'as-is', without any express or implied warranty, and you make use of them entirely at your own risk.&lt;br /&gt;
-- In no event will the author(s) or Vectric Ltd. be held liable for any damages arising from their use.&lt;br /&gt;
-- Permission is granted to anyone to use this software for any purpose,&lt;br /&gt;
-- including commercial applications, and to alter it and redistribute it freely,&lt;br /&gt;
-- subject to the following restrictions:&lt;br /&gt;
-- 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.&lt;br /&gt;
-- 2. If you use this software in a product, an acknowledgement in the product documentation would be appreciated but is not required.&lt;br /&gt;
-- 3. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.&lt;br /&gt;
-- 4. This notice may not be removed or altered from any source distribution.&lt;br /&gt;
-- Easy Seed Gadget Master is written by Jim Anderson of Houston Texas 2020&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
-- require(&amp;quot;mobdebug&amp;quot;).start()&lt;br /&gt;
-- require &amp;quot;strict&amp;quot;&lt;br /&gt;
local Tools&lt;br /&gt;
-- Global Variables --&lt;br /&gt;
local Ver = &amp;quot;1.0&amp;quot;  -- Version 7: Aug 2021 - Clean Up and added Ver to Dialog&lt;br /&gt;
&lt;br /&gt;
-- Table Names&lt;br /&gt;
Milling = {}&lt;br /&gt;
Project = {}&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
function main(script_path)&lt;br /&gt;
--[[&lt;br /&gt;
	Gadget Notes: Dec 2019 - My New Gadget&lt;br /&gt;
&lt;br /&gt;
  ]]&lt;br /&gt;
-- Localized Variables --&lt;br /&gt;
&lt;br /&gt;
-- Job Validation --&lt;br /&gt;
  local job = VectricJob()&lt;br /&gt;
  if not job.Exists then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Error: No job loaded&amp;quot;)&lt;br /&gt;
    return false&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  Tools = assert(loadfile(script_path .. &amp;quot;\\EasyGearToolsVer&amp;quot; .. Ver .. &amp;quot;.xlua&amp;quot;)) (Tools) -- Load Tool Function&lt;br /&gt;
-- Get Data --&lt;br /&gt;
&lt;br /&gt;
-- Calculation --&lt;br /&gt;
&lt;br /&gt;
-- Do Something --&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return true&lt;br /&gt;
end  -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Setup Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;-- =====================================================]]&lt;br /&gt;
╔═╗╔═╗╔╦╗╦ ╦╔═╗&lt;br /&gt;
╚═╗║╣  ║ ║ ║╠═╝&lt;br /&gt;
╚═╝╚═╝ ╩ ╚═╝╩&lt;br /&gt;
function SetupAndLetter Seeds()&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
  function LUA_Seed()&lt;br /&gt;
    -- VECTRIC LUA SCRIPT&lt;br /&gt;
    -- ==============================================================================&lt;br /&gt;
    --  Gadgets are an entirely optional add-in to Vectric's core software products.&lt;br /&gt;
    --  They are provided 'as-is', without any express or implied warranty, and you&lt;br /&gt;
    --  make use of them entirely at your own risk.&lt;br /&gt;
    --  In no event will the author(s) or Vectric Ltd. be held liable for any damages&lt;br /&gt;
    --  arising from their use.&lt;br /&gt;
    --  Permission is granted to anyone to use this software for any purpose,&lt;br /&gt;
    --  including commercial applications, and to alter it and redistribute it freely,&lt;br /&gt;
    --  subject to the following restrictions:&lt;br /&gt;
    --  1. The origin of this software must not be misrepresented;&lt;br /&gt;
    --     you must not claim that you wrote the original software.&lt;br /&gt;
    --     If you use this software in a product, an acknowledgement in the product&lt;br /&gt;
    --     documentation would be appreciated but is not required.&lt;br /&gt;
    --  2. Altered source versions must be plainly marked as such, and&lt;br /&gt;
    --     must not be misrepresented as being the original software.&lt;br /&gt;
    --  3. This notice may not be removed or altered from any source distribution.&lt;br /&gt;
    -- ==============================================================================&lt;br /&gt;
    -- &amp;quot;AppName Here&amp;quot; was written by JimAndi Gadgets of Houston Texas&lt;br /&gt;
    -- ==============================================================================&lt;br /&gt;
    -- =====================================================]]&lt;br /&gt;
    -- require(&amp;quot;mobdebug&amp;quot;).start()&lt;br /&gt;
    -- require &amp;quot;strict&amp;quot;&lt;br /&gt;
    -- =====================================================]]&lt;br /&gt;
    -- Global variables&lt;br /&gt;
    -- =====================================================]]&lt;br /&gt;
  end -- lua function&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
  function Install_letter()&lt;br /&gt;
  -- Steps to Install:&lt;br /&gt;
&lt;br /&gt;
  -- 1. Download the gadget x.zip that is attached to this post.&lt;br /&gt;
  -- 2. Rename it from x.zip to x.vgadget&lt;br /&gt;
  -- 3. In Vectric Pro or Aspire click on Gadgets -&amp;gt; Install Gadget and navigate to where you downloaded the file to, select it and click Ok.&lt;br /&gt;
&lt;br /&gt;
  -- It should give you a pop up saying the gadget was installed and you should see x in the Gadgets menu.&lt;br /&gt;
&lt;br /&gt;
  -- Image Here&lt;br /&gt;
&lt;br /&gt;
  -- Steps for Use:&lt;br /&gt;
  -- 1. Select a layer that you want to calculate for&lt;br /&gt;
  -- 2. Enter the cut depth&lt;br /&gt;
  -- 3. Enter the percentage of coverage for the area that will be filled in&lt;br /&gt;
  -- 4. Enter the hardner to resin percentage&lt;br /&gt;
  -- 5. Click the Calculate Button and the results will be displayed below in the Results Pane.&lt;br /&gt;
  end -- install function&lt;br /&gt;
&lt;br /&gt;
end -- Header function&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Toolpathing Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CreateLayerProfileToolpath===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function CreateLayerProfileToolpath(name, layer_name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
    -- clear current selection&lt;br /&gt;
    local selection = job.Selection&lt;br /&gt;
    selection:Clear()&lt;br /&gt;
    -- get layer&lt;br /&gt;
    local layer = job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;No layer found with name = &amp;quot; .. layer_name)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;No closed vectors found on layer &amp;quot; .. layer_name)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua End Mill&amp;quot;, Tool.END_MILL) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * 0.25&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC ...&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local profile_data = ProfileParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    profile_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    profile_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut - ProfileParameterData.&lt;br /&gt;
    -- CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION&lt;br /&gt;
    profile_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- side we machine on - ProfileParameterData.&lt;br /&gt;
    -- PROFILE_OUTSIDE, ProfileParameterData.PROFILE_INSIDE or&lt;br /&gt;
    -- ProfileParameterData.PROFILE_ON&lt;br /&gt;
    profile_data.ProfileSide = ProfileParameterData.PROFILE_OUTSIDE&lt;br /&gt;
    -- Allowance to leave on when machining&lt;br /&gt;
    profile_data.Allowance = 0.0&lt;br /&gt;
    -- true to preserve start point positions, false to reorder start&lt;br /&gt;
    -- points to minimise toolpath length&lt;br /&gt;
    profile_data.KeepStartPoints = false&lt;br /&gt;
    -- true if want to create 'square' external corners on toolpath&lt;br /&gt;
    profile_data.CreateSquareCorners = false&lt;br /&gt;
    -- true to perform corner sharpening on internal corners (only with v-bits)&lt;br /&gt;
    profile_data.CornerSharpen = false&lt;br /&gt;
    -- true to use tabs (position of tabs must already have been defined on vectors)&lt;br /&gt;
    profile_data.UseTabs = false&lt;br /&gt;
    -- length for tabs if being used&lt;br /&gt;
    profile_data.TabLength = 5.0&lt;br /&gt;
    -- Thickness for tabs if being used&lt;br /&gt;
    profile_data.TabThickness = 1.0&lt;br /&gt;
    -- if true then create 3d tabs else 2d tabs&lt;br /&gt;
    profile_data.Use3dTabs = true&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    profile_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object used to control ramping&lt;br /&gt;
    local ramping_data = RampingData()&lt;br /&gt;
    -- if true we do ramping into toolpath&lt;br /&gt;
    ramping_data.DoRamping = false&lt;br /&gt;
    -- type of ramping to perform RampingData.RAMP_LINEAR , RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
    -- or RampingData.RAMP_SPIRAL&lt;br /&gt;
    ramping_data.RampType = RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
    -- how ramp is contrained - either by angle or distance RampingData.CONSTRAIN_DISTANCE&lt;br /&gt;
    -- or RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
    ramping_data.RampConstraint = RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
    -- if we are constraining ramp by distance, distance to ramp over&lt;br /&gt;
    ramping_data.RampDistance = 100.0&lt;br /&gt;
    -- if we are contraining ramp by angle , angle to ramp in at (in degrees)&lt;br /&gt;
    ramping_data.RampAngle = 25.0&lt;br /&gt;
    -- if we are contraining ramp by angle, max distance to travel before 'zig zaging'&lt;br /&gt;
    -- if zig zaging&lt;br /&gt;
    ramping_data.RampMaxAngleDist = 15&lt;br /&gt;
    -- if true we restrict our ramping to lead in section of toolpath&lt;br /&gt;
    ramping_data.RampOnLeadIn = false&lt;br /&gt;
    -- Create object used to control lead in/out&lt;br /&gt;
    local lead_in_out_data = LeadInOutData()&lt;br /&gt;
    -- if true we create lead ins on profiles (not for profile on)&lt;br /&gt;
    lead_in_out_data.DoLeadIn = false&lt;br /&gt;
    -- if true we create lead outs on profiles (not for profile on)&lt;br /&gt;
    lead_in_out_data.DoLeadOut = false&lt;br /&gt;
    -- type of leads to create LeadInOutData.LINEAR_LEAD or LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
    lead_in_out_data.LeadType = LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
    -- length of lead to create&lt;br /&gt;
    lead_in_out_data.LeadLength = 10.0&lt;br /&gt;
    -- Angle for linear leads&lt;br /&gt;
    lead_in_out_data.LinearLeadAngle = 45&lt;br /&gt;
    -- Radius for circular arc leads&lt;br /&gt;
    lead_in_out_data.CirularLeadRadius = 5.0&lt;br /&gt;
    -- distance to 'overcut' (travel past start point) when profiling&lt;br /&gt;
    lead_in_out_data.OvercutDistance = 0.0&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateProfilingToolpath(name, tool, profile_data, ramping_data, lead_in_out_data, pos_data, geometry_selector, create_2d_previews, display_warnings )&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CreateProfileToolpath===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function CreateProfileToolpath(name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua End Mill&amp;quot;, Tool.END_MILL) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * 0.25&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC ...&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local profile_data = ProfileParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    profile_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    profile_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut - ProfileParameterData.&lt;br /&gt;
    -- CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION&lt;br /&gt;
    profile_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- side we machine on - ProfileParameterData.&lt;br /&gt;
    -- PROFILE_OUTSIDE, ProfileParameterData.PROFILE_INSIDE or&lt;br /&gt;
    -- ProfileParameterData.PROFILE_ON&lt;br /&gt;
    profile_data.ProfileSide = ProfileParameterData.PROFILE_OUTSIDE&lt;br /&gt;
    -- Allowance to leave on when machining&lt;br /&gt;
    profile_data.Allowance = 0.0&lt;br /&gt;
    -- true to preserve start point positions, false to reorder start&lt;br /&gt;
    -- points to minimise toolpath length&lt;br /&gt;
    profile_data.KeepStartPoints = false&lt;br /&gt;
    -- true if want to create 'square' external corners on toolpath&lt;br /&gt;
    profile_data.CreateSquareCorners = false&lt;br /&gt;
    -- true to perform corner sharpening on internal corners (only with v-bits)&lt;br /&gt;
    profile_data.CornerSharpen = false&lt;br /&gt;
    -- true to use tabs (position of tabs must already have been defined on vectors)&lt;br /&gt;
    profile_data.UseTabs = false&lt;br /&gt;
    -- length for tabs if being used&lt;br /&gt;
    profile_data.TabLength = 5.0&lt;br /&gt;
    -- Thickness for tabs if being used&lt;br /&gt;
    profile_data.TabThickness = 1.0&lt;br /&gt;
    -- if true then create 3d tabs else 2d tabs&lt;br /&gt;
    profile_data.Use3dTabs = true&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    profile_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object used to control ramping&lt;br /&gt;
    local ramping_data = RampingData()&lt;br /&gt;
    -- if true we do ramping into toolpath&lt;br /&gt;
    ramping_data.DoRamping = false&lt;br /&gt;
    -- type of ramping to perform RampingData.RAMP_LINEAR , RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
    -- or RampingData.RAMP_SPIRAL&lt;br /&gt;
    ramping_data.RampType = RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
    -- how ramp is contrained - either by angle or distance RampingData.CONSTRAIN_DISTANCE&lt;br /&gt;
    -- or RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
    ramping_data.RampConstraint = RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
    -- if we are constraining ramp by distance, distance to ramp over&lt;br /&gt;
    ramping_data.RampDistance = 100.0&lt;br /&gt;
    -- if we are contraining ramp by angle , angle to ramp in at (in degrees)&lt;br /&gt;
    ramping_data.RampAngle = 25.0&lt;br /&gt;
    -- if we are contraining ramp by angle, max distance to travel before 'zig zaging'&lt;br /&gt;
    -- if zig zaging&lt;br /&gt;
    ramping_data.RampMaxAngleDist = 15&lt;br /&gt;
    -- if true we restrict our ramping to lead in section of toolpath&lt;br /&gt;
    ramping_data.RampOnLeadIn = false&lt;br /&gt;
    -- Create object used to control lead in/out&lt;br /&gt;
    local lead_in_out_data = LeadInOutData()&lt;br /&gt;
    -- if true we create lead ins on profiles (not for profile on)&lt;br /&gt;
    lead_in_out_data.DoLeadIn = false&lt;br /&gt;
    -- if true we create lead outs on profiles (not for profile on)&lt;br /&gt;
    lead_in_out_data.DoLeadOut = false&lt;br /&gt;
    -- type of leads to create LeadInOutData.LINEAR_LEAD or LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
    lead_in_out_data.LeadType = LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
    -- length of lead to create&lt;br /&gt;
    lead_in_out_data.LeadLength = 10.0&lt;br /&gt;
    -- Angle for linear leads&lt;br /&gt;
    lead_in_out_data.LinearLeadAngle = 45&lt;br /&gt;
    -- Radius for circular arc leads&lt;br /&gt;
    lead_in_out_data.CirularLeadRadius = 5.0&lt;br /&gt;
    -- distance to 'overcut' (travel past start point) when profiling&lt;br /&gt;
    lead_in_out_data.OvercutDistance = 0.0&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateProfilingToolpath(name, tool, profile_data, ramping_data, lead_in_out_data, pos_data, geometry_selector, create_2d_previews, display_warnings )&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CreatePocketingToolpath===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function CreatePocketingToolpath(name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
  -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua End Mill&amp;quot;,Tool.END_MILL) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * (tool_stepover_percent / 100)&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC,...&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * (tool_stepover_percent / 100) -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass pocketing options&lt;br /&gt;
    local pocket_data = PocketParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    pocket_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    pocket_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION or&lt;br /&gt;
    -- ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
    pocket_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- Allowance to leave on when machining&lt;br /&gt;
    pocket_data.Allowance = 0.0&lt;br /&gt;
    -- if true use raster clearance strategy , else use offset area clearance&lt;br /&gt;
    pocket_data.DoRasterClearance = true&lt;br /&gt;
    -- angle for raster if using raster clearance&lt;br /&gt;
    pocket_data.RasterAngle = 0&lt;br /&gt;
    -- type of profile pass to perform PocketParameterData.PROFILE_NONE ,&lt;br /&gt;
    -- PocketParameterData.PROFILE_FIRST orPocketParameterData.PROFILE_LAST&lt;br /&gt;
    pocket_data.ProfilePassType = PocketParameterData.PROFILE_LAST&lt;br /&gt;
    -- if true we ramp into pockets (always zig-zag)&lt;br /&gt;
    pocket_data.DoRamping = false&lt;br /&gt;
    -- if ramping, distance to ramp over&lt;br /&gt;
    pocket_data.RampDistance = 10.0&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    pocket_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- if we are doing two tool pocketing define tool to use for area clearance&lt;br /&gt;
    local area_clear_tool = nill&lt;br /&gt;
    -- we just create a tool twice as large for testing here&lt;br /&gt;
    area_clear_tool = Tool(&amp;quot;Lua Clearance End Mill&amp;quot;, Tool.END_MILL) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    area_clear_tool.InMM = tool_in_mm&lt;br /&gt;
    area_clear_tool.ToolDia = tool_dia * 2&lt;br /&gt;
    area_clear_tool.Stepdown = tool_stepdown * 2&lt;br /&gt;
    area_clear_tool.Stepover = tool_dia * 2 *(tool_stepover_percent / 100)&lt;br /&gt;
    area_clear_tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC..&lt;br /&gt;
    area_clear_tool.FeedRate = 30&lt;br /&gt;
    area_clear_tool.PlungeRate = 10&lt;br /&gt;
    area_clear_tool.SpindleSpeed = 20000&lt;br /&gt;
    area_clear_tool.ToolNumber = 1&lt;br /&gt;
    area_clear_tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    area_clear_tool.ClearStepover = tool_dia*2*(tool_stepover_percent/100) -- used for vbit&lt;br /&gt;
  -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePocketingToolpath(name,tool,area_clear_tool,pocket_data,pos_data,geometry_selector,create_2d_previews,display_warnings)&lt;br /&gt;
    if toolpath_id == nill then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CreateDrillingToolpath===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function CreateDrillingToolpath(name, start_depth, cut_depth, retract_gap, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
  -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua Drill&amp;quot;, Tool.THROUGH_DRILL) -- BALL_NOSE, END_MILL, VBIT, THROUGH_DRILL&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * 0.25&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local drill_data = DrillParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    drill_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    drill_data.CutDepth = cut_depth&lt;br /&gt;
    -- if true perform peck drilling&lt;br /&gt;
    drill_data.DoPeckDrill = retract_gap &amp;gt; 0.0&lt;br /&gt;
    -- distance to retract above surface when peck drilling&lt;br /&gt;
    drill_data.PeckRetractGap = retract_gap&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    drill_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view,&lt;br /&gt;
    -- if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateDrillingToolpath(name,tool,drill_data,pos_data,geometry_selector,create_2d_previews,display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CreateVCarvingToolpath===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function CreateVCarvingToolpath(name, start_depth, flat_depth, vbit_angle, vbit_dia, vbit_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
    --[[ -------------- CreateVCarvingToolpath --------------&lt;br /&gt;
    |&lt;br /&gt;
    | Create a VCarving toolpath within the program for the currently selected vectors&lt;br /&gt;
    | Parameters:&lt;br /&gt;
    | name, -- Name for toolpath&lt;br /&gt;
    | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
    | flat_depth -- flat depth - if 0.0 assume not doing flat bottom&lt;br /&gt;
    | vbit_angle -- angle of vbit to use&lt;br /&gt;
    | vbit_dia -- diameter of VBit to use&lt;br /&gt;
    | vbit_stepdown -- stepdown for tool&lt;br /&gt;
    | tool_stepover_percent - percentage stepover for tool&lt;br /&gt;
    | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
    |&lt;br /&gt;
    | Return Values:&lt;br /&gt;
    | true if toolpath created OK else false&lt;br /&gt;
    |&lt;br /&gt;
  ]]&lt;br /&gt;
  -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua VBit&amp;quot;,Tool.VBIT )-- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = vbit_dia&lt;br /&gt;
    tool.Stepdown = vbit_stepdown&lt;br /&gt;
    tool.Stepover = vbit_dia * (tool_stepover_percent / 100)&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = vbit_dia * (tool_stepover_percent / 100) * 2 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()    &lt;br /&gt;
    vcarve_data:SetHomePosition(Milling.HomeX, Milling.HomeY, Milling.HomeZGap ) -- vcarve_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    vcarve_data.SafeZGap = Milling.SafeZGap -- vcarve_data.SafeZGap = 0.5&lt;br /&gt;
    local vcarve_data = VCarveParameterData() -- Create object used to pass pocketing options - used for area clearance only&lt;br /&gt;
    vcarve_data.StartDepth = start_depth    -- start depth for toolpath&lt;br /&gt;
    vcarve_data.DoFlatBottom = flat_depth &amp;gt; 0.0    -- flag indicating if we are creating a flat bottomed toolpath&lt;br /&gt;
    vcarve_data.FlatDepth = flat_depth    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    vcarve_data.ProjectToolpath = false    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    vcarve_data.UseAreaClearTool = true    -- set flag indicating we are using flat tool&lt;br /&gt;
    local pocket_data = PocketParameterData()    -- Create object used to pass pocketing options - used for area clearance only&lt;br /&gt;
    pocket_data.StartDepth = start_depth    -- start depth for toolpath&lt;br /&gt;
    pocket_data.CutDepth = flat_depth    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    pocket_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION    -- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
&lt;br /&gt;
    -- if true use raster clearance strategy , else use offset area clearance&lt;br /&gt;
    pocket_data.DoRasterClearance = false&lt;br /&gt;
    -- set flag indicating we are using flat tool&lt;br /&gt;
    pocket_data.UseAreaClearTool = true&lt;br /&gt;
    -- angle for raster if using raster clearance&lt;br /&gt;
    pocket_data.RasterAngle = 0&lt;br /&gt;
    -- type of profile pass to perform PocketParameterData.PROFILE_NONE ,&lt;br /&gt;
    -- PocketParameterData.PROFILE_FIRST orPocketParameterData.PROFILE_LAST&lt;br /&gt;
    pocket_data.ProfilePassType = PocketParameterData.PROFILE_LAST&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- if we are doing two tool pocketing define tool to use for area clearance&lt;br /&gt;
    local area_clear_tool = nil&lt;br /&gt;
    -- we just create a 10mm end mill&lt;br /&gt;
    area_clear_tool = Tool(&amp;quot;Lua Clearance End Mill&amp;quot;,Tool.END_MILL) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    area_clear_tool.InMM = true&lt;br /&gt;
    area_clear_tool.ToolDia = 10&lt;br /&gt;
    area_clear_tool.Stepdown = 3&lt;br /&gt;
    area_clear_tool.Stepover = 3&lt;br /&gt;
    area_clear_tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    area_clear_tool.FeedRate = 30&lt;br /&gt;
    area_clear_tool.PlungeRate = 10&lt;br /&gt;
    area_clear_tool.SpindleSpeed = 20000&lt;br /&gt;
    area_clear_tool.ToolNumber = 2&lt;br /&gt;
    local geometry_selector = GeometrySelector()    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateVCarvingToolpath(name,tool, area_clear_tool,vcarve_data, pocket_data,pos_data,geometry_selector, create_2d_previews,display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CreatePrismToolpath===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function CreatePrismToolpath(name, start_depth, cut_depth, vbit_angle, vbit_dia, vbit_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
  --[[ ------------------- CreatePrismToolpath -------------------&lt;br /&gt;
  |&lt;br /&gt;
  | Create a prism toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
  | vbit_angle -- angle of vbit to use&lt;br /&gt;
  | vbit_dia -- diameter of VBit to use&lt;br /&gt;
  | vbit_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_stepover_percent - percentage stepover for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua VBit&amp;quot;, Tool.VBIT ) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = vbit_dia&lt;br /&gt;
    tool.Stepdown = vbit_stepdown&lt;br /&gt;
    tool.Stepover = vbit_dia * (tool_stepover_percent / 100)&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = vbit_dia * (tool_stepover_percent / 100) * 2 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local prism_data = PrismCarveParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    prism_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    prism_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- or ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
    prism_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- calculate the minimum cut depth to fully form the bevel on the current&lt;br /&gt;
    -- selection with the current tool&lt;br /&gt;
    local min_bevel_depth = prism_data:CalculateMinimumBevelDepth(tool, true)&lt;br /&gt;
    if min_bevel_depth &amp;gt; cut_depth then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;A prism will not be fully formed with a depth of &amp;quot; .. cut_depth .. &amp;quot;\r\n&amp;quot; ..&lt;br /&gt;
                        &amp;quot;A depth of &amp;quot; .. min_bevel_depth .. &amp;quot; is required to fully form the prism&amp;quot;)&lt;br /&gt;
    end -- if end&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePrismCarvingToolpath(name, tool, prism_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CreateFlutingToolpath===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function CreateFlutingToolpath(name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
    --[[ ----------------- CreateFlutingToolpath -----------------&lt;br /&gt;
  | Create a flutting toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for toolpath&lt;br /&gt;
  | tool_dia -- diameter of tool to use&lt;br /&gt;
  | tool_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua Ball Nose&amp;quot;, Tool.BALL_NOSE) -- BALL_NOSE, END_MILL, VBIT, THROUGH_DRILL&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * 0.25&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass fluting options&lt;br /&gt;
    local fluting_data = FlutingParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    fluting_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    fluting_data.CutDepth = cut_depth&lt;br /&gt;
    -- type of fluting FULL_LENGTH, RAMP_START or RAMP_START_END&lt;br /&gt;
    fluting_data.FluteType = FlutingParameterData.RAMP_START_END&lt;br /&gt;
    -- type of ramping RAMP_LINEAR, RAMP_SMOOTH&lt;br /&gt;
    fluting_data.RampType = FlutingParameterData.RAMP_LINEAR&lt;br /&gt;
    -- if true use ratio field for controling ramp length else absolute length value&lt;br /&gt;
    fluting_data.UseRampRatio = false&lt;br /&gt;
    -- length of ramp as ratio of flute length(range 0 - 1.0)&lt;br /&gt;
    -- (for start and end - ratio is of half length)&lt;br /&gt;
    fluting_data.RampRatio = 0.2&lt;br /&gt;
    -- length to ramp over - if UseRampRatio == false&lt;br /&gt;
    fluting_data.RampLength = 15&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    fluting_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateFlutingToolpath(name, tool, fluting_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    else&lt;br /&gt;
      return true&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===SelectVectorsOnLayer===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function SelectVectorsOnLayer(layer, selection, select_closed, select_open, select_groups)&lt;br /&gt;
    -- Please Note: SelectVectorsOnLayer is provided by Vectric and can be found in the SDK and Sample Gadget files.&lt;br /&gt;
    --[[  ---------------- SelectVectorsOnLayer ----------------&lt;br /&gt;
    -- |   SelectVectorsOnLayer(&amp;quot;Stringer Profile&amp;quot;, selection, true, falus, falus)&lt;br /&gt;
    -- |   Add all the vectors on the layer to the selection&lt;br /&gt;
    -- |     layer,            -- layer we are selecting vectors on&lt;br /&gt;
    -- |     selection         -- selection object&lt;br /&gt;
    -- |     select_closed     -- if true  select closed objects&lt;br /&gt;
    -- |     select_open       -- if true  select open objects&lt;br /&gt;
    -- |     select_groups     -- if true select grouped vectors (irrespective of open / closed state of member objects)&lt;br /&gt;
    -- |  Return Values:&lt;br /&gt;
    -- |     true if selected one or more vectors|&lt;br /&gt;
    --]]&lt;br /&gt;
    local objects_selected = false&lt;br /&gt;
    local warning_displayed = false&lt;br /&gt;
    local pos = layer:GetHeadPosition()&lt;br /&gt;
    while pos ~= nil do&lt;br /&gt;
      local object&lt;br /&gt;
      object, pos = layer:GetNext(pos)&lt;br /&gt;
      local contour = object:GetContour()&lt;br /&gt;
      if contour == nil then&lt;br /&gt;
        if (object.ClassName == &amp;quot;vcCadObjectGroup&amp;quot;) and select_groups then&lt;br /&gt;
          selection:Add(object, true, true)&lt;br /&gt;
          objects_selected = true&lt;br /&gt;
        else&lt;br /&gt;
          if not warning_displayed then&lt;br /&gt;
            local message = &amp;quot;Object(s) without contour information found on layer - ignoring&amp;quot;&lt;br /&gt;
            if not select_groups then&lt;br /&gt;
              message = message ..  &amp;quot;\r\n\r\n&amp;quot; ..&lt;br /&gt;
              &amp;quot;If layer contains grouped vectors these must be ungrouped for this script&amp;quot;&lt;br /&gt;
            end -- if end&lt;br /&gt;
            DisplayMessageBox(message)&lt;br /&gt;
            warning_displayed = true&lt;br /&gt;
          end -- if end&lt;br /&gt;
        end -- if end&lt;br /&gt;
      else  -- contour was NOT nil, test if Open or Closed&lt;br /&gt;
        if contour.IsOpen and select_open then&lt;br /&gt;
          selection:Add(object, true, true)&lt;br /&gt;
          objects_selected = true&lt;br /&gt;
        elseif select_closed then&lt;br /&gt;
          selection:Add(object, true, true)&lt;br /&gt;
          objects_selected = true&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- if end&lt;br /&gt;
    end -- while end&lt;br /&gt;
    -- to avoid excessive redrawing etc we added vectors to the selection in 'batch' mode&lt;br /&gt;
    -- tell selection we have now finished updating&lt;br /&gt;
    if objects_selected then&lt;br /&gt;
      selection:GroupSelectionFinished()&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return objects_selected&lt;br /&gt;
  end -- function end&lt;br /&gt;
&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 10.0, published August 21, 2019. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=JimAndi_Toolbox&amp;diff=1096</id>
		<title>JimAndi Toolbox</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=JimAndi_Toolbox&amp;diff=1096"/>
		<updated>2024-11-16T17:20:00Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: /* CreatePrismToolpath */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:SDK]]&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
==Table and Array Tools==&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
&lt;br /&gt;
===ArrayClear===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
ArrayClear - Clears the data from a data array.&lt;br /&gt;
&lt;br /&gt;
local tbl = {1, 2, 5, 6}&lt;br /&gt;
&lt;br /&gt;
tbl = ArrayClear(tbl)&lt;br /&gt;
&lt;br /&gt;
returns tbl = {}&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function ArrayClear(arrayName)&lt;br /&gt;
   for _,v in ipairs(arrayName) do&lt;br /&gt;
     table.remove(arrayName, i)&lt;br /&gt;
   end -- for end&lt;br /&gt;
   return true&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===NameCheck===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Checks if Name is in the list of it is default name.&lt;br /&gt;
&lt;br /&gt;
a = {1, 2, 5, 6}&lt;br /&gt;
&lt;br /&gt;
Words = NameCheck(a, 5) -- returns true&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function NameCheck(Name, Defalt, ListName)&lt;br /&gt;
     if Name ~= Defalt then&lt;br /&gt;
       for i=1, ListName do&lt;br /&gt;
         if Name == i then&lt;br /&gt;
           return true&lt;br /&gt;
         end&lt;br /&gt;
       end&lt;br /&gt;
       return false&lt;br /&gt;
     else&lt;br /&gt;
       return  true&lt;br /&gt;
     end&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===RemoveDuplicates===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns table of unique items in &amp;quot;A&amp;quot; acending or &amp;quot;D&amp;quot; decending&lt;br /&gt;
&lt;br /&gt;
local tbl = {1, 2, 5, 3, 5, 6, 4}&lt;br /&gt;
&lt;br /&gt;
tbl = ArrayClear(tbl, &amp;quot;A&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
 returns tbl = {1, 2, 3, 4, 5, 6}&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function RemoveDuplicates(tab, order)&lt;br /&gt;
     local hashSet = {}&lt;br /&gt;
     local new = {}&lt;br /&gt;
     local value&lt;br /&gt;
     for i = 1, #tab do&lt;br /&gt;
       value = (tab[i])&lt;br /&gt;
       if hashSet[value] == nil then&lt;br /&gt;
         table.insert(new, value)&lt;br /&gt;
         hashSet[value] = true&lt;br /&gt;
       end&lt;br /&gt;
     end&lt;br /&gt;
     if string.upper(order) ==&amp;quot;A&amp;quot; then&lt;br /&gt;
       table.sort(new)&lt;br /&gt;
     else&lt;br /&gt;
       table.sort(new, function(a, b) return a &amp;gt; b end)&lt;br /&gt;
     end&lt;br /&gt;
     return new&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===RemoveTableItem=== &lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns table with item removed.&lt;br /&gt;
&lt;br /&gt;
local tbl = {1, 2, 3, 4, 5, 6}&lt;br /&gt;
&lt;br /&gt;
tbl = RemoveTableItem(tbl, 4)&lt;br /&gt;
&lt;br /&gt;
 returns tbl = {1, 2, 3, 5, 6}&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;  function RemoveTableItem(tabName, tabItem)&lt;br /&gt;
     for x = 1 in ipairs(tabName) do&lt;br /&gt;
       if tabName[x] == tabItem then&lt;br /&gt;
          table.remove(tabName, i)&lt;br /&gt;
       end&lt;br /&gt;
     end -- for end&lt;br /&gt;
     return true&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===TableLength===&lt;br /&gt;
&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; Returns table item count&lt;br /&gt;
 local tbl = {1, 2, 3, 4, 5, 6}&lt;br /&gt;
 tbl = TableLength(tbl)&lt;br /&gt;
&lt;br /&gt;
 returns tbl = 6&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
  function TableLength(tbl)&lt;br /&gt;
     -- tbl = {7, 6, 5, 4, 3, 2, 1}&lt;br /&gt;
     local count = 0&lt;br /&gt;
     for _ in pairs(tbl) do&lt;br /&gt;
       count = count + 1&lt;br /&gt;
     end&lt;br /&gt;
     return count&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===FindDups===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Find all duplicate items and returns two tables the dup and clean tables&lt;br /&gt;
&lt;br /&gt;
Returns table item count&lt;br /&gt;
&lt;br /&gt;
local tbl = {1, 2, 2, 4, 4, 6}&lt;br /&gt;
&lt;br /&gt;
local tbl1 = {}&lt;br /&gt;
&lt;br /&gt;
local tbl2 = {}&lt;br /&gt;
&lt;br /&gt;
tbl1, tbl2 = TableLength(tbl)&lt;br /&gt;
&lt;br /&gt;
returns tbl1, tbl2 = 6&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function FindDups(checktbl, duptbl, cleantbl)&lt;br /&gt;
     function tLength(tbl) -- tLength returns table count&lt;br /&gt;
       local count = 0&lt;br /&gt;
       for _ in pairs(tbl) do&lt;br /&gt;
         count = count + 1&lt;br /&gt;
       end&lt;br /&gt;
       return count&lt;br /&gt;
     end&lt;br /&gt;
     -- =================================&lt;br /&gt;
     local trip = false&lt;br /&gt;
     for i=1, tLength(checktbl) do&lt;br /&gt;
       for x=1, tLength(cleantbl) do&lt;br /&gt;
         if cleantbl[x] == checktbl[i] then&lt;br /&gt;
           trip = true&lt;br /&gt;
         end&lt;br /&gt;
       end&lt;br /&gt;
       if trip then&lt;br /&gt;
         table.insert(duptbl,   checktbl[i])&lt;br /&gt;
       else&lt;br /&gt;
         table.insert(cleantbl, checktbl[i])&lt;br /&gt;
       end&lt;br /&gt;
       trip = false&lt;br /&gt;
     end&lt;br /&gt;
     return table.sort(duptbl), table.sort(cleantbl)&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===ReverseTable===&lt;br /&gt;
&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
&lt;br /&gt;
Returns a reversed table&lt;br /&gt;
&lt;br /&gt;
local tbl = {1, 2, 3, 4, 5, 6}&lt;br /&gt;
&lt;br /&gt;
tbl = ReverseTable(tbl)&lt;br /&gt;
&lt;br /&gt;
returns tbl = {6, 5, 4, 3, 2, 1}&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function ReverseTable(tbl)&lt;br /&gt;
    --tbl = {7, 6, 7, A, 5, 4, 3, A, 2, 1}&lt;br /&gt;
     local n = #tbl&lt;br /&gt;
     local i = 1&lt;br /&gt;
     while i &amp;lt; n do&lt;br /&gt;
       tbl[i],tbl[n] = tbl[n],tbl[i]&lt;br /&gt;
       i = i + 1&lt;br /&gt;
       n = n - 1&lt;br /&gt;
     end&lt;br /&gt;
     return tbl&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Conversion Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This collection of functions that assist in the conversion activities.&lt;br /&gt;
&lt;br /&gt;
===Bool2Str===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
&amp;lt;nowiki&amp;gt; bool2Str - Converts true or false as a string.&lt;br /&gt;
 local x = true &lt;br /&gt;
 tbl = bool2Str(x)&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
 returns &amp;quot;true&amp;quot;&lt;br /&gt;
  function Bool2Str(x)&lt;br /&gt;
    if x then&lt;br /&gt;
      return &amp;quot;true&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      return &amp;quot;false&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  end --function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===D2S8===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
  D2S8 - Converts a Number (Double) to a String with 8 places&lt;br /&gt;
 &lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function D2S8(d)                               -- Converts a Number (Double) to a String with 8 places&lt;br /&gt;
-- local x =12.2351&lt;br /&gt;
-- returns &amp;quot;12.23510000&amp;quot;&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
    return string.format(&amp;quot;%.8f&amp;quot;, d)&lt;br /&gt;
  end -- end function &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===D2S4===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; D2S4 - Converts a Number (Double) to a String with 4 places&lt;br /&gt;
 local x =12.23&lt;br /&gt;
  = D2S4(x)&lt;br /&gt;
&lt;br /&gt;
 returns x = &amp;quot;12.2300&amp;quot;&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
  function D2S4(d) &lt;br /&gt;
    return string.format(&amp;quot;%.4f&amp;quot;, d)&lt;br /&gt;
  end -- end function &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Toint===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; Toint - Converts a Double Number to a intiger&lt;br /&gt;
 local x = 12.23&lt;br /&gt;
  = toint(x)&lt;br /&gt;
&lt;br /&gt;
 returns x = 12&lt;br /&gt;
  function toint(number)&lt;br /&gt;
    return math.floor(tonumber(number) or error(&amp;quot;Could not cast '&amp;quot; .. tostring(number) .. &amp;quot;' to number.'&amp;quot;))&lt;br /&gt;
  end -- end function &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Rounder===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
&lt;br /&gt;
  return tonumber(string.format(&amp;quot;%.&amp;quot; .. (idp or 0) .. &amp;quot;f&amp;quot;, n&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
function Rounder(num, idp)                              --  Rounds a Number (Double) up or down&lt;br /&gt;
  return tonumber(string.format(&amp;quot;%.&amp;quot; .. (idp or 0) .. &amp;quot;f&amp;quot;, num))&lt;br /&gt;
end -- end function &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===RUsame===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
function RUsame(num, comp)                              --  Rounds a Number (Double) up or down&lt;br /&gt;
  local function toint(number)&lt;br /&gt;
    return math.floor(tonumber(number) or error(&amp;quot;Could not cast '&amp;quot; .. tostring(number) .. &amp;quot;' to number.'&amp;quot;))&lt;br /&gt;
  end&lt;br /&gt;
  local function Rounder(num, idp)                      --  Rounds a Number (Double) up or down&lt;br /&gt;
    return tonumber(string.format(&amp;quot;%.&amp;quot; .. (idp or 0) .. &amp;quot;f&amp;quot;, num))&lt;br /&gt;
  end -- end function&lt;br /&gt;
        num = math.abs(num)&lt;br /&gt;
  local idp = #comp&lt;br /&gt;
  local Mynum = Rounder(num, idp)&lt;br /&gt;
  local Myint = toint(Mynum)&lt;br /&gt;
  local Myval = tonumber(tostring(Myint) .. &amp;quot;.&amp;quot; .. comp)&lt;br /&gt;
  if (Mynum == Myval) then&lt;br /&gt;
    return true&lt;br /&gt;
  else&lt;br /&gt;
    return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
end -- end function &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===WithIn===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Retuns true if number is within tolerance with match&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function WithIn(Num, Mat, Tol)&lt;br /&gt;
    if ((Num &amp;gt;= (Mat - Tol)) and (Num &amp;lt;= (Mat + Tol))) then&lt;br /&gt;
      return true&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return false&lt;br /&gt;
  end -- end function &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Double2Fraction===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Converts a Measurement (Double) to a Fractional String&lt;br /&gt;
&lt;br /&gt;
local txt = Double2Fraction(1.25)&lt;br /&gt;
&lt;br /&gt;
returns txt =&amp;quot;1-1/4&amp;quot;&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function Double2Fraction(Num)&lt;br /&gt;
  local Frac = &amp;quot;Error&amp;quot;&lt;br /&gt;
  if Num then&lt;br /&gt;
    Frac = tostring(Num)&lt;br /&gt;
  end&lt;br /&gt;
  if (not Milling.Unit) and Num then&lt;br /&gt;
    local AmountValuex = math.floor(math.abs(Num))&lt;br /&gt;
    local DicValue    = Num - AmountValuex&lt;br /&gt;
    local AmountValue = tostring(AmountValuex)&lt;br /&gt;
    Frac              = tostring(DicValue)&lt;br /&gt;
&lt;br /&gt;
    if Project.Fractions == &amp;quot;No Fractions&amp;quot; then&lt;br /&gt;
      Frac = tostring(Num)&lt;br /&gt;
&lt;br /&gt;
    elseif Project.Fractions == &amp;quot;1/8&amp;quot; then&lt;br /&gt;
      if     DicValue &amp;gt;= 0.9375 then&lt;br /&gt;
        AmountValue = tostring(AmountValuex + 1)&lt;br /&gt;
        Frac = &amp;quot;0&amp;quot;&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.8125 then Frac = &amp;quot;7/8&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.6875 then Frac = &amp;quot;3/4&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.5625 then Frac = &amp;quot;5/8&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.4375 then Frac = &amp;quot;1/2&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.3125 then Frac = &amp;quot;3/8&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.1875 then Frac = &amp;quot;1/4&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.0625 then Frac = &amp;quot;1/8&amp;quot; .. string.char(34)&lt;br /&gt;
      else&lt;br /&gt;
        Frac = &amp;quot;0&amp;quot;&lt;br /&gt;
      end&lt;br /&gt;
    elseif Project.Fractions == &amp;quot;1/16&amp;quot; then&lt;br /&gt;
      if     DicValue &amp;gt;= 0.96875 then&lt;br /&gt;
        AmountValue = tostring(AmountValuex + 1)&lt;br /&gt;
        Frac = &amp;quot;0&amp;quot;&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.90625 then Frac = &amp;quot;15/16&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.84375 then Frac = &amp;quot;7/8&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.78125 then Frac = &amp;quot;13/16&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.71875 then Frac = &amp;quot;3/4&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.65625 then Frac = &amp;quot;11/16&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.59375 then Frac = &amp;quot;5/8&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.53125 then Frac = &amp;quot;9/16&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.46875 then Frac = &amp;quot;1/2&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.40625 then Frac = &amp;quot;7/16&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.34375 then Frac = &amp;quot;3/8&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.28125 then Frac = &amp;quot;5/16&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.21875 then Frac = &amp;quot;1/4&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.15625 then Frac = &amp;quot;3/16&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.09375 then Frac = &amp;quot;1/8&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.03125 then Frac = &amp;quot;1/16&amp;quot;  .. string.char(34)&lt;br /&gt;
      else&lt;br /&gt;
        Frac = &amp;quot;0&amp;quot;&lt;br /&gt;
      end -- If end&lt;br /&gt;
    elseif Project.Fractions == &amp;quot;1/32&amp;quot; then&lt;br /&gt;
      if     DicValue &amp;gt;= 0.984375 then&lt;br /&gt;
        AmountValue = tostring(AmountValuex + 1)&lt;br /&gt;
        Frac = &amp;quot;0&amp;quot;&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.953126 then Frac = &amp;quot;31/32&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.921876 then Frac = &amp;quot;15/16&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.890626 then Frac = &amp;quot;29/32&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.859376 then Frac = &amp;quot;7/8&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.828126 then Frac = &amp;quot;27/32&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.796876 then Frac = &amp;quot;13/16&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.765626 then Frac = &amp;quot;25/32&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.737376 then Frac = &amp;quot;3/4&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.703126 then Frac = &amp;quot;23/32&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.671876 then Frac = &amp;quot;11/16&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.640626 then Frac = &amp;quot;21/32&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.609376 then Frac = &amp;quot;5/8&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.578126 then Frac = &amp;quot;19/32&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.541260 then Frac = &amp;quot;9/16&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.515626 then Frac = &amp;quot;17/32&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.484376 then Frac = &amp;quot;1/2&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.468760 then Frac = &amp;quot;15/32&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.421876 then Frac = &amp;quot;7/16&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.390626 then Frac = &amp;quot;13/32&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.359376 then Frac = &amp;quot;3/8&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.328126 then Frac = &amp;quot;11/32&amp;quot; .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.296876 then Frac = &amp;quot;5/16&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.265626 then Frac = &amp;quot;9/32&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.234376 then Frac = &amp;quot;1/4&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.203126 then Frac = &amp;quot;7/32&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.171876 then Frac = &amp;quot;3/16&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.140626 then Frac = &amp;quot;5/32&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.109376 then Frac = &amp;quot;1/8&amp;quot;   .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.078126 then Frac = &amp;quot;3/32&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.046876 then Frac = &amp;quot;1/16&amp;quot;  .. string.char(34)&lt;br /&gt;
      elseif DicValue &amp;gt;= 0.015626 then Frac = &amp;quot;1/32&amp;quot;  .. string.char(34)&lt;br /&gt;
      else&lt;br /&gt;
        Frac = &amp;quot;0&amp;quot;&lt;br /&gt;
      end -- If end&lt;br /&gt;
    elseif Project.Fractions == &amp;quot;1/64&amp;quot; then&lt;br /&gt;
      if     DicValue &amp;gt;= 0.9921875 then&lt;br /&gt;
        AmountValue = tostring(AmountValuex + 1)&lt;br /&gt;
        Frac = &amp;quot;0&amp;quot;&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.9765625 then Frac = &amp;quot;62/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.9609375 then Frac = &amp;quot;31/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.9453125 then Frac = &amp;quot;61/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.9296875 then Frac = &amp;quot;15/16&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.9140625 then Frac = &amp;quot;59/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.8984375 then Frac = &amp;quot;29/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.8828125 then Frac = &amp;quot;57/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.8671875 then Frac = &amp;quot;7/8&amp;quot;   .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.8515625 then Frac = &amp;quot;55/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.8359375 then Frac = &amp;quot;27/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.8203125 then Frac = &amp;quot;53/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.8046875 then Frac = &amp;quot;13/16&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.7890625 then Frac = &amp;quot;51/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.7734375 then Frac = &amp;quot;25/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.7578125 then Frac = &amp;quot;49/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.7421875 then Frac = &amp;quot;3/4&amp;quot;   .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.7265625 then Frac = &amp;quot;47/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.7109375 then Frac = &amp;quot;23/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.6953125 then Frac = &amp;quot;45/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.6796875 then Frac = &amp;quot;11/16&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.6640625 then Frac = &amp;quot;43/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.6484375 then Frac = &amp;quot;21/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.6328125 then Frac = &amp;quot;41/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.6171875 then Frac = &amp;quot;5/8&amp;quot;   .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.6015625 then Frac = &amp;quot;39/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.5859375 then Frac = &amp;quot;19/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.5703125 then Frac = &amp;quot;37/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.5546875 then Frac = &amp;quot;9/16&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.5390625 then Frac = &amp;quot;35/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.5234375 then Frac = &amp;quot;17/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.5078125 then Frac = &amp;quot;33/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.4921875 then Frac = &amp;quot;1/2&amp;quot;   .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.4765625 then Frac = &amp;quot;31/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.4609375 then Frac = &amp;quot;15/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.4453125 then Frac = &amp;quot;29/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.4296875 then Frac = &amp;quot;7/16&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.4140625 then Frac = &amp;quot;27/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.3984375 then Frac = &amp;quot;13/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.3828125 then Frac = &amp;quot;25/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.3671875 then Frac = &amp;quot;3/8&amp;quot;   .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.3515625 then Frac = &amp;quot;23/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.3359375 then Frac = &amp;quot;11/32&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.3203125 then Frac = &amp;quot;21/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.3046875 then Frac = &amp;quot;5/16&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.2890625 then Frac = &amp;quot;19/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.2734375 then Frac = &amp;quot;9/32&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.2578125 then Frac = &amp;quot;17/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.2421875 then Frac = &amp;quot;1/4&amp;quot;   .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.2265625 then Frac = &amp;quot;15/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.2109375 then Frac = &amp;quot;7/32&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.1953125 then Frac = &amp;quot;13/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.1796875 then Frac = &amp;quot;3/16&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.1640625 then Frac = &amp;quot;11/64&amp;quot; .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.1484375 then Frac = &amp;quot;5/32&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.1328125 then Frac = &amp;quot;9/64&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.1171875 then Frac = &amp;quot;1/8&amp;quot;   .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.1015625 then Frac = &amp;quot;7/64&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.0859375 then Frac = &amp;quot;3/32&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.0703125 then Frac = &amp;quot;5/64&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.0546875 then Frac = &amp;quot;1/16&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.0390625 then Frac = &amp;quot;3/64&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.0234375 then Frac = &amp;quot;1/32&amp;quot;  .. string.char(34)&lt;br /&gt;
        elseif DicValue &amp;gt;= 0.0078125 then Frac = &amp;quot;1/64&amp;quot;  .. string.char(34)&lt;br /&gt;
        else&lt;br /&gt;
          Frac = &amp;quot;0&amp;quot;&lt;br /&gt;
        end -- If end&lt;br /&gt;
      end&lt;br /&gt;
    if Project.Fractions == &amp;quot;No Fractions&amp;quot; then&lt;br /&gt;
      Frac = tostring(Num)&lt;br /&gt;
    else&lt;br /&gt;
      if Frac == &amp;quot;0&amp;quot; then&lt;br /&gt;
        Frac = AmountValue .. string.char(34)&lt;br /&gt;
      else&lt;br /&gt;
        if AmountValue ~= &amp;quot;0&amp;quot; then&lt;br /&gt;
          Frac = AmountValue .. &amp;quot;-&amp;quot; .. Frac&lt;br /&gt;
        end&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  return Frac&lt;br /&gt;
end -- end function &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Time and Date Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This collection of functions are utilized in the date and time calculations.&lt;br /&gt;
&lt;br /&gt;
===StartDateTime===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
StartDateTime - Returns the Date and Time.&lt;br /&gt;
&lt;br /&gt;
local dt= StartDateTime(true)&lt;br /&gt;
&lt;br /&gt;
returns tbl = &amp;quot;10/02/23&amp;quot;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;   function StartDateTime(LongShort)&lt;br /&gt;
--[[ Date Value Codes&lt;br /&gt;
--  |    %a  abbreviated weekday name (e.g., Wed)&lt;br /&gt;
--  |    %A  full weekday name (e.g., Wednesday)&lt;br /&gt;
--  |    %b  abbreviated month name (e.g., Sep)&lt;br /&gt;
--  |    %B  full month name (e.g., September)&lt;br /&gt;
--  |    %c  date and time (e.g., 09/16/98 23:48:10)&lt;br /&gt;
--  |    %d  day of the month (16) [01-31]&lt;br /&gt;
--  |    %H  hour, using a 24-hour clock (23) [00-23]&lt;br /&gt;
--  |    %I  hour, using a 12-hour clock (11) [01-12]&lt;br /&gt;
--  |    %M  minute (48) [00-59]&lt;br /&gt;
--  |    %m  month (09) [01-12]&lt;br /&gt;
--  |    %p  either &amp;quot;am&amp;quot; or &amp;quot;pm&amp;quot; (pm)&lt;br /&gt;
--  |    %S  second (10) [00-60]&lt;br /&gt;
--  |    %w  weekday (3) [0-6 = Sunday-Saturday]&lt;br /&gt;
--  |    %x  date (e.g., 09/16/98)&lt;br /&gt;
--  |    %X  time (e.g., 23:48:10)&lt;br /&gt;
--  |    %Y  full year (e.g., 1998)&lt;br /&gt;
--  |    %y  two-digit year (98) [00-99]&lt;br /&gt;
--  |    %%  the character `%´ ]]&lt;br /&gt;
    if LongShort then&lt;br /&gt;
      return os.date(&amp;quot;%b %d, %Y&amp;quot;) .. &amp;quot; - &amp;quot; .. os.date(&amp;quot;%I&amp;quot;) .. &amp;quot;:&amp;quot; .. os.date(&amp;quot;%m&amp;quot;) .. os.date(&amp;quot;%p&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      return os.date(&amp;quot;%Y%m%d%H%M&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
  end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===StartDate===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
StartDate - Returns the Date and Time.&lt;br /&gt;
&lt;br /&gt;
local dt= StartDate(true)&lt;br /&gt;
&lt;br /&gt;
returns tbl = &amp;quot;10/02/23&amp;quot;&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function StartDate(LongShort)&lt;br /&gt;
--[[ Date Value Codes&lt;br /&gt;
--  |    %a  abbreviated weekday name (e.g., Wed)&lt;br /&gt;
--  |    %A  full weekday name (e.g., Wednesday)&lt;br /&gt;
--  |    %b  abbreviated month name (e.g., Sep)&lt;br /&gt;
--  |    %B  full month name (e.g., September)&lt;br /&gt;
--  |    %c  date and time (e.g., 09/16/98 23:48:10)&lt;br /&gt;
--  |    %d  day of the month (16) [01-31]&lt;br /&gt;
--  |    %H  hour, using a 24-hour clock (23) [00-23]&lt;br /&gt;
--  |    %I  hour, using a 12-hour clock (11) [01-12]&lt;br /&gt;
--  |    %M  minute (48) [00-59]&lt;br /&gt;
--  |    %m  month (09) [01-12]&lt;br /&gt;
--  |    %p  either &amp;quot;am&amp;quot; or &amp;quot;pm&amp;quot; (pm)&lt;br /&gt;
--  |    %S  second (10) [00-60]&lt;br /&gt;
--  |    %w  weekday (3) [0-6 = Sunday-Saturday]&lt;br /&gt;
--  |    %x  date (e.g., 09/16/98)&lt;br /&gt;
--  |    %X  time (e.g., 23:48:10)&lt;br /&gt;
--  |    %Y  full year (e.g., 1998)&lt;br /&gt;
--  |    %y  two-digit year (98) [00-99]&lt;br /&gt;
--  |    %%  the character `%´ ]]&lt;br /&gt;
&lt;br /&gt;
    if LongShort then&lt;br /&gt;
      return os.date(&amp;quot;%b %d, %Y&amp;quot;)  -- &amp;quot;Sep 01, 2022&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      return os.date(&amp;quot;%Y%m%d&amp;quot;)     -- &amp;quot;20220901&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Wait===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Wait - Waits for a duration.&lt;br /&gt;
&lt;br /&gt;
local dt = Wait(true)&lt;br /&gt;
&lt;br /&gt;
returns tbl = &amp;quot;10/02/23&amp;quot;&lt;br /&gt;
&lt;br /&gt;
   &amp;lt;nowiki&amp;gt; function Wait(time)&lt;br /&gt;
    local duration = os.time() + time&lt;br /&gt;
    while os.time() &amp;lt; duration do end&lt;br /&gt;
    end&lt;br /&gt;
 end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Debugging Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This collection of functions assist in the debugging of code.&lt;br /&gt;
&lt;br /&gt;
===DMark - places a circle and notation to assist in geometry debugging===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws a circle and marks on the drawing for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
call = DebugMarkPoint(&amp;quot;Note: Hi&amp;quot;, Pt1)&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function DMark(Note, Pt)&lt;br /&gt;
  -- ==== Sub Function&lt;br /&gt;
    local function DrawCircle(job, Cpt, CircleRadius, LayerName)  -- Draws a circle&lt;br /&gt;
      local pa   = Polar2D(Cpt, 180.0, CircleRadius)&lt;br /&gt;
      local pb   = Polar2D(Cpt,   0.0, CircleRadius)&lt;br /&gt;
      local line = Contour(0.0)&lt;br /&gt;
      line:AppendPoint(pa); line:ArcTo(pb,1); line:ArcTo(pa,1)&lt;br /&gt;
      local layer = job.LayerManager:GetLayerWithName(LayerName)&lt;br /&gt;
      layer:AddObject(CreateCadContour(line), true)&lt;br /&gt;
      return true&lt;br /&gt;
    end -- function end&lt;br /&gt;
  -- ====&lt;br /&gt;
    local BubbleSize = 1.25&lt;br /&gt;
    if not Project.DebugAngle then&lt;br /&gt;
      Project.DebugAngle = 0.0&lt;br /&gt;
    end&lt;br /&gt;
    Project.DebugAngle = Project.DebugAngle + 2.0&lt;br /&gt;
    if Project.DebugAngle &amp;gt;= 90.0 and Project.DebugAngle &amp;lt;= 358.0 then&lt;br /&gt;
      Project.DebugAngle = 272.0&lt;br /&gt;
    elseif Project.DebugAngle &amp;gt;= 360.0 then&lt;br /&gt;
      Project.DebugAngle = 2.0&lt;br /&gt;
    end&lt;br /&gt;
    if Pt then&lt;br /&gt;
      local job = VectricJob()&lt;br /&gt;
      local Pt1 = Polar2D(Pt, Project.DebugAngle, BubbleSize)&lt;br /&gt;
      local Pt2 = Polar2D(Pt1, 0.0, BubbleSize * 0.25)&lt;br /&gt;
      local Pt3 = Polar2D(Pt2, 315.0, BubbleSize * 0.0883883476483188 * 4.0)&lt;br /&gt;
      local line = Contour(0.0)&lt;br /&gt;
      local layer = job.LayerManager:GetLayerWithName(&amp;quot;Debug&amp;quot;)&lt;br /&gt;
      line:AppendPoint(Pt)&lt;br /&gt;
      line:LineTo(Pt1)&lt;br /&gt;
      line:LineTo(Pt2)&lt;br /&gt;
      layer:AddObject(CreateCadContour(line), true)&lt;br /&gt;
      DrawWriter(Note, Pt3, BubbleSize * 0.5, &amp;quot;Debug&amp;quot;, 0.0)&lt;br /&gt;
      DrawCircle(job, Pt, BubbleSize * 0.5, &amp;quot;Debug&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Issue with Point for - &amp;quot; .. Note)&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===StatusMessage===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Useage: (Type of Message, Dialog Header, Question or Message, Err No.)&lt;br /&gt;
&lt;br /&gt;
StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Base Cabinet Settings&amp;quot;, &amp;quot;Face Frame Bottom Rail Width - value cannot be 0.&amp;quot;, &amp;quot;(9000)&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Note: if the debug flag is on (true) a message box shows the message length, dialog size and error number&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function StatusMessage(Type, Header, Question, ErrorNumber)&lt;br /&gt;
&lt;br /&gt;
  local dialog&lt;br /&gt;
  local X = 460&lt;br /&gt;
  local Y = 124&lt;br /&gt;
  local step = 35&lt;br /&gt;
  Question = WrapString(Question, step)&lt;br /&gt;
  local QL = string.len(Question)&lt;br /&gt;
  if (QL &amp;gt; step) and (QL &amp;lt; step * 2) then&lt;br /&gt;
    Y = Y + 12&lt;br /&gt;
  elseif (QL &amp;gt; (step * 2) +1) and (QL &amp;lt; 105) then&lt;br /&gt;
    Y = Y + 24&lt;br /&gt;
  elseif (QL &amp;gt; (step * 3) +1) and (QL &amp;lt; (step * 4)) then&lt;br /&gt;
    Y = Y + 36&lt;br /&gt;
  elseif (QL &amp;gt; (step * 4) +1) and (QL &amp;lt; (step * 5)) then&lt;br /&gt;
    Y = Y + 48&lt;br /&gt;
  elseif (QL &amp;gt; (step * 5) +1) and (QL &amp;lt; (step * 6)) then&lt;br /&gt;
    Y = Y + 60&lt;br /&gt;
  elseif (QL &amp;gt; (step * 6) +1) and (QL &amp;lt; (step * 7)) then&lt;br /&gt;
    Y = Y + 72&lt;br /&gt;
  elseif (QL &amp;gt; (step * 7) +1) and (QL &amp;lt; (step * 8)) then&lt;br /&gt;
    Y = Y + 84&lt;br /&gt;
  elseif (QL &amp;gt; (step * 8) +1) and (QL &amp;lt; (step * 9)) then&lt;br /&gt;
    Y = Y + 96&lt;br /&gt;
  elseif (QL &amp;gt; (step * 9) +1) and (QL &amp;lt; (step * 10)) then&lt;br /&gt;
    Y = Y + 108&lt;br /&gt;
  elseif (QL &amp;gt; (step * 10) +1) and (QL &amp;lt; (step * 11)) then&lt;br /&gt;
    Y = Y + 120&lt;br /&gt;
  else&lt;br /&gt;
    Y = Y + 150&lt;br /&gt;
  end&lt;br /&gt;
  if Project.Debugger then&lt;br /&gt;
    Queston = Question .. &amp;quot; - &amp;quot; .. ErrorNumber&lt;br /&gt;
  end&lt;br /&gt;
  if Type == &amp;quot;Alert&amp;quot; then&lt;br /&gt;
    dialog = HTML_Dialog(true, DialogWindow.myHtml16, X, Y, Header)&lt;br /&gt;
  else -- &amp;quot;Error&amp;quot;&lt;br /&gt;
    dialog = HTML_Dialog(true, DialogWindow.myHtml17, X, Y, Header)&lt;br /&gt;
  end -- if end&lt;br /&gt;
  if Project.Debugger then&lt;br /&gt;
    Question = Question .. &amp;quot; &amp;quot; .. ErrorNumber&lt;br /&gt;
  end&lt;br /&gt;
  dialog:AddLabelField(&amp;quot;Question&amp;quot;, Type .. &amp;quot;: &amp;quot; .. Question)&lt;br /&gt;
  dialog:ShowDialog()&lt;br /&gt;
  if Project.Debugger then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Question Len &amp;quot; .. &amp;quot; = &amp;quot; .. tostring(string.len(Question)) .. &amp;quot;: \nWindow = &amp;quot; .. tostring(dialog.WindowWidth) .. &amp;quot; x &amp;quot; .. tostring(dialog.WindowHeight))&lt;br /&gt;
  end&lt;br /&gt;
  return true&lt;br /&gt;
end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===DebugMarkPoint===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Used in debugging drawing issues - Draws a Circle and Text at the provided point(x,y) &lt;br /&gt;
&lt;br /&gt;
call = DebugMarkPoint(&amp;quot;Note: Hi&amp;quot;, Pt1, 0.125, &amp;quot;Jim&amp;quot;)&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DebugMarkPoint(Note, Pt, Size, LayerName)&lt;br /&gt;
    if Size == nil then&lt;br /&gt;
      Size = 0.125&lt;br /&gt;
    end&lt;br /&gt;
    if LayerName == nil then&lt;br /&gt;
      LayerName = &amp;quot;Debug&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
  -- ==== Sub Function&lt;br /&gt;
    local function DrawCircle(job, Cpt, CircleRadius, LayerName)  -- Draws a circle&lt;br /&gt;
      local pa = Polar2D(Cpt, 180.0, CircleRadius)&lt;br /&gt;
      local pb = Polar2D(Cpt,   0.0, CircleRadius)&lt;br /&gt;
      local line = Contour(0.0)&lt;br /&gt;
      line:AppendPoint(pa); line:ArcTo(pb,1);   line:ArcTo(pa,1)&lt;br /&gt;
      local layer = job.LayerManager:GetLayerWithName(LayerName)&lt;br /&gt;
      layer:AddObject(CreateCadContour(line), true)&lt;br /&gt;
      return true&lt;br /&gt;
    end -- sub function end&lt;br /&gt;
  -- ====&lt;br /&gt;
    local job = VectricJob()&lt;br /&gt;
    local Pt1 = Polar2D(Pt, Project.DebugAngle, Size * 2.0)&lt;br /&gt;
    local Pt2 = Polar2D(Pt1, 0.0, 0.500 * Size)&lt;br /&gt;
    local Pt3 = Polar2D(Pt2, 315.0, (0.500 * Size) * 1.4142135623731)&lt;br /&gt;
    local line = Contour(0.0)&lt;br /&gt;
    local layer = job.LayerManager:GetLayerWithName(LayerName)&lt;br /&gt;
    line:AppendPoint(Pt)&lt;br /&gt;
    line:LineTo(Pt1)&lt;br /&gt;
    line:LineTo(Pt2)&lt;br /&gt;
    layer:AddObject(CreateCadContour(line), true)&lt;br /&gt;
    DrawWriter(Note, Pt3, Size, LayerName, 0.0)&lt;br /&gt;
    DrawCircle(job, Pt, Size, LayerName)&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===ShowDialogSize===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function ShowDialogSize()&lt;br /&gt;
    DisplayMessageBox(tostring(dialog.WindowWidth) .. &amp;quot; x &amp;quot; ..  tostring(dialog.WindowHeight))&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Dialog and Menu Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document.&lt;br /&gt;
&lt;br /&gt;
===DialogSize===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function DialogSize(Str)                                -- Returns the X and Y value of the dialogue&lt;br /&gt;
  local InText = string.find(string.upper(Str) , &amp;quot;X&amp;quot;)&lt;br /&gt;
  local DialogX = All_Trim(string.sub(Str, 1, InText - 1))&lt;br /&gt;
  local DialogY = All_Trim(string.sub(Str, InText + 1))&lt;br /&gt;
  return tonumber(DialogX), tonumber(DialogY)&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===ProgressBarAmount===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function ProgressBarAmount(TotalRecords, Record)        -- Calculates the percent amount of progression based on total process&lt;br /&gt;
  --[[&lt;br /&gt;
  local MyProgressBar&lt;br /&gt;
    MyProgressBar = ProgressBar(&amp;quot;Working&amp;quot;, ProgressBar.LINEAR)                -- Setup Type of progress bar&lt;br /&gt;
    MyProgressBar:SetPercentProgress(0)                                       -- Sets progress bar to zero&lt;br /&gt;
    MyProgressBar:SetPercentProgress(ProgressAmount(Door.Records, myRecord))  -- sends percent of process progress bar (adds to the bar)&lt;br /&gt;
    MyProgressBar:SetPercentProgress(ProgressAmount(12000, 416))              -- sends percent of process progress bar (adds to the bar)&lt;br /&gt;
    MyProgressBar:SetText(&amp;quot;Compete&amp;quot;)                                          -- Sets the label to Complete&lt;br /&gt;
    MyProgressBar:Finished()                                                  -- Close Progress Bar&lt;br /&gt;
  ]]&lt;br /&gt;
    local X1 = (100.0 / TotalRecords)&lt;br /&gt;
    local X2 = X1 * Record&lt;br /&gt;
    local X3 = math.abs(X2)&lt;br /&gt;
    local X4 = (math.floor(X3))&lt;br /&gt;
    return (math.floor(math.abs((100.0 / TotalRecords) * Record)))&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===OnLuaButton_InquiryGearCalulate===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function OnLuaButton_InquiryGearCalulate(dialog)&lt;br /&gt;
  Gear.Addendum         = dialog:GetDoubleField(&amp;quot;Gear.Addendum&amp;quot;)&lt;br /&gt;
  Gear.Dedendum         = dialog:GetDoubleField(&amp;quot;Gear.Dedendum&amp;quot;)&lt;br /&gt;
  Gear.AddendumDiameter = dialog:GetDoubleField(&amp;quot;Gear.AddendumDiameter&amp;quot;)&lt;br /&gt;
  Gear.DedendumDiameter = dialog:GetDoubleField(&amp;quot;Gear.DedendumDiameter&amp;quot;)&lt;br /&gt;
  Gear.ToothTickness    = dialog:GetDoubleField(&amp;quot;Gear.ToothTickness&amp;quot;)&lt;br /&gt;
  Gear.Slotwidth        = dialog:GetDoubleField(&amp;quot;Gear.Slotwidth&amp;quot;)&lt;br /&gt;
  Gear.PitchAmount      = dialog:GetDoubleField(&amp;quot;Gear.PitchAmount&amp;quot;)&lt;br /&gt;
  Gear.FilletRadius     = dialog:GetDoubleField(&amp;quot;Gear.FilletRadius&amp;quot;)&lt;br /&gt;
  Gear.ToplandAmount    = dialog:GetDoubleField(&amp;quot;Gear.ToplandAmount&amp;quot;)&lt;br /&gt;
  Gear.FaceFlankRadius  = dialog:GetDoubleField(&amp;quot;Gear.FaceFlankRadius&amp;quot;)&lt;br /&gt;
  Gear.ToothCount       = dialog:GetDropDownListValue(&amp;quot;Gear.ToothCount&amp;quot;)&lt;br /&gt;
  Gear.ShowLines        = dialog:GetDropDownListValue(&amp;quot;Gear.ShowLines&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  dialog:UpdateDoubleField(&amp;quot;Gear.Addendum&amp;quot;,                      Gear.Addendum)&lt;br /&gt;
  dialog:UpdateDoubleField(&amp;quot;Gear.Dedendum&amp;quot;,                      Gear.Dedendum)&lt;br /&gt;
  dialog:UpdateDoubleField(&amp;quot;Gear.AddendumDiameter&amp;quot;,              Gear.AddendumDiameter)&lt;br /&gt;
  dialog:UpdateDoubleField(&amp;quot;Gear.DedendumDiameter&amp;quot;,              Gear.DedendumDiameter)&lt;br /&gt;
  dialog:UpdateDoubleField(&amp;quot;Gear.ToothTickness&amp;quot;,                 Gear.ToothTickness)&lt;br /&gt;
  dialog:UpdateDoubleField(&amp;quot;Gear.Slotwidth&amp;quot;,                     Gear.Slotwidth)&lt;br /&gt;
  dialog:UpdateDoubleField(&amp;quot;Gear.PitchAmount&amp;quot;,                   Gear.PitchAmount)&lt;br /&gt;
  dialog:UpdateDoubleField(&amp;quot;Gear.FilletRadius&amp;quot;,                  Gear.FilletRadius)&lt;br /&gt;
  dialog:UpdateDoubleField(&amp;quot;Gear.ToplandAmount&amp;quot;,                 Gear.ToplandAmount)&lt;br /&gt;
  dialog:UpdateDoubleField(&amp;quot;Gear.FaceFlankRadius&amp;quot;,               Gear.FaceFlankRadius)&lt;br /&gt;
&lt;br /&gt;
  return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===InquiryDropList===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function InquiryDropList(Header, Quest, DX, DY, DList)&lt;br /&gt;
--[[&lt;br /&gt;
    Drop list foe user input&lt;br /&gt;
    Caller: local y = InquiryDropList(&amp;quot;Cabinet Maker&amp;quot;, &amp;quot;Select Cabinet Style&amp;quot;, 290, 165, IniFile)&lt;br /&gt;
    Dialog Header = &amp;quot;Cabinet Maker&amp;quot;&lt;br /&gt;
    Quest = &amp;quot;Select Cabinet Style&amp;quot;&lt;br /&gt;
    Selection Array = IniFile&lt;br /&gt;
    Returns = String&lt;br /&gt;
]]&lt;br /&gt;
    local myHtml = [[&amp;lt;!DOCTYPE HTML&amp;gt;&amp;lt;html lang=&amp;quot;en&amp;quot;&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;My List Box&amp;lt;/title&amp;gt;&amp;lt;style&amp;gt;.FormButton{font-weight:700;width:75px;font-size:12px;white-space:nowrap;font-family:Arial,Helvetica,sans-serif font-size: 12px}.h1-l{font-size:12px;font-weight:700;text-align:left;white-space:nowrap}.h1-c{font-size:12px;font-weight:700;text-align:center;white-space:nowrap}table{width:100%;border:0}body,td,th{background-color:#3a4660;background-position:center;overflow:hidden;font-family:arial,helvetica,sans-serif;font-size:12px;color:#fff;background-image:url(']].. DialogWindow.myBackGround ..[[')}html{overflow:hidden}&amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;h1-l&amp;quot; id=&amp;quot;Questions&amp;quot;&amp;gt;&amp;lt;strong class=&amp;quot;h2&amp;quot;&amp;gt;Message Here&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;h1-c&amp;quot;&amp;gt;&amp;lt;select name=&amp;quot;DList&amp;quot; size=&amp;quot;10&amp;quot; class=&amp;quot;h1-c&amp;quot; id=&amp;quot;ListBox&amp;quot;&amp;gt;&amp;lt;option&amp;gt;My Default 1&amp;lt;/option&amp;gt;&amp;lt;option selected=&amp;quot;selected&amp;quot;&amp;gt;My Default 2&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;My Default 3&amp;lt;/option&amp;gt;&amp;lt;option&amp;gt;My Default 4&amp;lt;/option&amp;gt;&amp;lt;/select&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;th class=&amp;quot;h1-l&amp;quot; colspan=&amp;quot;3&amp;quot; id=&amp;quot;QuestionID&amp;quot;&amp;gt;&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;h1-c&amp;quot;&amp;gt;&amp;lt;input id=&amp;quot;ButtonCancel&amp;quot; class=&amp;quot;FormButton&amp;quot; name=&amp;quot;ButtonCancel&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;Cancel&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td class=&amp;quot;h1-c&amp;quot;&amp;gt;&amp;lt;input id=&amp;quot;ButtonOK&amp;quot; class=&amp;quot;FormButton&amp;quot; name=&amp;quot;ButtonOK&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;OK&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;]] ;&lt;br /&gt;
&lt;br /&gt;
    local dialog = HTML_Dialog(true, myHtml, DX, DY, Header)&lt;br /&gt;
          dialog:AddLabelField(&amp;quot;Questions&amp;quot;, Quest)&lt;br /&gt;
          dialog:AddDropDownList(&amp;quot;ListBox&amp;quot;, &amp;quot;DEFAULT&amp;quot;)&lt;br /&gt;
          dialog:AddDropDownListValue(&amp;quot;ListBox&amp;quot;, &amp;quot;DEFAULT&amp;quot;)&lt;br /&gt;
    for index, value in pairs(DList) do&lt;br /&gt;
        dialog:AddDropDownListValue(&amp;quot;ListBox&amp;quot;, value)&lt;br /&gt;
    end&lt;br /&gt;
    if not dialog:ShowDialog() then&lt;br /&gt;
      return &amp;quot;.&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      return dialog:GetDropDownListValue(&amp;quot;ListBox&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===InquiryFileBox===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function InquiryFileBox(Header, Quest, DefaltPath)&lt;br /&gt;
--[[&lt;br /&gt;
    Dialog Box for user to pick a file&lt;br /&gt;
    Caller: local X = InquiryFileBox(&amp;quot;Select File&amp;quot;, &amp;quot;Where is the file location?&amp;quot;, &amp;quot;C:\\&amp;quot;)&lt;br /&gt;
    Dialog Header = &amp;quot;File Name&amp;quot;&lt;br /&gt;
    User Question = &amp;quot;Path name?&amp;quot;&lt;br /&gt;
    Default Value = &amp;quot;C:\\&amp;quot;&lt;br /&gt;
    Returns = String&lt;br /&gt;
  ]]&lt;br /&gt;
  local myHtml = [[&amp;lt;html&amp;gt; &amp;lt;head&amp;gt; &amp;lt;title&amp;gt;Easy Tools&amp;lt;/title&amp;gt; &amp;lt;style type = &amp;quot;text/css&amp;quot;&amp;gt;  html {overflow: hidden; } body {&lt;br /&gt;
             background-color: #EBEBEB; overflow:hidden; font-family: Arial, Helvetica, sans-serif; font-size: 12px; } body, td,&lt;br /&gt;
             th {font-family: Arial, Helvetica, sans-serif ; font-size: 12px ; color: #000 ; } .FormButton {font-weight: bold ;&lt;br /&gt;
             width: 100% ; font-family: Arial, Helvetica, sans-serif ; font-size: 12px ; } body { background-color: #EBEBEB; }&lt;br /&gt;
             &amp;lt;/style&amp;gt; &amp;lt;/head&amp;gt; &amp;lt;body bgcolor = &amp;quot;#EBEBEB&amp;quot; text = &amp;quot;#000000&amp;quot;&amp;gt; &amp;lt;table width = &amp;quot;470&amp;quot; border = &amp;quot;0&amp;quot; cellpadding = &amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;tr&amp;gt; &amp;lt;th align = &amp;quot;left&amp;quot; valign = &amp;quot;top&amp;quot; bgcolor = &amp;quot;#EBEBEB&amp;quot; id = &amp;quot;QuestionID&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Message Here&amp;lt;/strong&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
             &amp;lt;th align = &amp;quot;left&amp;quot; valign = &amp;quot;middle&amp;quot; bgcolor = &amp;quot;#EBEBEB&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/th&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt;&lt;br /&gt;
             &amp;lt;th width = &amp;quot;381&amp;quot; align = &amp;quot;right&amp;quot; valign = &amp;quot;middle&amp;quot; bgcolor = &amp;quot;#EBEBEB&amp;quot; id = &amp;quot;QuestionID&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;input name = &amp;quot;ReadFile&amp;quot; type = &amp;quot;text&amp;quot; id = &amp;quot;ReadFile&amp;quot; size = &amp;quot;60&amp;quot;&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
             &amp;lt;th width = &amp;quot;83&amp;quot; align = &amp;quot;center&amp;quot; valign = &amp;quot;middle&amp;quot; bgcolor = &amp;quot;#EBEBEB&amp;quot;&amp;gt; &amp;lt;span style=&amp;quot;width: 15%&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;input id = &amp;quot;FilePicker&amp;quot; class = &amp;quot;FilePicker&amp;quot; name = &amp;quot;FilePicker&amp;quot; type = &amp;quot;button&amp;quot; value = &amp;quot;Path&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td colspan = &amp;quot;2&amp;quot; align = &amp;quot;center&amp;quot; valign = &amp;quot;middle&amp;quot; bgcolor = &amp;quot;#EBEBEB&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;table border = &amp;quot;0&amp;quot; width = &amp;quot;100%&amp;quot;&amp;gt; &amp;lt;tr align = &amp;quot;right&amp;quot;&amp;gt; &amp;lt;td style = &amp;quot;width: 20%&amp;quot;&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
             &amp;lt;td style = &amp;quot;width: 20%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;td style = &amp;quot;width: 25%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;td style = &amp;quot;width: 15%&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;input id = &amp;quot;ButtonCancel&amp;quot; class = &amp;quot;FormButton&amp;quot; name = &amp;quot;ButtonCancel&amp;quot; type = &amp;quot;button&amp;quot; value = &amp;quot;Cancel&amp;quot;&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
             &amp;lt;td style = &amp;quot;width: 15%&amp;quot;&amp;gt; &amp;lt;input id = &amp;quot;ButtonOK&amp;quot; class = &amp;quot;FormButton&amp;quot; name = &amp;quot;ButtonOK&amp;quot; type = &amp;quot;button&amp;quot; value = &amp;quot;OK&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;/table&amp;gt; &amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;/table&amp;gt; &amp;lt;/body&amp;gt;  &amp;lt;/html&amp;gt;]]&lt;br /&gt;
  -- =============================================&lt;br /&gt;
  local dialog = HTML_Dialog(true, myHtml, 505, 150, Header)&lt;br /&gt;
    dialog:AddLabelField(&amp;quot;QuestionID&amp;quot;, Quest)&lt;br /&gt;
    dialog:AddTextField(&amp;quot;ReadFile&amp;quot;, DefaltPath )&lt;br /&gt;
    dialog:AddFilePicker(true, &amp;quot;FilePickerButton&amp;quot;, &amp;quot;ReadFile&amp;quot;, true)&lt;br /&gt;
    if not dialog:ShowDialog() then&lt;br /&gt;
      return &amp;quot;&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      return dialog:GetTextField(&amp;quot;ReadFile&amp;quot;)&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===InquiryPathBox===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function InquiryPathBox(Header, Quest, DefaltPath)&lt;br /&gt;
--[[&lt;br /&gt;
    Number Box for user input with default value&lt;br /&gt;
    Caller: local X = InquiryPathBox(&amp;quot;Select Path&amp;quot;, &amp;quot;Where is the file location?&amp;quot;, &amp;quot;C:\\&amp;quot;)&lt;br /&gt;
    Dialog Header = &amp;quot;Tool Name&amp;quot;&lt;br /&gt;
    User Question = &amp;quot;Path name?&amp;quot;&lt;br /&gt;
    Default Value = &amp;quot;C:\\&amp;quot;&lt;br /&gt;
    Returns = String&lt;br /&gt;
  ]]&lt;br /&gt;
  local myHtml = [[ &amp;lt;html&amp;gt; &amp;lt;head&amp;gt; &amp;lt;title&amp;gt;Easy Tools&amp;lt;/title&amp;gt; &amp;lt;style type = &amp;quot;text/css&amp;quot;&amp;gt;  html {overflow: hidden; } body {&lt;br /&gt;
             background-color: #EBEBEB; overflow:hidden; font-family: Arial, Helvetica, sans-serif; font-size: 12px; } body, td,&lt;br /&gt;
             th {font-family: Arial, Helvetica, sans-serif ; font-size: 12px ; color: #000 ; } .FormButton {font-weight: bold ;&lt;br /&gt;
             width: 100% ; font-family: Arial, Helvetica, sans-serif ; font-size: 12px ; } body { background-color: #EBEBEB; }&lt;br /&gt;
             &amp;lt;/style&amp;gt; &amp;lt;/head&amp;gt; &amp;lt;body bgcolor = &amp;quot;#EBEBEB&amp;quot; text = &amp;quot;#000000&amp;quot;&amp;gt; &amp;lt;table width = &amp;quot;470&amp;quot; border = &amp;quot;0&amp;quot; cellpadding = &amp;quot;0&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;tr&amp;gt; &amp;lt;th align = &amp;quot;left&amp;quot; valign = &amp;quot;top&amp;quot; bgcolor = &amp;quot;#EBEBEB&amp;quot; id = &amp;quot;QuestionID&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Message Here&amp;lt;/strong&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
             &amp;lt;th align = &amp;quot;left&amp;quot; valign = &amp;quot;middle&amp;quot; bgcolor = &amp;quot;#EBEBEB&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/th&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt;&lt;br /&gt;
             &amp;lt;th width = &amp;quot;381&amp;quot; align = &amp;quot;right&amp;quot; valign = &amp;quot;middle&amp;quot; bgcolor = &amp;quot;#EBEBEB&amp;quot; id = &amp;quot;QuestionID&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;input name = &amp;quot;DInput&amp;quot; type = &amp;quot;text&amp;quot; id = &amp;quot;DInput&amp;quot; size = &amp;quot;60&amp;quot;&amp;gt;&amp;lt;/th&amp;gt;&lt;br /&gt;
             &amp;lt;th width = &amp;quot;83&amp;quot; align = &amp;quot;center&amp;quot; valign = &amp;quot;middle&amp;quot; bgcolor = &amp;quot;#EBEBEB&amp;quot;&amp;gt; &amp;lt;span style=&amp;quot;width: 15%&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;input id = &amp;quot;DirectoryPicker&amp;quot; class = &amp;quot;DirectoryPicker&amp;quot; name = &amp;quot;DirectoryPicker&amp;quot; type = &amp;quot;button&amp;quot; value = &amp;quot;Path&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;/span&amp;gt;&amp;lt;/th&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td colspan = &amp;quot;2&amp;quot; align = &amp;quot;center&amp;quot; valign = &amp;quot;middle&amp;quot; bgcolor = &amp;quot;#EBEBEB&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;table border = &amp;quot;0&amp;quot; width = &amp;quot;100%&amp;quot;&amp;gt; &amp;lt;tr align = &amp;quot;right&amp;quot;&amp;gt; &amp;lt;td style = &amp;quot;width: 20%&amp;quot;&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
             &amp;lt;td style = &amp;quot;width: 20%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;td style = &amp;quot;width: 25%&amp;quot;&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;td style = &amp;quot;width: 15%&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;input id = &amp;quot;ButtonCancel&amp;quot; class = &amp;quot;FormButton&amp;quot; name = &amp;quot;ButtonCancel&amp;quot; type = &amp;quot;button&amp;quot; value = &amp;quot;Cancel&amp;quot;&amp;gt; &amp;lt;/td&amp;gt;&lt;br /&gt;
             &amp;lt;td style = &amp;quot;width: 15%&amp;quot;&amp;gt; &amp;lt;input id = &amp;quot;ButtonOK&amp;quot; class = &amp;quot;FormButton&amp;quot; name = &amp;quot;ButtonOK&amp;quot; type = &amp;quot;button&amp;quot; value = &amp;quot;OK&amp;quot;&amp;gt;&lt;br /&gt;
             &amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;/table&amp;gt; &amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;/table&amp;gt; &amp;lt;/body&amp;gt;  &amp;lt;/html&amp;gt;]]&lt;br /&gt;
  -- =============================================&lt;br /&gt;
  local dialog = HTML_Dialog(true, myHtml, 505, 150, Header)&lt;br /&gt;
    dialog:AddLabelField(&amp;quot;QuestionID&amp;quot;, Quest)&lt;br /&gt;
    dialog:AddTextField(&amp;quot;DInput&amp;quot;, DefaltPath )&lt;br /&gt;
    dialog:AddDirectoryPicker(&amp;quot;DirectoryPicker&amp;quot;,  &amp;quot;DInput&amp;quot;,  true)&lt;br /&gt;
    if not dialog:ShowDialog() then&lt;br /&gt;
      return &amp;quot;&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      return dialog:GetTextField(&amp;quot;DInput&amp;quot;)&lt;br /&gt;
    end -- if end&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===InquiryAreYouSureYesNo===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function InquiryAreYouSureYesNo(Header, Question1, Question2)&lt;br /&gt;
 --[[&lt;br /&gt;
     Drop list for user to input project info&lt;br /&gt;
     Caller = local y = InquiryAreYouSureYesNo(&amp;quot;Pie Question&amp;quot;, &amp;quot;Do you want free pie&amp;quot;)&lt;br /&gt;
     Dialog Header = &amp;quot;Pie Question&amp;quot;&lt;br /&gt;
     User Question1 = &amp;quot;Do you want a Free Pie&amp;quot;&lt;br /&gt;
     User Question2 = &amp;quot;You only get one&amp;quot;&lt;br /&gt;
     Returns = true / false&lt;br /&gt;
   ]]&lt;br /&gt;
    local myHtml = [[ &amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Yes or No Question&amp;lt;/title&amp;gt;]] .. DialogWindow.Style ..[[&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; class=&amp;quot;h2-lw&amp;quot; id=&amp;quot;Question1&amp;quot;&amp;gt;Question1&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; class=&amp;quot;h2-lw&amp;quot; id=&amp;quot;Question2&amp;quot;&amp;gt;Question2&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;h2-l&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot; class=&amp;quot;h2-l&amp;quot;&amp;gt;Are you sure?&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;h2-l&amp;quot;&amp;gt;&amp;amp;nbsp;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;3&amp;quot;&amp;gt;&amp;lt;h2&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/h2&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
   &amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;h1-l&amp;quot;&amp;gt;&amp;lt;input id=&amp;quot;ButtonOK&amp;quot; class=&amp;quot;FormButton FormBut&amp;quot; name=&amp;quot;ButtonOK&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;  Yes  &amp;quot;&amp;gt; &amp;lt;/td&amp;gt; &amp;lt;td class=&amp;quot;h1-r&amp;quot;&amp;gt; &amp;lt;input id=&amp;quot;ButtonCancel&amp;quot; class=&amp;quot;FormButton FormBut&amp;quot; name=&amp;quot;ButtonCancel&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;  No  &amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;]]&lt;br /&gt;
-- =========================================================&lt;br /&gt;
    local dialog = HTML_Dialog(true, myHtml, 440, 218, Header)&lt;br /&gt;
    dialog:AddLabelField(&amp;quot;Question1&amp;quot;, Question1)&lt;br /&gt;
    dialog:AddLabelField(&amp;quot;Question2&amp;quot;, Question2)&lt;br /&gt;
    if not dialog:ShowDialog() then&lt;br /&gt;
      return false&lt;br /&gt;
    else&lt;br /&gt;
      return true&lt;br /&gt;
    end&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===InquiryDoubleBox===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function InquiryDoubleBox(Header, Quest, DefaltN)&lt;br /&gt;
--[[&lt;br /&gt;
-- nquiryNumberBox for user input with default number value&lt;br /&gt;
-- Caller: local x = InquiryNumberBox(&amp;quot;Cabinet Maker&amp;quot;, &amp;quot;Enter the cabinet height&amp;quot;, 30.0)&lt;br /&gt;
-- Dialog Header: &amp;quot;Cabinet Maker&amp;quot;&lt;br /&gt;
-- User Question: &amp;quot;Enter the cabinet height&amp;quot;&lt;br /&gt;
-- Default value = 30.0&lt;br /&gt;
-- Returns = double&lt;br /&gt;
]]&lt;br /&gt;
   local myHtml = [[&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Get Double Value&amp;lt;/title&amp;gt;&amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;html{overflow:hidden}body{background-color:#ebebeb;overflow:hidden;font-family:Arial,Helvetica,sans-serif;font-size:12px;text:#000}.h1-l{font-family:Arial,Helvetica,sans-serif;font-size:12px;font-weight:700;text-align:left;white-space:nowrap}.h1-r{font-family:Arial,Helvetica,sans-serif;font-size:12px;font-weight:700;text-align:right;white-space:nowrap}.h1-c{font-family:Arial,Helvetica,sans-serif;font-size:12px;font-weight:700;text-align:center;white-space:nowrap}table{width:100%;border:0;cellpadding:0}.FilePicker{font-weight:700;font-family:Arial,Helvetica,sans-serif;font-size:12px;width:50px}.FormButton{font-weight:700;width:65px;font-family:Arial,Helvetica,sans-serif;font-size:12px}&amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td id=&amp;quot;QuestionID&amp;quot; class=&amp;quot;h1-r&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Message Here&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;NumberInput&amp;quot; size=&amp;quot;5&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;2&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr class=&amp;quot;h1-c&amp;quot;&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input id=&amp;quot;ButtonCancel&amp;quot; class=&amp;quot;FormButton&amp;quot; name=&amp;quot;ButtonCancel&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;Cancel&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input id=&amp;quot;ButtonOK&amp;quot; class=&amp;quot;FormButton&amp;quot; name=&amp;quot;ButtonOK&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;OK&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;]]&lt;br /&gt;
   local dialog = HTML_Dialog(true, myHtml, 260, 125, Header)&lt;br /&gt;
   dialog:AddLabelField(&amp;quot;QuestionID&amp;quot;, Quest) ;&lt;br /&gt;
   dialog:AddDoubleField(&amp;quot;NumberInput&amp;quot;, DefaltN) ;&lt;br /&gt;
  if not dialog:ShowDialog() then&lt;br /&gt;
    return -1&lt;br /&gt;
  else&lt;br /&gt;
    return dialog:GetDoubleField(&amp;quot;NumberInput&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===InquiryIntegerBox===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function InquiryIntegerBox(Header, Quest, DefaltI)&lt;br /&gt;
--[[&lt;br /&gt;
-- InquiryIntegerBox for user input with default number value&lt;br /&gt;
-- Caller: local x = InquiryIntegerBox(&amp;quot;Cabinet Maker&amp;quot;, &amp;quot;Enter the door count&amp;quot;, 4)&lt;br /&gt;
-- Dialog Header: &amp;quot;Cabinet Maker&amp;quot;&lt;br /&gt;
-- User Question: &amp;quot;Enter the door count&amp;quot;&lt;br /&gt;
-- Default value = 4&lt;br /&gt;
-- Returns = integer&lt;br /&gt;
]]&lt;br /&gt;
   local myHtml = [[&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Get Integer&amp;lt;/title&amp;gt;&amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;html{overflow:auto}body{background-color:#ebebeb}table{width:100%;border:0}body,td,th{font-family:Arial,Helvetica,sans-serif;font-size:12px;color:#000}.FormButton{font-weight:700;width:85px;font-family:Arial,Helvetica,sans-serif;font-size:12px}body{background-color:#ebebeb;text:#000}&amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td id=&amp;quot;QuestionID&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Message Here&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;IntegerInput&amp;quot; size=&amp;quot;10&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;2&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input id=&amp;quot;ButtonCancel&amp;quot; class=&amp;quot;FormButton&amp;quot; name=&amp;quot;ButtonCancel&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;Cancel&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input id=&amp;quot;ButtonOK&amp;quot; class=&amp;quot;FormButton&amp;quot; name=&amp;quot;ButtonOK&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;OK&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;]]&lt;br /&gt;
   local dialog = HTML_Dialog(true, myHtml, 505, 140, Header)&lt;br /&gt;
   dialog:AddLabelField(&amp;quot;QuestionID&amp;quot;, Quest)&lt;br /&gt;
   dialog:AddIntegerField(&amp;quot;IntegerInput&amp;quot;, DefaltI)&lt;br /&gt;
  if not dialog:ShowDialog() then&lt;br /&gt;
    return -1&lt;br /&gt;
  else&lt;br /&gt;
    return dialog:GetIntegerField(&amp;quot;IntegerInput&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===InquiryTextgBox===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function InquiryTextgBox(Header, Quest, DefaltS)&lt;br /&gt;
--[[&lt;br /&gt;
-- InquiryStringBox for user input with default number value&lt;br /&gt;
-- Caller: local x = InquiryTextgBox(&amp;quot;Cabinet Maker&amp;quot;, &amp;quot;Enter the cabinet Name&amp;quot;, &amp;quot;Jim&amp;quot;)&lt;br /&gt;
-- Dialog Header: &amp;quot;Cabinet Maker&amp;quot;&lt;br /&gt;
-- User Question: &amp;quot;Enter the cabinet Name&amp;quot;&lt;br /&gt;
-- Default value = Jim&lt;br /&gt;
-- Returns = string&lt;br /&gt;
]]&lt;br /&gt;
   local myHtml = [[&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Get Number&amp;lt;/title&amp;gt;&amp;lt;style type=&amp;quot;text/css&amp;quot;&amp;gt;html{overflow:auto}body{background-color:#ebebeb}table{width:100%;border:0}body,td,th{font-family:Arial,Helvetica,sans-serif;font-size:12px;color:#000}.FormButton{font-weight:700;width:85px;font-family:Arial,Helvetica,sans-serif;font-size:12px}body{background-color:#ebebeb;text:#000}&amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td id=&amp;quot;QuestionID&amp;quot;&amp;gt;&amp;lt;strong&amp;gt;Message Here&amp;lt;/strong&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;text&amp;quot; id=&amp;quot;StringInput&amp;quot; size=&amp;quot;10&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;2&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input id=&amp;quot;ButtonCancel&amp;quot; class=&amp;quot;FormButton&amp;quot; name=&amp;quot;ButtonCancel&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;Cancel&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input id=&amp;quot;ButtonOK&amp;quot; class=&amp;quot;FormButton&amp;quot; name=&amp;quot;ButtonOK&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;OK&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;]]&lt;br /&gt;
   local dialog = HTML_Dialog(true, myHtml, 505, 140, Header)&lt;br /&gt;
   dialog:AddLabelField(&amp;quot;QuestionID&amp;quot;, Quest)&lt;br /&gt;
   dialog:AddTextField(&amp;quot;StringInput&amp;quot;, DefaltS)&lt;br /&gt;
  if not dialog:ShowDialog() then&lt;br /&gt;
    return -1&lt;br /&gt;
  else&lt;br /&gt;
    return dialog:GetTextField(&amp;quot;NumberInput&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===OnLuaButton_InquiryError===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function OnLuaButton_InquiryError(Message)&lt;br /&gt;
    --[[&lt;br /&gt;
     Provides user information on an Error&lt;br /&gt;
     Caller = local ItWorked = OnLuaButton_InquiryError(&amp;quot;No number found&amp;quot;)&lt;br /&gt;
     Dialog Header = &amp;quot;Something Error&amp;quot;&lt;br /&gt;
     User Message = &amp;quot;No Number etc...&amp;quot;&lt;br /&gt;
     Returns = True&lt;br /&gt;
   ]]&lt;br /&gt;
  local myHtml = [[&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Error&amp;lt;/title&amp;gt;&amp;lt;style type = &amp;quot;text/css&amp;quot;&amp;gt;.FormButton{font-weight:bold;width:75px;font-family:Arial,Helvetica,sans-serif;font-size:12px;white-space:nowrap}.Error{font-family:Arial,Helvetica,sans-serif;font-size:18px;font-weight:bold;color:#F00;text-align:left;white-space:nowrap;padding-right:4px;padding-left:10px;padding-top:4px;padding-bottom:4px}.ErrorMessage{font-family:Arial,Helvetica,sans-serif;font-size:12px;color:#000;font-weight:bold;text-align:left;white-space:nowrap;padding-right:4px;padding-left:10px;padding-top:4px;padding-bottom:4px}.ErrorTable{background-color:#FFF white-space:nowrap}html{overflow:hidden}&amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body text = &amp;quot;#000000&amp;quot;&amp;gt;&amp;lt;table width=&amp;quot;100%&amp;quot; border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;0&amp;quot; class=&amp;quot;ErrorTable&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;th align=&amp;quot;center&amp;quot; nowrap=&amp;quot;nowrap&amp;quot; class=&amp;quot;Error&amp;quot;&amp;gt;Error!&amp;lt;/th&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td id=&amp;quot;ErrorMessage&amp;quot;&amp;gt;&amp;lt;label class=&amp;quot;ErrorMessage&amp;quot;&amp;gt;-&amp;lt;/label&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td width=&amp;quot;30%&amp;quot; align=&amp;quot;right&amp;quot; style = &amp;quot;width: 15%&amp;quot;&amp;gt;&amp;lt;input id = &amp;quot;ButtonOK&amp;quot; class = &amp;quot;FormButton&amp;quot; name = &amp;quot;ButtonOK&amp;quot; type = &amp;quot;button&amp;quot; value = &amp;quot;Exit&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;]]&lt;br /&gt;
  local dialogWide =  (#Message + 300)&lt;br /&gt;
  local dialog = HTML_Dialog(true, myHtml, 250, dialogWide, &amp;quot;Gadget Error&amp;quot;)&lt;br /&gt;
  dialog:AddLabelField(&amp;quot;ErrorMessage&amp;quot;,   Message)&lt;br /&gt;
  dialog:ShowDialog()&lt;br /&gt;
  Dovetail.InquiryErrorX = Dialog.WindowWidth&lt;br /&gt;
  Dovetail.InquiryErrorY = Dialog.WindowHeight&lt;br /&gt;
  WriteRegistry()&lt;br /&gt;
  return  true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===PresentMessage===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function PresentMessage(Header, Type, Line)&lt;br /&gt;
    --[[&lt;br /&gt;
     Provides user information on an Error&lt;br /&gt;
     Caller = local ItWorked = OnLuaButton_InquiryError(&amp;quot;No number found&amp;quot;)&lt;br /&gt;
     Dialog Header = &amp;quot;Something Error&amp;quot;&lt;br /&gt;
     User Message = &amp;quot;No Number etc...&amp;quot;&lt;br /&gt;
     Returns = True&lt;br /&gt;
   ]]&lt;br /&gt;
  local myHtml = [[&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Error&amp;lt;/title&amp;gt;]] .. DialogWindow.Style ..[[&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&lt;br /&gt;
  &amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;th valign=&amp;quot;top&amp;quot; id=&amp;quot;MessageType&amp;quot; class=&amp;quot;Error&amp;quot;&amp;gt;-&amp;lt;/th&amp;gt;&amp;lt;td id=&amp;quot;MessageLine&amp;quot;&amp;gt;&amp;lt;label class=&amp;quot;ErrorMessage&amp;quot;&amp;gt;-&amp;lt;/label&amp;gt;&amp;lt;td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td align=&amp;quot;right&amp;quot;&amp;gt;&amp;lt;input id = &amp;quot;ButtonOK&amp;quot; class = &amp;quot;FormButton&amp;quot; name = &amp;quot;ButtonOK&amp;quot; type = &amp;quot;button&amp;quot; value = &amp;quot;OK&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;]]&lt;br /&gt;
  local dialog = HTML_Dialog(true, myHtml, 500, 150, Header)&lt;br /&gt;
  dialog:AddLabelField(&amp;quot;MessageType&amp;quot;, Type .. &amp;quot;: &amp;quot;)&lt;br /&gt;
  dialog:AddLabelField(&amp;quot;MessageLine&amp;quot;, Line)&lt;br /&gt;
  dialog:ShowDialog()&lt;br /&gt;
  return  true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===OnLuaButton_InquiryAbout===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function OnLuaButton_InquiryAbout()&lt;br /&gt;
local myHtml = [[&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;About&amp;lt;/title&amp;gt;]] .. DialogWindow.Style ..[[&amp;lt;/head&amp;gt;&amp;lt;body text = &amp;quot;#000000&amp;quot;&amp;gt;&amp;lt;table width=&amp;quot;680&amp;quot; border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;0&amp;quot;&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td align=&amp;quot;center&amp;quot; nowrap=&amp;quot;nowrap&amp;quot; class=&amp;quot;header1-c&amp;quot; id=&amp;quot;SysName&amp;quot;&amp;gt;Easy Cabinet Maker&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td align=&amp;quot;center&amp;quot; nowrap=&amp;quot;nowrap&amp;quot; id=&amp;quot;Version&amp;quot; class=&amp;quot;ver-c&amp;quot;&amp;gt;Version&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td align=&amp;quot;center&amp;quot; nowrap=&amp;quot;nowrap&amp;quot;&amp;gt;&amp;lt;hr&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td align=&amp;quot;center&amp;quot; nowrap=&amp;quot;nowrap&amp;quot; class=&amp;quot;header2-c&amp;quot;&amp;gt;Disclaimer&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td align=&amp;quot;center&amp;quot; class=&amp;quot;p1-l&amp;quot;&amp;gt;&amp;lt;p class=&amp;quot;p1-l&amp;quot;&amp;gt;The ]] .. Dovetail.AppName .. [[ Gadget is a plugin for Vectric software, V-Carve Pro and Aspire.&amp;lt;br&amp;gt; Gadgets are an entirely optional add-in to Vectric's core software products.&amp;lt;br&amp;gt; They are provided 'as-is', without any express or implied warranty, and you make use of them entirely at your own risk.&amp;lt;br&amp;gt; In no event will the author(s) or Vectric Ltd. be held liable for any damages arising from their use.&amp;lt;br&amp;gt; &amp;lt;br&amp;gt; Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:&amp;lt;br&amp;gt; 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.&amp;lt;br&amp;gt; * If you use this software in a product, an acknowledgement in the product documentation would be appreciated but is not required.&amp;lt;br&amp;gt; 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.&amp;lt;br&amp;gt; 3. This notice may not be removed or altered from any source distribution.&amp;lt;br&amp;gt; &amp;lt;br&amp;gt;The author heavily utilized the SDK documentation and supplied code samples in addition to the outstanding user community on the Vectric User forum.&amp;lt;/p&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;https://forum.vectric.com&amp;quot; class=&amp;quot;webLink-c&amp;quot;&amp;gt;Vectric User Forum&amp;lt;/a&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;header2-c&amp;quot;&amp;gt;JimAndi&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td align=&amp;quot;center&amp;quot;&amp;gt;&amp;lt;span class=&amp;quot;h1-c&amp;quot;&amp;gt;Houston, TX.&amp;lt;/span&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td&amp;gt;&amp;lt;hr&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt; &amp;lt;tr&amp;gt; &amp;lt;td width=&amp;quot;30%&amp;quot; align=&amp;quot;center&amp;quot; style = &amp;quot;width: 15%&amp;quot;&amp;gt;&amp;lt;input id = &amp;quot;ButtonOK&amp;quot; class = &amp;quot;FormButton&amp;quot; name = &amp;quot;ButtonOK&amp;quot; type = &amp;quot;button&amp;quot; value = &amp;quot;OK&amp;quot;&amp;gt;&amp;lt;/td&amp;gt; &amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;]]&lt;br /&gt;
  local dialog = HTML_Dialog(true, myHtml, 720, 468, &amp;quot;About&amp;quot;)&lt;br /&gt;
  dialog:AddLabelField(&amp;quot;SysName&amp;quot;, Project.ProgramName)&lt;br /&gt;
  dialog:AddLabelField(&amp;quot;Version&amp;quot;, &amp;quot;Version: &amp;quot; .. Project.ProgramVersion)&lt;br /&gt;
  dialog:ShowDialog()&lt;br /&gt;
  Project.AboutXY = tostring(dialog.WindowWidth) .. &amp;quot; x &amp;quot; .. tostring(dialog.WindowHeight)&lt;br /&gt;
  return  true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Color_HTML ===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function Color_HTML ()&lt;br /&gt;
  MessageBox(&amp;quot; X = &amp;quot; .. tostring(dialog.WindowWidth) ..&lt;br /&gt;
             &amp;quot; Y = &amp;quot; .. tostring(dialog.WindowHeight)&lt;br /&gt;
 )&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
--[[ -- begin HTML for Layer Color&lt;br /&gt;
&amp;lt;table&amp;gt;&lt;br /&gt;
  &amp;lt;tr&amp;gt;&lt;br /&gt;
    &amp;lt;td width=&amp;quot;200&amp;quot; align=&amp;quot;right&amp;quot; valign=&amp;quot;middle&amp;quot; nowrap class=&amp;quot;h1-rp&amp;quot;&amp;gt;Layer Name&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td width=&amp;quot;300&amp;quot; align=&amp;quot;right&amp;quot; valign=&amp;quot;middle&amp;quot; nowrap class=&amp;quot;h1-l&amp;quot; id=&amp;quot;ValueTable&amp;quot;&amp;gt;&lt;br /&gt;
      &amp;lt;input name=&amp;quot;Panel.PinHole&amp;quot; type=&amp;quot;text&amp;quot; class=&amp;quot;h1-l&amp;quot; id=&amp;quot;Panel.PinHole&amp;quot; size=&amp;quot;50&amp;quot; maxlength=&amp;quot;50&amp;quot;/&amp;gt;&lt;br /&gt;
      &amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td width=&amp;quot;150&amp;quot;align=&amp;quot;right&amp;quot; valign=&amp;quot;middle&amp;quot; nowrap class=&amp;quot;h1-l&amp;quot;&amp;gt;&amp;lt;label for=&amp;quot;Panel.LineColor01&amp;quot;&amp;gt;Color&amp;lt;/label&amp;gt;&lt;br /&gt;
      &amp;lt;select name=&amp;quot;Panel.LineColor01&amp;quot; id=&amp;quot;Panel.LineColor01&amp;quot;&amp;gt;&lt;br /&gt;
        &amp;lt;option selected=&amp;quot;selected&amp;quot;&amp;gt;Black&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Blue&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Brown&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Cyan&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Gray&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Green&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Lime&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Magenta&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Maroon&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Navy&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Olive&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Orange&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Purple&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Red&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Silver&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Teal&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;White&amp;lt;/option&amp;gt;&lt;br /&gt;
        &amp;lt;option&amp;gt;Yellow&amp;lt;/option&amp;gt;&lt;br /&gt;
    &amp;lt;/select&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
  &amp;lt;/tr&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
&amp;lt;table width=&amp;quot;101%&amp;quot; border=&amp;quot;0&amp;quot; id=&amp;quot;ButtonTable&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/table&amp;gt;&lt;br /&gt;
]] -- end HTML&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Style===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function Style()&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
DialogWindow.Style = [[ &amp;lt;style&amp;gt;&lt;br /&gt;
.DirectoryPicker {&lt;br /&gt;
  font-weight: bold;&lt;br /&gt;
  font-size: 12px;&lt;br /&gt;
  white-space: nowrap;&lt;br /&gt;
  background-color: #663300;&lt;br /&gt;
  color: #FFFFFF;&lt;br /&gt;
}&lt;br /&gt;
.FormButton {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	width: 75px;&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	background-color: #663300;&lt;br /&gt;
	color: #FFFFFF;&lt;br /&gt;
}&lt;br /&gt;
.FormButton-Help {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	width: 75px;&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	background-color: #663300;&lt;br /&gt;
	color: #FFFFFF;&lt;br /&gt;
	padding-left: 10;&lt;br /&gt;
	padding-right: 10;&lt;br /&gt;
}&lt;br /&gt;
.LuaButton {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	background-color: #663300;&lt;br /&gt;
	color: #FFFFFF;&lt;br /&gt;
}&lt;br /&gt;
.ToolNameLabel {&lt;br /&gt;
	font-weight: bolder;&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	text-align: left;&lt;br /&gt;
	color: #000;&lt;br /&gt;
	width: 70%;&lt;br /&gt;
}&lt;br /&gt;
.ToolPicker {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	width: 50px;&lt;br /&gt;
	background-color: #663300;&lt;br /&gt;
	color: #FFFFFF;&lt;br /&gt;
}&lt;br /&gt;
.alert-c {&lt;br /&gt;
	font-size: 14px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.alert-l {&lt;br /&gt;
	font-size: 14px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-shadow: 5px 5px 10px #FFF;&lt;br /&gt;
	text-align: left;&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.alert-r {&lt;br /&gt;
	font-size: 14px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: right;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.error {&lt;br /&gt;
	font-size: 18px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	color: #FF0000;&lt;br /&gt;
	text-align: left;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	padding-right: 4px;&lt;br /&gt;
	padding-left: 10px;&lt;br /&gt;
	padding-top: 4px;&lt;br /&gt;
	padding-bottom: 4px;&lt;br /&gt;
}&lt;br /&gt;
.errorMessage {&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	color: #000;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: left;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	padding-right: 4px;&lt;br /&gt;
	padding-left: 10px;&lt;br /&gt;
	padding-top: 4px;&lt;br /&gt;
	padding-bottom: 4px;&lt;br /&gt;
}&lt;br /&gt;
.errorTable {&lt;br /&gt;
	background-color: #FFFFFF;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.p1-l {&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	text-align: left;&lt;br /&gt;
}&lt;br /&gt;
.h1-c {&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.h1-cOk {&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	width: 15%;&lt;br /&gt;
}&lt;br /&gt;
.h1-l {&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: left;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.h1-r {&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: right;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.h1-rP {&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: right;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	padding-right: 4px;&lt;br /&gt;
	padding-left: 4px;&lt;br /&gt;
}&lt;br /&gt;
.h1-rPx {&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: right;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	padding-right: 8px;&lt;br /&gt;
	padding-left: 8px;&lt;br /&gt;
}&lt;br /&gt;
.h2-c {&lt;br /&gt;
	font-size: 14px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	text-shadow: 2px 2px white;&lt;br /&gt;
}&lt;br /&gt;
.h2-l {&lt;br /&gt;
	font-size: 14px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	color: #663300;&lt;br /&gt;
	text-align: left;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	text-shadow: 2px 2px white;&lt;br /&gt;
}&lt;br /&gt;
.h2-r {&lt;br /&gt;
	font-size: 14px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	color: #663300;&lt;br /&gt;
	text-align: right;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	text-shadow: 2px 2px white;&lt;br /&gt;
}&lt;br /&gt;
.h3-bc {&lt;br /&gt;
	font-size: 16px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.h3-c {&lt;br /&gt;
	font-size: 16px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.h3-l {&lt;br /&gt;
	font-size: 16px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: left;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.h3-r {&lt;br /&gt;
	font-size: 16px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: right;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.h4-c {&lt;br /&gt;
	font-size: 18px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.h4-l {&lt;br /&gt;
	font-size: 18px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: left;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.h4-r {&lt;br /&gt;
	font-size: 18px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: right;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
.help_But {&lt;br /&gt;
	width: 45px;&lt;br /&gt;
}&lt;br /&gt;
.MyCenter{&lt;br /&gt;
	text-align:center;&lt;br /&gt;
	width:10;&lt;br /&gt;
}&lt;br /&gt;
.MyLeft{&lt;br /&gt;
	text-align:left;&lt;br /&gt;
	width:10;&lt;br /&gt;
}&lt;br /&gt;
.MyRight{&lt;br /&gt;
	text-align:right;&lt;br /&gt;
	width:10;&lt;br /&gt;
}&lt;br /&gt;
.helplabel-r {&lt;br /&gt;
	cursor: pointer;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	text-align: right;&lt;br /&gt;
}&lt;br /&gt;
.helplabel-rp {&lt;br /&gt;
	cursor: pointer;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	text-align: right;&lt;br /&gt;
	padding-right: 8px;&lt;br /&gt;
}&lt;br /&gt;
.jsTag-no-vis {&lt;br /&gt;
	font-size: 10px;&lt;br /&gt;
	display: none;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	color: #00F;&lt;br /&gt;
	visibility: hidden;&lt;br /&gt;
}&lt;br /&gt;
.jsbutton {&lt;br /&gt;
	background-color: #663300;&lt;br /&gt;
	border: 2px solid #999;&lt;br /&gt;
	border-right-color: #000;&lt;br /&gt;
	border-bottom-color: #000;&lt;br /&gt;
	border-top-color: #FFF;&lt;br /&gt;
	border-left-color: #FFF;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	text-decoration: none;&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	margin: 1px 1px;&lt;br /&gt;
	color: #FFFFFF;&lt;br /&gt;
}&lt;br /&gt;
.p1-c {&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
}&lt;br /&gt;
.p1-r {&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	text-align: right;&lt;br /&gt;
}&lt;br /&gt;
.ver-c {&lt;br /&gt;
	font-size: 10px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	color: #ffd9b3;&lt;br /&gt;
}&lt;br /&gt;
.webLink-c {&lt;br /&gt;
	font-size: 16px;&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	background-color: yellow;&lt;br /&gt;
	text-align: center;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
}&lt;br /&gt;
body {&lt;br /&gt;
	background-color: #3a4660;&lt;br /&gt;
	background-position: center;&lt;br /&gt;
	overflow: hidden;&lt;br /&gt;
	font-family: arial, helvetica, sans-serif;&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	color: #FFFFFF;&lt;br /&gt;
	background-image: url(]].. DialogWindow.myBackGround ..[[);&lt;br /&gt;
}&lt;br /&gt;
html {&lt;br /&gt;
	overflow: hidden&lt;br /&gt;
}&lt;br /&gt;
table {&lt;br /&gt;
	width: 100%;&lt;br /&gt;
	border: 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/style&amp;gt;]]&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Orgin===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function Orgin()                                       -- Anchor Point&lt;br /&gt;
-- ================================&lt;br /&gt;
  DialogWindow.Orgin = [[&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td colspan=&amp;quot;2&amp;quot; class=&amp;quot;h2-l&amp;quot;&amp;gt;Anchor Point&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr class=&amp;quot;MyLeft&amp;quot;&amp;gt;&amp;lt;td class=&amp;quot;MyLeft&amp;quot;&amp;gt;&amp;lt;table class=&amp;quot;MyCenter&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;DrawingOrigin&amp;quot; checked=&amp;quot;checked&amp;quot; value=&amp;quot;V1&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;hr&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;DrawingOrigin&amp;quot; checked=&amp;quot;checked&amp;quot; value=&amp;quot;V2&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;auto-style9&amp;quot;&amp;gt;|&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;DrawingOrigin&amp;quot; checked=&amp;quot;checked&amp;quot; value=&amp;quot;V3&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;|&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;DrawingOrigin&amp;quot; checked=&amp;quot;checked&amp;quot; value=&amp;quot;V4&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;hr&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td valign=&amp;quot;top&amp;quot;&amp;gt;&amp;lt;input type=&amp;quot;radio&amp;quot; name=&amp;quot;DrawingOrigin&amp;quot; checked=&amp;quot;checked&amp;quot; value=&amp;quot;V5&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;td width=&amp;quot;81%&amp;quot;&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr class=&amp;quot;MyLeft&amp;quot;&amp;gt;&amp;lt;td&amp;gt;X&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input name=&amp;quot;OriginX0&amp;quot; type=&amp;quot;text&amp;quot; id=&amp;quot;OriginX&amp;quot; size=&amp;quot;8&amp;quot; maxlength=&amp;quot;8&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr class=&amp;quot;MyLeft&amp;quot;&amp;gt;&amp;lt;td&amp;gt;Y&amp;lt;/td&amp;gt;&amp;lt;td&amp;gt;&amp;lt;input name=&amp;quot;OriginY0&amp;quot; type=&amp;quot;text&amp;quot; id=&amp;quot;OriginY&amp;quot; size=&amp;quot;8&amp;quot; maxlength=&amp;quot;8&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;]]&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===GetColor===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function GetColor(str)                                  -- returns the RGB value for the standard color names&lt;br /&gt;
-- str = &amp;quot;Purple&amp;quot;&lt;br /&gt;
-- returns = 128 0 128&lt;br /&gt;
    local Colors = {}&lt;br /&gt;
    Colors.Black  = &amp;quot;0,0,0&amp;quot;;       Colors.White  = &amp;quot;255,255,255&amp;quot;; Colors.Red    = &amp;quot;255,0,0&amp;quot;&lt;br /&gt;
    Colors.Lime   = &amp;quot;0,255,0&amp;quot;;     Colors.Blue   = &amp;quot;0,0,255&amp;quot;;     Colors.Yellow = &amp;quot;255,255,0&amp;quot;&lt;br /&gt;
    Colors.Cyan   = &amp;quot;0,255,255&amp;quot;;   Colors.Magenta = &amp;quot;255,0,255&amp;quot;;  Colors.Silver = &amp;quot;192,192,192&amp;quot;&lt;br /&gt;
    Colors.Gray   = &amp;quot;128,128,128&amp;quot;; Colors.Maroon = &amp;quot;128,0,0&amp;quot;;     Colors.Olive  = &amp;quot;128,128,0&amp;quot;&lt;br /&gt;
    Colors.Green  = &amp;quot;0,128,0&amp;quot;;     Colors.Purple = &amp;quot;128,0,128&amp;quot;;   Colors.Teal   = &amp;quot;0,128,128&amp;quot;&lt;br /&gt;
    Colors.Navy   = &amp;quot;0,0,128&amp;quot;&lt;br /&gt;
    local Red, Green, Blue = 0&lt;br /&gt;
    if &amp;quot;&amp;quot; == str then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error: Empty string passed&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      str = Colors[str]&lt;br /&gt;
      if &amp;quot;string&amp;quot; == type(str) then&lt;br /&gt;
        if string.find(str, &amp;quot;,&amp;quot;) then&lt;br /&gt;
          Red  = tonumber(string.sub(str, 1, assert(string.find(str, &amp;quot;,&amp;quot;) - 1)))&lt;br /&gt;
          str = string.sub(str, assert(string.find(str, &amp;quot;,&amp;quot;) + 1))&lt;br /&gt;
          Green = tonumber(string.sub(str, 1, assert(string.find(str, &amp;quot;,&amp;quot;) - 1)))&lt;br /&gt;
          Blue = tonumber(string.sub(str, assert(string.find(str, &amp;quot;,&amp;quot;) + 1)))&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        DisplayMessageBox(&amp;quot;Error: Color Not Found&amp;quot;)&lt;br /&gt;
        Red = 0&lt;br /&gt;
        Green = 0&lt;br /&gt;
        Blue = 0&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    return Red, Green, Blue&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===StatusMessage===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y vaalues.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function StatusMessage(Type, Header, Question, length) -- Standardize messaging dialogues&lt;br /&gt;
  -- StatusMessage(&amp;quot;Alert&amp;quot;,    &amp;quot;Alert Test&amp;quot;,     &amp;quot;This is a test of Alert&amp;quot;,    165)&lt;br /&gt;
  -- StatusMessage(&amp;quot;Question&amp;quot;, &amp;quot;Question Test&amp;quot;,  &amp;quot;This is a test of Question&amp;quot;, 165)&lt;br /&gt;
  -- StatusMessage(&amp;quot;Tick&amp;quot;,     &amp;quot;Tick Test&amp;quot;,      &amp;quot;This is a test of Tick&amp;quot;,     165)&lt;br /&gt;
  -- StatusMessage(&amp;quot;Minus&amp;quot;,    &amp;quot;Minus Test&amp;quot;,     &amp;quot;This is a test of Minus&amp;quot;,    165)&lt;br /&gt;
  -- StatusMessage(&amp;quot;Error&amp;quot;,    &amp;quot;Error Test&amp;quot;,     &amp;quot;This is a test of Error&amp;quot;,    165)&lt;br /&gt;
  -- StatusMessage(&amp;quot;Success&amp;quot;,  &amp;quot;Success Test&amp;quot;,   &amp;quot;This is a test of Success&amp;quot;,  165)&lt;br /&gt;
  -- StatusMessage(&amp;quot;Blank&amp;quot;,    &amp;quot;Blank Test&amp;quot;,     &amp;quot;This is a test of Blank&amp;quot;,    165)&lt;br /&gt;
  local Image = &amp;quot;&amp;quot;&lt;br /&gt;
  if     Type == &amp;quot;Alert&amp;quot; then&lt;br /&gt;
    Image = AlertImage()&lt;br /&gt;
  elseif Type == &amp;quot;Question&amp;quot; then&lt;br /&gt;
    Image = QuestionImage()&lt;br /&gt;
  elseif Type == &amp;quot;Tick&amp;quot; then&lt;br /&gt;
    Image = TickImage()&lt;br /&gt;
  elseif Type == &amp;quot;Minus&amp;quot; then&lt;br /&gt;
    Image = MinusImage()&lt;br /&gt;
  elseif Type == &amp;quot;Error&amp;quot; then&lt;br /&gt;
    Image = ErrorImage()&lt;br /&gt;
  elseif Type == &amp;quot;Success&amp;quot; then&lt;br /&gt;
    Image = SuccessImage()&lt;br /&gt;
  else -- &amp;quot;Status&amp;quot;&lt;br /&gt;
    Image = TickImage()&lt;br /&gt;
  end -- if end&lt;br /&gt;
  local help = [[&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;]] .. Header ..[[&amp;lt;/title&amp;gt;&amp;lt;style&amp;gt;&lt;br /&gt;
.FormButton {font-family: Arial, Helvetica, sans-serif;font-weight: bold;font-size: 12px;white-space: nowrap;background-color: #663300;color: #FFFFFF;width: 75px;&lt;br /&gt;
}table {width: 100%;border: 0;}.h2-lm {font-family: Arial, Helvetica, sans-serif;font-size: 14px;font-weight: bold;text-align: left;}.h2-r {font-family: Arial, Helvetica, sans-serif;font-size: 14px;font-weight: bold;text-align: right;white-space: nowrap;}.h2-l {font-family: Arial, Helvetica, sans-serif;font-size: 14px;font-weight: bold;text-align: left;white-space: nowrap;}body {background-color: #3a4660;background-position: center;overflow: hidden;font-family: arial, helvetica, sans-serif;font-size: 12px;color: #FFFFFF;background-image: url(]] .. myBackGround() .. [[);}html {overflow: hidden}&amp;lt;/style&amp;gt;&amp;lt;/head&amp;gt;&amp;lt;body&amp;gt;&amp;lt;table&amp;gt; &amp;lt;tr&amp;gt;  &amp;lt;td class=&amp;quot;h2-l&amp;quot;&amp;gt;&amp;lt;]] .. Image .. [[&amp;quot; width=&amp;quot;60&amp;quot; height=&amp;quot;60&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;td class=&amp;quot;h2-lm&amp;quot; id=&amp;quot;Question&amp;quot;&amp;gt;]] .. Question .. [[&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td colspan=2&amp;gt;&amp;lt;h2&amp;gt;&amp;lt;span&amp;gt;&amp;lt;/span&amp;gt;&amp;lt;/h2&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td class=&amp;quot;h2-r&amp;quot;&amp;gt;&amp;lt;input id=&amp;quot;ButtonOK&amp;quot; class=&amp;quot;FormButton&amp;quot; name=&amp;quot;ButtonOK&amp;quot; type=&amp;quot;button&amp;quot; value=&amp;quot;OK&amp;quot;&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;
    &amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;]]&lt;br /&gt;
  local dialog = HTML_Dialog(true, help , 550,  length, Header)&lt;br /&gt;
  dialog:ShowDialog()&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===DialogStringChecks===&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DialogStringChecks()&lt;br /&gt;
  local MyTrue = false&lt;br /&gt;
  if Milling.LNBottomProfile == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Bottom Profile layer name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryLayers()&lt;br /&gt;
  elseif  Milling.LNSideProfile  == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Side Profile layer name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryLayers()&lt;br /&gt;
  elseif  Milling.LNSidePocket  == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Side Pocket layer name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryLayers()&lt;br /&gt;
  elseif Milling.LNFrontProfile == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Front Profile layer name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryLayers()&lt;br /&gt;
  elseif Milling.LNFrontPocket  == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Front Pocket layer name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryLayers()&lt;br /&gt;
  elseif Milling.LNBackProfile  == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Back Profile layer name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryLayers()&lt;br /&gt;
  elseif Milling.LNBackPocket == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Back Pocket layer name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryLayers()&lt;br /&gt;
  elseif Milling.LNDrawNotes == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Draw Notes layer name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryLayers()&lt;br /&gt;
  elseif Milling.LNPartLabels == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Part Lables layer name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryLayers()&lt;br /&gt;
  elseif Milling.LNBlume == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Blume layer name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryLayers()&lt;br /&gt;
  elseif Project.ProjectName == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Project Name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryProjectInfo()&lt;br /&gt;
  elseif Project.ContactEmail  == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Contact Email cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryProjectInfo()&lt;br /&gt;
  elseif Project.ContactName == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Contact Name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryProjectInfo()&lt;br /&gt;
  elseif Project.ContactPhoneNumber == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Project Name cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryProjectInfo()&lt;br /&gt;
  elseif Project.DrawerID == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Contact Phone Number cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryProjectInfo()&lt;br /&gt;
  elseif Project.ProjectPath == &amp;quot;&amp;quot; then&lt;br /&gt;
    MessageBox(&amp;quot;Error: Project Path cannot be blank&amp;quot;)&lt;br /&gt;
    OnLuaButton_InquiryProjectInfo()&lt;br /&gt;
  else&lt;br /&gt;
    MyTrue = true&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return MyTrue&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Directory and File Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===MakeFolder()===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y values.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function MakeFolder(xPath)&lt;br /&gt;
    os.execute( &amp;quot;mkdir  &amp;quot; .. xPath)&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===PathFix()===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function PathFix(xPath)              -- Returns path with /&lt;br /&gt;
    return string.gsub(xPath, &amp;quot;\\&amp;quot;, &amp;quot;/&amp;quot;)&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===IsDir()===&lt;br /&gt;
&lt;br /&gt;
Validates a directory path&lt;br /&gt;
&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function IsDir(path)                     -- Returns true if path is found&lt;br /&gt;
    local function exists(file)&lt;br /&gt;
      local ok, err, code = os.rename(file, file)&lt;br /&gt;
      if not ok then&lt;br /&gt;
        if code == 13 then&lt;br /&gt;
          return true&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- if end&lt;br /&gt;
      return ok, err&lt;br /&gt;
    end -- function end&lt;br /&gt;
    return exists(path..&amp;quot;/&amp;quot;)&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===FileExists()===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns Dialog size in a message box showing the X and Y values.&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function FileExists(name)&lt;br /&gt;
-- FileExists(name&lt;br /&gt;
-- DisplayMessageBox(name)&lt;br /&gt;
    local f=io.open(name,&amp;quot;r&amp;quot;)&lt;br /&gt;
    if f~=nil then&lt;br /&gt;
      io.close(f)&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DirectoryProcessor()===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
&lt;br /&gt;
Returns number of files that were processed by an operation.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function DirectoryProcessor(job, dir_name, filter, do_sub_dirs, function_ptr)&lt;br /&gt;
      local num_files_processed = 0&lt;br /&gt;
      local directory_reader = DirectoryReader()&lt;br /&gt;
      local cur_dir_reader = DirectoryReader()&lt;br /&gt;
      directory_reader:BuildDirectoryList(dir_name, do_sub_dirs)&lt;br /&gt;
      directory_reader:SortDirs()&lt;br /&gt;
      local number_of_directories = directory_reader:NumberOfDirs()&lt;br /&gt;
      for i = 1, number_of_directories do&lt;br /&gt;
        local cur_directory = directory_reader:DirAtIndex(i)&lt;br /&gt;
         -- get contents of current directory&lt;br /&gt;
         -- dont include sub dirs, use passed filter&lt;br /&gt;
        cur_dir_reader:BuildDirectoryList(cur_directory.Name, false)&lt;br /&gt;
        cur_dir_reader:GetFiles(filter, true, false)&lt;br /&gt;
         -- call passed method for each file:&lt;br /&gt;
        local num_files_in_dir = cur_dir_reader:NumberOfFiles()&lt;br /&gt;
        for j=1, num_files_in_dir  do&lt;br /&gt;
          local file_info = cur_dir_reader:FileAtIndex(j)&lt;br /&gt;
          if not function_ptr(job, file_info.Name) then&lt;br /&gt;
            return true&lt;br /&gt;
          end -- if end&lt;br /&gt;
           num_files_processed = num_files_processed + 1&lt;br /&gt;
        end -- for end&lt;br /&gt;
        -- empty out our directory object ready for next go&lt;br /&gt;
        cur_dir_reader:ClearDirs()&lt;br /&gt;
        cur_dir_reader:ClearFiles()&lt;br /&gt;
      end -- for end&lt;br /&gt;
      return num_files_processed&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Drawing Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DrawArrowLineArrow===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws a dimension line with arrow heads and extension leaders&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawArrowLineArrow(Pt1, Ext1, Pt2, Ext2, Off, Str, Layer, scale)&lt;br /&gt;
  -- DrawArrowLineArrow(pt1, true, pt3, true, 2.5, &amp;quot;122.5&amp;quot;, &amp;quot;TestLayer&amp;quot;, 6.0) -- both&lt;br /&gt;
  -- DrawArrowLineArrow(pt1, true, pt3, false, 2.5, &amp;quot;122.5&amp;quot;, &amp;quot;TestLayer&amp;quot;, 6.0) -- first leader only&lt;br /&gt;
  -- DrawArrowLineArrow(pt1, false, pt3, true, 2.5, &amp;quot;122.5&amp;quot;, &amp;quot;TestLayer&amp;quot;, 6.0) -- second leader only&lt;br /&gt;
  -- -----------------------------------------------------]]&lt;br /&gt;
    local job = VectricJob()&lt;br /&gt;
    if not job.Exists then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error: No job loaded&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    local DimArrow1Angle = GetPolarDirection(Pt1, Pt2, Polar2D(Pt2, 0.0, 1.0))&lt;br /&gt;
    local DimArrow2Angle = DimArrow1Angle + 180.0&lt;br /&gt;
    local LederAng       = DimArrow1Angle + 90.0&lt;br /&gt;
    local LedDrop        = LederAng + 180.0&lt;br /&gt;
    local TxtCenter      =  GetDistance(Pt1, Pt2) * 0.5&lt;br /&gt;
    local ArrowLen       = 0.125 * scale&lt;br /&gt;
    local StrSet         = (string.len(Str) * ArrowLen) * 0.5&lt;br /&gt;
    local PT01A          = Polar2D(Pt1, LederAng, ArrowLen * 2.0)&lt;br /&gt;
    local PT02A          = Polar2D(PT01A, LederAng, Off)&lt;br /&gt;
    local PT03A          = Polar2D(PT02A, LederAng, ArrowLen)&lt;br /&gt;
    local PT01B          = Polar2D(Pt2, LederAng, ArrowLen * 2.0)&lt;br /&gt;
    local PT02B          = Polar2D(PT01B, LederAng, Off)&lt;br /&gt;
    local PT03B          = Polar2D(PT02B, LederAng, ArrowLen)&lt;br /&gt;
    local Apt1           = Polar2D(PT02A, DimArrow1Angle + 15.0, ArrowLen)&lt;br /&gt;
    local Apt2           = Polar2D(PT02A, DimArrow1Angle - 15.0, ArrowLen)&lt;br /&gt;
    local TxtPt1         = Polar2D(Polar2D(PT02A, DimArrow1Angle, TxtCenter), DimArrow1Angle + 90.0, ArrowLen)&lt;br /&gt;
    local TxtPt          = Polar2D(TxtPt1, DimArrow2Angle, StrSet)&lt;br /&gt;
    local ArrowHead      = (ArrowLen * 0.333)&lt;br /&gt;
    local line1          = Contour(0.0)&lt;br /&gt;
    local layer1         = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
    line1:AppendPoint(Apt1)&lt;br /&gt;
    line1:LineTo(PT02A)&lt;br /&gt;
    line1:LineTo(Apt2)&lt;br /&gt;
    line1:LineTo(Apt1)&lt;br /&gt;
    layer1:AddObject(CreateCadContour(line1), true)&lt;br /&gt;
    local Apt3 = Polar2D(PT02B, DimArrow2Angle + 15.0, ArrowLen)&lt;br /&gt;
    local Apt4 = Polar2D(PT02B, DimArrow2Angle - 15.0, ArrowLen)&lt;br /&gt;
    local line2 = Contour(0.0)&lt;br /&gt;
    local layer2 = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
    line2:AppendPoint(Apt3)&lt;br /&gt;
    line2:LineTo(PT02B)&lt;br /&gt;
    line2:LineTo(Apt4)&lt;br /&gt;
    line2:LineTo(Apt3)&lt;br /&gt;
    layer2:AddObject(CreateCadContour(line2), true)&lt;br /&gt;
    if Ext1 then&lt;br /&gt;
      local lineA = Contour(0.0)&lt;br /&gt;
      local layerA = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
      lineA:AppendPoint(PT01A)&lt;br /&gt;
      lineA:LineTo(PT03A)&lt;br /&gt;
      layerA:AddObject(CreateCadContour(lineA), true)&lt;br /&gt;
    end -- if end&lt;br /&gt;
    if Ext2 then&lt;br /&gt;
      local lineB = Contour(0.0)&lt;br /&gt;
      local layerB = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
      lineB:AppendPoint(PT01B)&lt;br /&gt;
      lineB:LineTo(PT03B)&lt;br /&gt;
      layerB:AddObject(CreateCadContour(lineB), true)&lt;br /&gt;
    end -- if end&lt;br /&gt;
    local lineC = Contour(0.0)&lt;br /&gt;
    local layerC = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
    lineC:AppendPoint(PT02A)&lt;br /&gt;
    lineC:LineTo(PT02B)&lt;br /&gt;
    layerC:AddObject(CreateCadContour(lineC), true)&lt;br /&gt;
    DrawWriter(Double2Fraction(Str), TxtPt, ArrowLen, Layer, DimArrow1Angle)&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===LayerClear===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Deletes Layer if empty.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function LayerClear(LayerName)&lt;br /&gt;
   local Mylayer = Milling.job.LayerManager:GetLayerWithName(LayerName)&lt;br /&gt;
   if Mylayer.IsEmpty then&lt;br /&gt;
     Milling.job.LayerManager:RemoveLayer(Mylayer)&lt;br /&gt;
   end -- if end&lt;br /&gt;
   return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===LeaderLine===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawLeader(Pt1, Pt2, Pt3, Str, Layer, scale)   --Draws a leader with text&lt;br /&gt;
  --[[&lt;br /&gt;
  DrawLeader(pt1, pt2, &amp;quot;122.5&amp;quot;, &amp;quot;TestLayer&amp;quot;, 6.0)&lt;br /&gt;
  --]]&lt;br /&gt;
    local job = VectricJob()&lt;br /&gt;
    if not job.Exists then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error: No job loaded&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    local ArrowLen       = 0.125 * scale&lt;br /&gt;
    local DimArrowAngle  = GetPolarDirection(Pt1, Pt2, Polar2D(Pt2, 0.0, 1.0))&lt;br /&gt;
    local TxtAngle       = GetPolarDirection(Pt2, Pt3, Polar2D(Pt3, 0.0, 1.0))&lt;br /&gt;
    local TxtPt          = Polar2D(Polar2D(Pt3, TxtAngle, ArrowLen), TxtAngle-45, H(ArrowLen))&lt;br /&gt;
    local Apt1           = Polar2D(Pt1, DimArrowAngle + 15.0, ArrowLen)&lt;br /&gt;
    local Apt2           = Polar2D(Pt1, DimArrowAngle - 15.0, ArrowLen)&lt;br /&gt;
    local ArrowHead      = ArrowLen * 0.333&lt;br /&gt;
    local line1          = Contour(0.0)&lt;br /&gt;
    local layer1         = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
    line1:AppendPoint(Pt1)&lt;br /&gt;
    line1:LineTo(Apt2) ;  line1:LineTo(Apt1) ; line1:LineTo(Pt1)&lt;br /&gt;
    layer1:AddObject(CreateCadContour(line1), true)&lt;br /&gt;
    local lineC = Contour(0.0)&lt;br /&gt;
    local layerC = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
    lineC:AppendPoint(Pt1)&lt;br /&gt;
    lineC:LineTo(Pt2)&lt;br /&gt;
    lineC:LineTo(Pt3)&lt;br /&gt;
    layerC:AddObject(CreateCadContour(lineC), true)&lt;br /&gt;
    if IsAllNumber(Str) then&lt;br /&gt;
      DrawWriter(Double2Fraction(Str), TxtPt, ArrowLen, Layer, TxtAngle)&lt;br /&gt;
    else&lt;br /&gt;
      DrawWriter(Str, TxtPt, ArrowLen, Layer, TxtAngle)&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Scale===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Provides the correct scale rate-based drawing units.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function Scale(Num)&lt;br /&gt;
   local mtl_block = MaterialBlock()&lt;br /&gt;
   if mtl_block.InMM then&lt;br /&gt;
     return Num * 25.4&lt;br /&gt;
   else&lt;br /&gt;
     return Num&lt;br /&gt;
   end&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===AssyHoler===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws Assy Holes in a stright line (Rabbet and/or Dado).&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function AssyHoler(pt1, pt2, PartName)                  -- Draws Assy Holes in a stright line&lt;br /&gt;
     local Ang1 = GetPolarDirection(pt1, pt2)&lt;br /&gt;
     local Ang2 = GetPolarDirection(pt2, pt1)&lt;br /&gt;
            pt1 = Polar2D(pt1, Ang1, Milling.AssemblyHoleStartEnd)&lt;br /&gt;
     DrawCircle(pt1, Milling.AssemblyHoleRad, Milling.LNAssemblyHole .. PartName)&lt;br /&gt;
            pt2 = Polar2D(pt2, Ang2, Milling.AssemblyHoleStartEnd)&lt;br /&gt;
     DrawCircle(pt2, Milling.AssemblyHoleRad, Milling.LNAssemblyHole .. PartName)&lt;br /&gt;
     local Dist = GetDistance(pt1, pt2)&lt;br /&gt;
     if Project.Debugger then&lt;br /&gt;
        DMark(&amp;quot;pt1&amp;quot;, pt1)&lt;br /&gt;
        DMark(&amp;quot;pt2&amp;quot;, pt2)&lt;br /&gt;
     end -- if end &lt;br /&gt;
     BaseScrew(2)&lt;br /&gt;
     Milling.AssemblyHoleSpace = ((Milling.AssemblyHoleMaxSpace + Milling.AssemblyHoleMinSpace) * 0.5)&lt;br /&gt;
     HoleCount = Round(math.floor(Dist / Milling.AssemblyHoleSpace))&lt;br /&gt;
     HoleSpacing = (Dist / HoleCount)&lt;br /&gt;
     HoleCount = (Dist / HoleSpacing)&lt;br /&gt;
     if (Dist &amp;gt; (HoleSpacing * 2.0)) then&lt;br /&gt;
     for i = HoleCount, 1, -1 do&lt;br /&gt;
       pt1 = Polar2D(pt1, Ang1, HoleSpacing)&lt;br /&gt;
       DrawCircle(pt1, Milling.AssemblyHoleRad, Milling.LNAssemblyHole .. PartName)&lt;br /&gt;
       if Project.Debugger then&lt;br /&gt;
 &amp;gt;       DMark(&amp;quot;pt1w&amp;quot;, pt1)&lt;br /&gt;
       end -- if end&lt;br /&gt;
       BaseScrew(1)&lt;br /&gt;
     end -- for end&lt;br /&gt;
   elseif (Dist &amp;gt; HoleSpacing) then&lt;br /&gt;
     ptC = Polar2D(pt1, Ang1, Dist / 2.0)&lt;br /&gt;
     if Project.Debugger then&lt;br /&gt;
       DMark(&amp;quot;ptC&amp;quot;, ptC)&lt;br /&gt;
     end -- if end&lt;br /&gt;
     DrawCircle(ptC, Milling.AssemblyHoleRad, Milling.LNAssemblyHole .. PartName)&lt;br /&gt;
   else&lt;br /&gt;
     -- Done No Holes&lt;br /&gt;
   end -- if end&lt;br /&gt;
   return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DrawBoneCenter2Pts===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws dog bone joints.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawBoneCenter2Pts(pt1, pt2, SlotWidth, BitRadius)&lt;br /&gt;
   Local Project = {}&lt;br /&gt;
   Project.job   = VectricJob()&lt;br /&gt;
   Project.ang   = GetPolarDirection(pt1, pt2)&lt;br /&gt;
   Project.dis   = H(SlotWidth)&lt;br /&gt;
   Project.bit   = math.sin(math.rad(45.0)) * BitRadius&lt;br /&gt;
   Project.ptA   = Polar2D(pt1, Project.ang +  90.0, Project.dis)&lt;br /&gt;
   Project.ptAa  = Polar2D(Project.ptA, Project.ang, Project.bit)&lt;br /&gt;
   Project.ptAb  = Polar2D(Project.ptA, Project.ang + 270.0, Project.bit)&lt;br /&gt;
   Project.ptB   = Polar2D(pt1, Project.ang + 270.0, Project.dis)&lt;br /&gt;
   Project.ptBa  = Polar2D(Project.ptB, Project.ang +  90.0, Project.bit)&lt;br /&gt;
   Project.ptBb  = Polar2D(Project.ptB, Project.ang, Project.bit)&lt;br /&gt;
   Project.ptC   = Polar2D(pt2, Project.ang + 270.0, Project.dis)&lt;br /&gt;
   Project.ptCa  = Polar2D(Project.ptC, Project.ang +  90.0, Project.bit)&lt;br /&gt;
   Project.ptCb  = Polar2D(Project.ptC, Project.ang - 180.0, Project.bit)&lt;br /&gt;
   Project.ptD   = Polar2D(pt2, Project.ang +  90.0, Project.dis)&lt;br /&gt;
   Project.ptDa  = Polar2D(Project.ptD, Project.ang - 180.0, Project.bit)&lt;br /&gt;
   Project.ptDb  = Polar2D(Project.ptD, Project.ang + 270.0, Project.bit)&lt;br /&gt;
   Project.line  = Contour(0.0)&lt;br /&gt;
   Project.layer = Project.job.LayerManager:GetLayerWithName(&amp;quot;DogBone&amp;quot;)&lt;br /&gt;
   Project.line:AppendPoint(Project.ptAa)&lt;br /&gt;
   Project.line:ArcTo(Project.ptAb, 1.0)&lt;br /&gt;
   Project.line:LineTo(Project.ptBa)&lt;br /&gt;
   Project.line:ArcTo(Project.ptBb, 1.0)&lt;br /&gt;
   Project.line:LineTo(Project.ptCb)&lt;br /&gt;
   Project.line:ArcTo(Project.ptCa, 1.0)&lt;br /&gt;
   Project.line:LineTo(Project.ptDb)&lt;br /&gt;
   Project.line:ArcTo(Project.ptDa, 1.0)&lt;br /&gt;
   Project.line:LineTo(Project.ptAa)&lt;br /&gt;
   Project.layer:AddObject(CreateCadContour(Project.line), true)&lt;br /&gt;
   return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===InsideCornerNipper===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws the nipping of a corner for easy fitting.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function InsideCornerNipper(AngPlung, BitRadius, CornerPt)&lt;br /&gt;
   local NipLength = math.sin(math.rad(45.0)) * ((BitRadius + 0.04) * 2.0)&lt;br /&gt;
   local Pt1, Pt2 = Point2D()&lt;br /&gt;
   if Material.Orientation == &amp;quot;V&amp;quot; then&lt;br /&gt;
     Pt1 = Polar2D(CornerPt, (AngPlung + 90.0) - 45.0, NipLength)&lt;br /&gt;
     Pt2 = Polar2D(CornerPt, (AngPlung + 90.0) + 45.0, NipLength)&lt;br /&gt;
   else&lt;br /&gt;
     Pt1 = Polar2D(CornerPt, (AngPlung + 180.0) - 45.0, NipLength)&lt;br /&gt;
     Pt2 = Polar2D(CornerPt, (AngPlung + 180.0) + 45.0, NipLength)&lt;br /&gt;
   end&lt;br /&gt;
   return Pt1, Pt2&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===AddGroupToJob===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Builds a Grouping from the layer selection.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function AddGroupToJob(job, group, layer_name)&lt;br /&gt;
   --[[  --------------- AddGroupToJob --------------------------------------------------|&lt;br /&gt;
   |  Add passed group to the job - returns object created&lt;br /&gt;
   |  Parameters:&lt;br /&gt;
   |     job              -- job we are working with&lt;br /&gt;
   |     group            -- group of contours to   add to document&lt;br /&gt;
   |     layer_name       -- name of layer group will be created on|&lt;br /&gt;
   |  Return Values:&lt;br /&gt;
   |     object created to represent group in document&lt;br /&gt;
   ]]&lt;br /&gt;
   --  create a CadObject to represent the  group&lt;br /&gt;
   local cad_object = CreateCadGroup(group);&lt;br /&gt;
   -- create a layer with passed name if it doesnt already exist&lt;br /&gt;
   local layer = job.LayerManager:GetLayerWithName(layer_name)&lt;br /&gt;
   -- and add our object to it&lt;br /&gt;
   layer:AddObject(cad_object, true)&lt;br /&gt;
   return cad_object&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DrawArc===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws an Arc from points provided.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawArc(PtS, PtE, ArcRadius, Layer)&lt;br /&gt;
   --[[Draw Arc&lt;br /&gt;
   function main(script_path)&lt;br /&gt;
   local MyPt1 = Point2D(3.5,3.8)&lt;br /&gt;
   local MyPt2 = Point2D(3.5,6.8)&lt;br /&gt;
   local layer = &amp;quot;My Arc&amp;quot;&lt;br /&gt;
   DrawArc(MyPt1, MyPt2, -0.456, Layer)&lt;br /&gt;
   return true&lt;br /&gt;
   end -- function end&lt;br /&gt;
   -- -----------------------------------------------------]]&lt;br /&gt;
       local job = VectricJob()&lt;br /&gt;
       if not job.Exists then&lt;br /&gt;
         DisplayMessageBox(&amp;quot;Error: No job loaded&amp;quot;)&lt;br /&gt;
         return false&lt;br /&gt;
       end&lt;br /&gt;
       local line = Contour(0.0)&lt;br /&gt;
       local layer = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
       line:AppendPoint(PtS)&lt;br /&gt;
       line:ArcTo(PtE,1);&lt;br /&gt;
       layer:AddObject(CreateCadContour(line), true)&lt;br /&gt;
       return true&lt;br /&gt;
     end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DrawEllipse===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws a DrawEllipse from points provided.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawEllipse(CenterPt, LongAxe, ShortAxe, Layer)&lt;br /&gt;
   local LongAngle = 90.0&lt;br /&gt;
   local ValueAB = (LongAxe - ShortAxe) * 0.50&lt;br /&gt;
   local ValueAC = ValueAB * math.cos(math.rad(LongAngle))&lt;br /&gt;
   local job = VectricJob()&lt;br /&gt;
   local LRad = LongAxe * 0.50&lt;br /&gt;
   local ptT = Polar2D(CenterPt, LongAngle, LRad)&lt;br /&gt;
   local X = 0.0&lt;br /&gt;
   local pty = Point2D(0.0,0.0)&lt;br /&gt;
   local ptx = Point2D(0.0,0.0)&lt;br /&gt;
   local mylayer = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
   local line = Contour(0.0)&lt;br /&gt;
         line:AppendPoint(ptT)&lt;br /&gt;
     while (X &amp;lt; 360.0) do&lt;br /&gt;
        pty = Polar2D(CenterPt, LongAngle + X, LRad)&lt;br /&gt;
    ValueAC = ValueAB * math.cos(math.rad(LongAngle + X))&lt;br /&gt;
    if ((LongAngle + X) &amp;gt;= 90.0) then&lt;br /&gt;
      ptx = Polar2D(pty, 180.0, ValueAC)&lt;br /&gt;
    else&lt;br /&gt;
      ptx = Polar2D(pty,   0.0, ValueAC)&lt;br /&gt;
    end&lt;br /&gt;
    line:LineTo(ptx)&lt;br /&gt;
    X = X + 1&lt;br /&gt;
   end -- while end&lt;br /&gt;
   line:LineTo(ptT)&lt;br /&gt;
   mylayer:AddObject(CreateCadContour(line), true)&lt;br /&gt;
   return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DrawEllipse1===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws a DrawEllipse from points provided.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawEllipse1(DrawEllipse_CenterPt, DrawEllipse_LongAxe, DrawEllipse_ShortAxe, DrawEllipse_LongAxeAngle, DrawEllipse_Layer)&lt;br /&gt;
     -- ---------------------------------------------------]]&lt;br /&gt;
     function H(x)                                         -- Returns half the value&lt;br /&gt;
       return x * 0.5&lt;br /&gt;
     end -- function end&lt;br /&gt;
     -- ---------------------------------------------------]]&lt;br /&gt;
     function Polar2D(pt, ang, dis)                        -- Calculate a new point based on reference point, angle and distance.&lt;br /&gt;
     -- Returns a 2Dpoint(x, y)&lt;br /&gt;
       return Point2D((pt.X + dis * math.cos(math.rad(ang))), (pt.Y + dis * math.sin(math.rad(ang))))&lt;br /&gt;
     end -- End Function&lt;br /&gt;
     -- ---------------------------------------------------]]&lt;br /&gt;
     function GetDistance(objA, objB)&lt;br /&gt;
       local xDist = objB.x - objA.x&lt;br /&gt;
       local yDist = objB.y - objA.y&lt;br /&gt;
       return math.sqrt((xDist ^ 2) + (yDist ^ 2))&lt;br /&gt;
     end -- function end&lt;br /&gt;
     -- ---------------------------------------------------]]&lt;br /&gt;
     function Radius2Bulge (p1, p2, Rad)&lt;br /&gt;
       local chord = math.sqrt(((p2.x - p1.x) ^ 2) + ((p2.y - p1.y) ^ 2))&lt;br /&gt;
       local seg = (Rad - (0.5 * (math.sqrt((4.0 * Rad^2) - chord^2))))&lt;br /&gt;
       local bulge = (2 * seg) / chord&lt;br /&gt;
       return bulge&lt;br /&gt;
     end -- function end&lt;br /&gt;
     -- ---------------------------------------------------]]&lt;br /&gt;
   function GetPolarAngle(Start, Corner, End)&lt;br /&gt;
     local function GetPolarDirection(point1, point2)              --&lt;br /&gt;
       local ang = math.abs(math.deg(math.atan((point2.Y - point1.Y) / (point2.X - point1.X))))&lt;br /&gt;
       if point1.X &amp;lt; point2.X then&lt;br /&gt;
         if point1.Y &amp;lt; point2.Y then&lt;br /&gt;
           ang = ang + 0.0&lt;br /&gt;
         else&lt;br /&gt;
           ang = 360.0 - ang&lt;br /&gt;
         end -- if end&lt;br /&gt;
       else&lt;br /&gt;
         if point1.Y &amp;lt; point2.Y then&lt;br /&gt;
           ang = 180.0 - ang&lt;br /&gt;
         else&lt;br /&gt;
           ang = ang + 180.0&lt;br /&gt;
         end -- if end&lt;br /&gt;
       end -- if end&lt;br /&gt;
       if ang &amp;gt;=360 then&lt;br /&gt;
         ang = ang -360.0&lt;br /&gt;
       end -- if end&lt;br /&gt;
       return ang&lt;br /&gt;
     end -- function end&lt;br /&gt;
     return  math.abs(GetPolarDirection(Corner, Start) - GetPolarDirection(Corner, End))&lt;br /&gt;
   end -- function end&lt;br /&gt;
     -- ---------------------------------------------------]]&lt;br /&gt;
 &lt;br /&gt;
     -- Call = DrawEllipse(2DPoint(20.0, 20.0), 20.0, 10.0, 0.0, &amp;quot;Jim&amp;quot;)&lt;br /&gt;
     local job = VectricJob()&lt;br /&gt;
     local EndRadius = 0.0&lt;br /&gt;
     local TopRadius = 0.0&lt;br /&gt;
     local ptT = Polar2D(DrawEllipse_CenterPt,  (90.0 + DrawEllipse_LongAxeAngle), H(DrawEllipse_ShortAxe))&lt;br /&gt;
     local ptB = Polar2D(DrawEllipse_CenterPt, (270.0 + DrawEllipse_LongAxeAngle), H(DrawEllipse_ShortAxe))&lt;br /&gt;
     local ptR = Polar2D(DrawEllipse_CenterPt,   (0.0 + DrawEllipse_LongAxeAngle), H(DrawEllipse_LongAxe))&lt;br /&gt;
     local ptL = Polar2D(DrawEllipse_CenterPt, (180.0 + DrawEllipse_LongAxeAngle), H(DrawEllipse_LongAxe))&lt;br /&gt;
     local ptC = DrawEllipse_CenterPt&lt;br /&gt;
     --[[&lt;br /&gt;
       DMark(&amp;quot;ptC&amp;quot;, ptC)&lt;br /&gt;
       DMark(&amp;quot;ptT&amp;quot;, ptT)&lt;br /&gt;
       DMark(&amp;quot;ptB&amp;quot;, ptB)&lt;br /&gt;
       DMark(&amp;quot;ptL&amp;quot;, ptL)&lt;br /&gt;
       DMark(&amp;quot;ptR&amp;quot;, ptR)]]&lt;br /&gt;
     local C_Offset = H(DrawEllipse_LongAxe - DrawEllipse_ShortAxe)&lt;br /&gt;
     local LT_SlopeDist = H(GetDistance(ptL, ptT) - H(DrawEllipse_LongAxe - DrawEllipse_ShortAxe))&lt;br /&gt;
     local LT_Dist  = GetDistance(ptL, ptT)&lt;br /&gt;
     local LT_Angle = math.abs(90.0 - GetAngle(ptT, ptL, ptC))&lt;br /&gt;
     local pt_a = Polar2D(ptL, LT_Angle + DrawEllipse_LongAxeAngle, LT_SlopeDist)&lt;br /&gt;
     local aT_Dist  = GetDistance(pt_a, ptT)&lt;br /&gt;
     local aC_Dist = aT_Dist / (math.tan(math.rad(LT_Angle)))&lt;br /&gt;
     local Tc_Dist = math.sqrt(aT_Dist^2 + aC_Dist^2)&lt;br /&gt;
     local pt_c = Polar2D(ptT, (270.0 + DrawEllipse_LongAxeAngle), Tc_Dist)&lt;br /&gt;
     local cC_Dist  = GetDistance(pt_c, ptC)&lt;br /&gt;
     local b_Dist = math.tan(math.rad(LT_Angle)) * cC_Dist&lt;br /&gt;
     local pt_b = Polar2D(ptC, (180.0 + DrawEllipse_LongAxeAngle), b_Dist)&lt;br /&gt;
     local pt_d = Polar2D(ptB,  (90.0 + DrawEllipse_LongAxeAngle), Tc_Dist)&lt;br /&gt;
     local pt_e = Polar2D(ptC,   (0.0 + DrawEllipse_LongAxeAngle), b_Dist)&lt;br /&gt;
     local pt1  = Polar2D(pt_d, (270.0 + DrawEllipse_LongAxeAngle) - LT_Angle, Tc_Dist)&lt;br /&gt;
     local pt2  = Polar2D(pt_d, (270.0 + DrawEllipse_LongAxeAngle) + LT_Angle, Tc_Dist)&lt;br /&gt;
     local pt3  = Polar2D(pt_c,  (90.0 + DrawEllipse_LongAxeAngle) - LT_Angle, Tc_Dist)&lt;br /&gt;
     local pt4  = Polar2D(pt_c,  (90.0 + DrawEllipse_LongAxeAngle) + LT_Angle, Tc_Dist)&lt;br /&gt;
     --[[&lt;br /&gt;
       DMark(&amp;quot;pt1&amp;quot;, pt1)&lt;br /&gt;
       DMark(&amp;quot;pt2&amp;quot;, pt2)&lt;br /&gt;
       DMark(&amp;quot;pt3&amp;quot;, pt3)&lt;br /&gt;
       DMark(&amp;quot;pt4&amp;quot;, pt4)&lt;br /&gt;
       local line = Contour(0.0)&lt;br /&gt;
       local layer = job.LayerManager:GetLayerWithName(DrawEllipse_Layer)&lt;br /&gt;
       line:AppendPoint(pt1)&lt;br /&gt;
       line:LineTo(pt2)&lt;br /&gt;
       line:LineTo(pt3)&lt;br /&gt;
       line:LineTo(pt4)&lt;br /&gt;
       line:LineTo(pt1)&lt;br /&gt;
       layer:AddObject(CreateCadContour(line), true)]]&lt;br /&gt;
     local T_Sec   = GetDistance(ptC, ptT) - H(GetDistance(pt1, pt4))&lt;br /&gt;
     local R_Sec   = GetDistance(ptC, ptR) - H(GetDistance(pt1, pt2))&lt;br /&gt;
     local T_Chor  = GetDistance(pt1, pt2)&lt;br /&gt;
     local R_Chor  = GetDistance(pt1, pt4)&lt;br /&gt;
     local T_Bulge = Radius2Bulge (pt1, pt2, Tc_Dist)&lt;br /&gt;
     local L_Bulge = Radius2Bulge (pt1, pt4, GetDistance(ptL, pt_b))&lt;br /&gt;
 &lt;br /&gt;
     local line = Contour(0.0)&lt;br /&gt;
     local layer = job.LayerManager:GetLayerWithName(DrawEllipse_Layer)&lt;br /&gt;
     line:AppendPoint(pt1)&lt;br /&gt;
     line:ArcTo(pt2, T_Bulge)&lt;br /&gt;
     line:ArcTo(pt3, L_Bulge)&lt;br /&gt;
     line:ArcTo(pt4, T_Bulge)&lt;br /&gt;
     line:ArcTo(pt1, L_Bulge)&lt;br /&gt;
     layer:AddObject(CreateCadContour(line), true)&lt;br /&gt;
     job:Refresh2DView()&lt;br /&gt;
     return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DrawBox===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws a Box from points provided.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawBox(p1, p2, p3, p4, Layer)&lt;br /&gt;
     --[[ Draw Box&lt;br /&gt;
     function main(script_path)&lt;br /&gt;
     local MyPt1 = Point2D(1.0,1.0)&lt;br /&gt;
     local MyPt2 = Point2D(1.0,3.0)&lt;br /&gt;
     local MyPt3 = Point2D(3.0,1.0)&lt;br /&gt;
     local MyPt4 = Point2D(3.0,3.0)&lt;br /&gt;
     local layer = &amp;quot;My Box&amp;quot;&lt;br /&gt;
     DrawBox(MyPt1 ,MyPt2, MyPt3, MyPt4, Layer)&lt;br /&gt;
     return true&lt;br /&gt;
     end -- function end&lt;br /&gt;
   -- -----------------------------------------------------]]&lt;br /&gt;
       local job = VectricJob()&lt;br /&gt;
       if not job.Exists then&lt;br /&gt;
         DisplayMessageBox(&amp;quot;Error: No job loaded&amp;quot;)&lt;br /&gt;
         return false&lt;br /&gt;
       end -- if end&lt;br /&gt;
       local line = Contour(0.0)&lt;br /&gt;
       local layer = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
       line:AppendPoint(p1)&lt;br /&gt;
       line:LineTo(p2)&lt;br /&gt;
       line:LineTo(p3)&lt;br /&gt;
       line:LineTo(p4)&lt;br /&gt;
       line:LineTo(p1)&lt;br /&gt;
       layer:AddObject(CreateCadContour(line), true)&lt;br /&gt;
       return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DrawCircle===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws a circle.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawCircle(Pt1, CenterRadius, Layer)&lt;br /&gt;
   --[[ ==Draw Circle==&lt;br /&gt;
     function main(script_path)&lt;br /&gt;
     local MyPt1 = Point2D(1.0,1.0)&lt;br /&gt;
     local MyRad = 3.0&lt;br /&gt;
     local layer = &amp;quot;My Box&amp;quot;&lt;br /&gt;
     DrawCircle(MyPt1, MyRad, Layer)&lt;br /&gt;
     return true&lt;br /&gt;
     end -- function end&lt;br /&gt;
   -- -----------------------------------------------------]]&lt;br /&gt;
     local job = VectricJob()&lt;br /&gt;
     if not job.Exists then&lt;br /&gt;
       DisplayMessageBox(&amp;quot;Error: No job loaded&amp;quot;)&lt;br /&gt;
       return false&lt;br /&gt;
     end -- if end&lt;br /&gt;
     local pa = Polar2D(Pt1,   180.0, CenterRadius)&lt;br /&gt;
     local pb = Polar2D(Pt1,     0.0, CenterRadius)&lt;br /&gt;
     local Contour = Contour(0.0)&lt;br /&gt;
     local layer = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
     Contour:AppendPoint(pa)&lt;br /&gt;
     Contour:ArcTo(pb, 1)&lt;br /&gt;
     Contour:ArcTo(pa, 1)&lt;br /&gt;
     layer:AddObject(CreateCadContour(Contour), true)&lt;br /&gt;
     return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===DrawLine===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws a Line from points provided.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawLine(Pt1, Pt2, Layer)&lt;br /&gt;
   --[[Draws a line from Pt1 to Pt2 on the layer name.&lt;br /&gt;
   function main(script_path)&lt;br /&gt;
   local MyPt1 = Point2D(3.5,3.8)&lt;br /&gt;
   local MyPt2 = Point2D(3.5,6.8)&lt;br /&gt;
   local layer = &amp;quot;My Line&amp;quot;&lt;br /&gt;
   DrawLine(MyPt1 , MyPt2, MyPt3, Layer)&lt;br /&gt;
   return true&lt;br /&gt;
   end -- function end&lt;br /&gt;
   -- -----------------------------------------------------]]&lt;br /&gt;
     local job = VectricJob()&lt;br /&gt;
     if not job.Exists then&lt;br /&gt;
       DisplayMessageBox(&amp;quot;Error: No job loaded&amp;quot;)&lt;br /&gt;
       return false&lt;br /&gt;
     end&lt;br /&gt;
     local line = Contour(0.0)&lt;br /&gt;
     local layer = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
     line:AppendPoint(Pt1)&lt;br /&gt;
     line:LineTo(Pt2)&lt;br /&gt;
     layer:AddObject(CreateCadContour(line), true)&lt;br /&gt;
     return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DrawStar===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws a Star from points provided.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawStar(pt1, InRadius ,OutRadius, layer)      --This draw function requires the center point, inter star radius, outer star radius and layer name.&lt;br /&gt;
   --[[&lt;br /&gt;
     function main(script_path)&lt;br /&gt;
       local MyPt = Point2D(3.5,3.8)&lt;br /&gt;
       local InRadius = 9.0&lt;br /&gt;
       local OutRadius= 20.0&lt;br /&gt;
       local layer = &amp;quot;My Star&amp;quot;&lt;br /&gt;
       DrawStar(MyPt , InRadius ,OutRadius, layer)&lt;br /&gt;
       return true&lt;br /&gt;
     end -- function end&lt;br /&gt;
   -- -----------------------------------------------------]]&lt;br /&gt;
     local job = VectricJob()&lt;br /&gt;
     if not job.Exists then&lt;br /&gt;
       DisplayMessageBox(&amp;quot;Error: No job loaded&amp;quot;)&lt;br /&gt;
       return false&lt;br /&gt;
     end&lt;br /&gt;
     local p1 =  Polar2D(pt1,  18.0,  OutRadius)&lt;br /&gt;
     local p2 =  Polar2D(pt1,  54.0,  InRadius)&lt;br /&gt;
     local p3 =  Polar2D(pt1,  90.0,  OutRadius)&lt;br /&gt;
     local p4 =  Polar2D(pt1,  126.0, InRadius)&lt;br /&gt;
     local p5 =  Polar2D(pt1,  162.0, OutRadius)&lt;br /&gt;
     local p6 =  Polar2D(pt1,  198.0, InRadius)&lt;br /&gt;
     local p7 =  Polar2D(pt1,  234.0, OutRadius)&lt;br /&gt;
     local p8 =  Polar2D(pt1,  270.0, InRadius)&lt;br /&gt;
     local p9 =  Polar2D(pt1,  306.0, OutRadius)&lt;br /&gt;
     local p0 =  Polar2D(pt1,  342.0, InRadius)&lt;br /&gt;
     local line = Contour(0.0)&lt;br /&gt;
    -- local layers = job.LayerManager:GetLayerWithName(layer)&lt;br /&gt;
     line:AppendPoint(p1);&lt;br /&gt;
     line:LineTo(p2);  line:LineTo(p3)&lt;br /&gt;
     line:LineTo(p4);  line:LineTo(p5)&lt;br /&gt;
     line:LineTo(p6);  line:LineTo(p7)&lt;br /&gt;
     line:LineTo(p8);  line:LineTo(p9)&lt;br /&gt;
     line:LineTo(p0);  line:LineTo(p1)&lt;br /&gt;
     layer:AddObject(CreateCadContour(line), true)&lt;br /&gt;
     job:Refresh2DView()&lt;br /&gt;
     return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DrawTriangle===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws a Triangle from points provided.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawTriangle(p1, p2, p3, Layer)&lt;br /&gt;
   --&amp;lt;nowiki&amp;gt;[[Draw Triangle&lt;br /&gt;
     function main(script_path)&lt;br /&gt;
       local MyPt1 = Point2D(3.5,3.8)&lt;br /&gt;
       local MyPt2 = Point2D(3.5,6.8)&lt;br /&gt;
       local MyPt3 = Point2D(9.8,6.8)&lt;br /&gt;
       local layer = &amp;quot;My Triangle&amp;quot;&lt;br /&gt;
       DrawTriangle(MyPt1 , MyPt2, MyPt3, Layer)&lt;br /&gt;
       return true&lt;br /&gt;
     end -- function end &lt;br /&gt;
     local job = VectricJob()&lt;br /&gt;
     if not job.Exists then&lt;br /&gt;
       DisplayMessageBox(&amp;quot;Error: No job loaded&amp;quot;)&lt;br /&gt;
       return false&lt;br /&gt;
     end&lt;br /&gt;
     local line = Contour(0.0)&lt;br /&gt;
     local layer = job.LayerManager:GetLayerWithName(Layer)&lt;br /&gt;
     line:AppendPoint(p1)&lt;br /&gt;
     line:LineTo(p2)&lt;br /&gt;
     line:LineTo(p3)&lt;br /&gt;
     line:LineTo(p1)&lt;br /&gt;
     layer:AddObject(CreateCadContour(line), true)&lt;br /&gt;
     job:Refresh2DView()&lt;br /&gt;
     return true&lt;br /&gt;
   end -- function end&lt;br /&gt;
   -- =====================================================]]&lt;br /&gt;
   function Radius2Bulge (p1, p2, Rad)&lt;br /&gt;
     local chord = math.sqrt(((p2.x - p1.x) ^ 2) + ((p2.y - p1.y) ^ 2))&lt;br /&gt;
     local seg = (Rad - (0.5 * (math.sqrt((4.0 * Rad^2) - chord^2))))&lt;br /&gt;
     local bulge = (2 * seg) / chord&lt;br /&gt;
     return bulge&lt;br /&gt;
   end&lt;br /&gt;
   -- =====================================================]]&lt;br /&gt;
   function ChordSeg2Radius (Chr, Seg)&lt;br /&gt;
     local rad =  (((Chr * Chr)/(Seg * 4)) + Seg) / 2.0&lt;br /&gt;
     return rad&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CreateJob===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Create a new job/drawing setup.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function CreateJob(job_name, width, height, thickness, in_mm, job_origin, z_on_surface)&lt;br /&gt;
 --[[ ----------- CreateJob -------------------------------------------------&lt;br /&gt;
   | This function was provided &amp;quot;as is&amp;quot; by Vectric technical team and a part of the gadget API documentation.&lt;br /&gt;
   | Create a new empty job with the passed settings]]&lt;br /&gt;
   -- we fill in most of our bounds in a Box2D&lt;br /&gt;
   local job_bounds = Box2D()&lt;br /&gt;
   local blc = Point2D(0, 0)&lt;br /&gt;
   local trc = Point2D(width, height)&lt;br /&gt;
   local origin_offset = Vector2D(0,0)&lt;br /&gt;
   -- calculate bottom left corner offset for chosen origin&lt;br /&gt;
   if Template.DXFOrientation == &amp;quot;Vertical&amp;quot; then&lt;br /&gt;
     trc = Point2D(height, width)&lt;br /&gt;
     if (job_origin == &amp;quot;BLC&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(0, 0)&lt;br /&gt;
     elseif (job_origin == &amp;quot;BRC&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(height, 0)&lt;br /&gt;
     elseif (job_origin == &amp;quot;TRC&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(height, width)&lt;br /&gt;
     elseif (job_origin == &amp;quot;TLC&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(0, width)&lt;br /&gt;
     elseif (job_origin == &amp;quot;CENTRE&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(height / 2, width / 2)&lt;br /&gt;
     elseif (job_origin == &amp;quot;CENTER&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(height / 2, width / 2)&lt;br /&gt;
     else&lt;br /&gt;
       MessageBox(&amp;quot;Unknown XY origin specified &amp;quot; .. job_origin)&lt;br /&gt;
     end&lt;br /&gt;
   else&lt;br /&gt;
     if (job_origin == &amp;quot;BLC&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(0, 0)&lt;br /&gt;
     elseif (job_origin == &amp;quot;BRC&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(width, 0)&lt;br /&gt;
     elseif (job_origin == &amp;quot;TRC&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(width, height)&lt;br /&gt;
     elseif (job_origin == &amp;quot;TLC&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(0, height)&lt;br /&gt;
     elseif (job_origin == &amp;quot;CENTRE&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(width / 2, height / 2)&lt;br /&gt;
     elseif (job_origin == &amp;quot;CENTER&amp;quot;) then&lt;br /&gt;
       origin_offset:Set(width / 2, height / 2)&lt;br /&gt;
     else&lt;br /&gt;
       MessageBox(&amp;quot;Unknown XY origin specified &amp;quot; .. job_origin)&lt;br /&gt;
     end&lt;br /&gt;
   end&lt;br /&gt;
   -- subtract the origin offset vector from our 'standard' corner positions to get position for corners for requested origin&lt;br /&gt;
   blc = blc - origin_offset&lt;br /&gt;
   trc = trc - origin_offset&lt;br /&gt;
   job_bounds:Merge(blc)&lt;br /&gt;
   job_bounds:Merge(trc)&lt;br /&gt;
   local success = CreateNewJob(job_name,job_bounds,thickness,in_mm,z_on_surface)&lt;br /&gt;
   return success&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DrawFontGrid - Draws font grid to create letters===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws the font grid for drawing new letters.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawFontGrid(job)&lt;br /&gt;
     local pt = Point2D(0.3,0.3)&lt;br /&gt;
     local scl  = 1.0 -- (scl * 0.5)&lt;br /&gt;
     local pA0  = pt&lt;br /&gt;
     local ang  = 0.0&lt;br /&gt;
     local pA1  = Polar2D(pt, ang + 90.0000, (0.2500 * scl))&lt;br /&gt;
     local pA2  = Polar2D(pt, ang + 90.0000, (0.5000 * scl))&lt;br /&gt;
     local pA3  = Polar2D(pt, ang + 90.0000, (0.7500 * scl))&lt;br /&gt;
     local pA4  = Polar2D(pt, ang + 90.0000, (1.0000 * scl))&lt;br /&gt;
     local pA5  = Polar2D(pt, ang + 90.0000, (1.2500 * scl))&lt;br /&gt;
     local pA6  = Polar2D(pt, ang + 90.0000, (1.5000 * scl))&lt;br /&gt;
     local pA7  = Polar2D(pt, ang + 90.0000, (1.7500 * scl))&lt;br /&gt;
     local pA8  = Polar2D(pt, ang + 90.0000, (2.0000 * scl))&lt;br /&gt;
     local pA9  = Polar2D(pt, ang + 90.0000, (2.2500 * scl))&lt;br /&gt;
     local pA10 = Polar2D(pt, ang + 90.0000, (2.5000 * scl))&lt;br /&gt;
 &lt;br /&gt;
     PointCircle(pA0)&lt;br /&gt;
     PointCircle(pA1)&lt;br /&gt;
     PointCircle(pA2)&lt;br /&gt;
     PointCircle(pA3)&lt;br /&gt;
     PointCircle(pA4)&lt;br /&gt;
     PointCircle(pA5)&lt;br /&gt;
     PointCircle(pA6)&lt;br /&gt;
     PointCircle(pA7)&lt;br /&gt;
     PointCircle(pA8)&lt;br /&gt;
     PointCircle(pA9)&lt;br /&gt;
     PointCircle(pA10)&lt;br /&gt;
 &lt;br /&gt;
     local pB0  = Polar2D(pt, ang +  0.0000, (0.2500 * scl))&lt;br /&gt;
     local pB1  = Polar2D(pt, ang + 45.0000, (0.3536 * scl))&lt;br /&gt;
     local pB2  = Polar2D(pt, ang + 63.4352, (0.5590 * scl))&lt;br /&gt;
     local pB3  = Polar2D(pt, ang + 71.5651, (0.7906 * scl))&lt;br /&gt;
     local pB4  = Polar2D(pt, ang + 75.9638, (1.0308 * scl))&lt;br /&gt;
     local pB5  = Polar2D(pt, ang + 78.6901, (1.2748 * scl))&lt;br /&gt;
     local pB6  = Polar2D(pt, ang + 80.5376, (1.5207 * scl))&lt;br /&gt;
     local pB7  = Polar2D(pt, ang + 81.8699, (1.7678 * scl))&lt;br /&gt;
     local pB8  = Polar2D(pt, ang + 82.8750, (2.0156 * scl))&lt;br /&gt;
     local pB10 = Polar2D(pt, ang + 84.2894, (2.5125 * scl))&lt;br /&gt;
 &lt;br /&gt;
     PointCircle(pB0)&lt;br /&gt;
     PointCircle(pB1)&lt;br /&gt;
     PointCircle(pB2)&lt;br /&gt;
     PointCircle(pB3)&lt;br /&gt;
     PointCircle(pB4)&lt;br /&gt;
     PointCircle(pB5)&lt;br /&gt;
     PointCircle(pB7)&lt;br /&gt;
     PointCircle(pB8)&lt;br /&gt;
     PointCircle(pB10)&lt;br /&gt;
 &lt;br /&gt;
     local pC0 = Polar2D(pt, ang +  0.0000, (0.5000 * scl))&lt;br /&gt;
     local pC1 = Polar2D(pt, ang + 26.5650, (0.5590 * scl))&lt;br /&gt;
     local pC2 = Polar2D(pt, ang + 45.0000, (0.7071 * scl))&lt;br /&gt;
     local pC3 = Polar2D(pt, ang + 56.3099, (0.9014 * scl))&lt;br /&gt;
     local pC4 = Polar2D(pt, ang + 63.4342, (1.1180 * scl))&lt;br /&gt;
     local pC5 = Polar2D(pt, ang + 68.1993, (1.3463 * scl))&lt;br /&gt;
     local pC6 = Polar2D(pt, ang + 71.5650, (1.5811 * scl))&lt;br /&gt;
     local pC7 = Polar2D(pt, ang + 63.4342, (1.1180 * scl))&lt;br /&gt;
     local pC8 = Polar2D(pt, ang + 74.0550, (1.8201 * scl))&lt;br /&gt;
     local pC10 = Polar2D(pt, ang + 78.6899, (2.5495 * scl))&lt;br /&gt;
 &lt;br /&gt;
     PointCircle(pC0)&lt;br /&gt;
     PointCircle(pC1)&lt;br /&gt;
     PointCircle(pC2)&lt;br /&gt;
     PointCircle(pC3)&lt;br /&gt;
     PointCircle(pC4)&lt;br /&gt;
     PointCircle(pC6)&lt;br /&gt;
     PointCircle(pC8)&lt;br /&gt;
     PointCircle(pC10)&lt;br /&gt;
 &lt;br /&gt;
     local pD0 = Polar2D(pt, ang +  0.0000, (0.6250 * scl))&lt;br /&gt;
     local pD1 = Polar2D(pt, ang + 21.8014, (0.6731 * scl))&lt;br /&gt;
     local pD2 = Polar2D(pt, ang + 33.6901, (0.9014 * scl))&lt;br /&gt;
     local pD4 = Polar2D(pt, ang + 57.9946, (1.1792 * scl))&lt;br /&gt;
     local pD7 = Polar2D(pt, ang + 70.3462, (1.8583 * scl))&lt;br /&gt;
     local pD8 = Polar2D(pt, ang + 72.6460, (2.0954 * scl))&lt;br /&gt;
 &lt;br /&gt;
     PointCircle(pD0)&lt;br /&gt;
     PointCircle(pD1)&lt;br /&gt;
     PointCircle(pD2)&lt;br /&gt;
     PointCircle(pD4)&lt;br /&gt;
     PointCircle(pD7)&lt;br /&gt;
     PointCircle(pD8)&lt;br /&gt;
 &lt;br /&gt;
     local pE0 = Polar2D(pt, ang +  0.0000, (0.7500 * scl))&lt;br /&gt;
     local pE1 = Polar2D(pt, ang + 18.4346, (0.7906 * scl))&lt;br /&gt;
     local pE2 = Polar2D(pt, ang + 33.6901, (0.9014 * scl))&lt;br /&gt;
     local pE3 = Polar2D(pt, ang + 45.0000, (1.0607 * scl))&lt;br /&gt;
     local pE5 = Polar2D(pt, ang + 59.0371, (1.4578 * scl))&lt;br /&gt;
     local pE6 = Polar2D(pt, ang + 63.4349, (1.6771 * scl))&lt;br /&gt;
     local pE7 = Polar2D(pt, ang + 66.4349, (1.9039 * scl))&lt;br /&gt;
     local pE8 = Polar2D(pt, ang + 69.4440, (2.1360 * scl))&lt;br /&gt;
 &lt;br /&gt;
     PointCircle(pE0)&lt;br /&gt;
     PointCircle(pE1)&lt;br /&gt;
     PointCircle(pE2)&lt;br /&gt;
     PointCircle(pE3)&lt;br /&gt;
     PointCircle(pE5)&lt;br /&gt;
     PointCircle(pE6)&lt;br /&gt;
     PointCircle(pE7)&lt;br /&gt;
     PointCircle(pE8)&lt;br /&gt;
 &lt;br /&gt;
     local pF0 = Polar2D(pt, ang +  0.0000, (1.0000 * scl))&lt;br /&gt;
     local pF1 = Polar2D(pt, ang + 14.0360, (1.0308 * scl))&lt;br /&gt;
     local pF2 = Polar2D(pt, ang + 26.5651, (1.1180 * scl))&lt;br /&gt;
     local pF3 = Polar2D(pt, ang + 36.8699, (1.2500 * scl))&lt;br /&gt;
     local pF4 = Polar2D(pt, ang + 45.0000, (1.4142 * scl))&lt;br /&gt;
     local pF5 = Polar2D(pt, ang + 51.3425, (1.6006 * scl))&lt;br /&gt;
     local pF6 = Polar2D(pt, ang + 56.3099, (1.8025 * scl))&lt;br /&gt;
     local pF7 = Polar2D(pt, ang + 60.2551, (2.0156 * scl))&lt;br /&gt;
     local pF8 = Polar2D(pt, ang + 63.4349, (2.2361 * scl))&lt;br /&gt;
 &lt;br /&gt;
     PointCircle(pF0)&lt;br /&gt;
     PointCircle(pF1)&lt;br /&gt;
     PointCircle(pF2)&lt;br /&gt;
     PointCircle(pF3)&lt;br /&gt;
     PointCircle(pF4)&lt;br /&gt;
     PointCircle(pF5)&lt;br /&gt;
     PointCircle(pF6)&lt;br /&gt;
     PointCircle(pF7)&lt;br /&gt;
     PointCircle(pF8)&lt;br /&gt;
 &lt;br /&gt;
     local pG0 = Polar2D(pt, ang +  0.0000, (1.2500 * scl))&lt;br /&gt;
     local pG1 = Polar2D(pt, ang + 11.3099, (1.2748 * scl))&lt;br /&gt;
     local pG2 = Polar2D(pt, ang + 21.8014, (1.3463 * scl))&lt;br /&gt;
     local pG3 = Polar2D(pt, ang + 30.9638, (1.4577 * scl))&lt;br /&gt;
     local pG4 = Polar2D(pt, ang + 38.6598, (1.6008 * scl))&lt;br /&gt;
     local pG5 = Polar2D(pt, ang + 45.0000, (1.7678 * scl))&lt;br /&gt;
     local pG6 = Polar2D(pt, ang + 50.1944, (1.9526 * scl))&lt;br /&gt;
     local pG7 = Polar2D(pt, ang + 54.4623, (2.1506 * scl))&lt;br /&gt;
     local pG8 = Polar2D(pt, ang + 57.9946, (2.3585 * scl))&lt;br /&gt;
     local pG10 = Polar2D(pt,59.0362, (2.9155 * scl))&lt;br /&gt;
 &lt;br /&gt;
     PointCircle(pG0)&lt;br /&gt;
     PointCircle(pG1)&lt;br /&gt;
     PointCircle(pG2)&lt;br /&gt;
     PointCircle(pG3)&lt;br /&gt;
     PointCircle(pG4)&lt;br /&gt;
     PointCircle(pG5)&lt;br /&gt;
     PointCircle(pG6)&lt;br /&gt;
     PointCircle(pG7)&lt;br /&gt;
     PointCircle(pG8)&lt;br /&gt;
     PointCircle(pG10)&lt;br /&gt;
 &lt;br /&gt;
     local pH0  = Polar2D(pt, ang + 0.0000, (1.5000 * scl))&lt;br /&gt;
     local pH10 = Polar2D(pt, 63.4349,      (2.7951 * scl))&lt;br /&gt;
     PointCircle(pH0)&lt;br /&gt;
     PointCircle(pH10)&lt;br /&gt;
     job:Refresh2DView()&lt;br /&gt;
     return true&lt;br /&gt;
   end&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
   -- =========================================================================&lt;br /&gt;
   local function AddGroupToJob(job, group, layer_name)&lt;br /&gt;
      --  create a CadObject to represent the  group&lt;br /&gt;
     local cad_object = CreateCadGroup(group);&lt;br /&gt;
      -- create a layer with passed name if it doesnt already exist&lt;br /&gt;
     local layer = job.LayerManager:GetLayerWithName(layer_name)&lt;br /&gt;
      -- and add our object to it&lt;br /&gt;
     layer:AddObject(cad_object, true)&lt;br /&gt;
     return cad_object&lt;br /&gt;
   end -- end function&lt;br /&gt;
 &lt;br /&gt;
   -- =========================================================================&lt;br /&gt;
     local job = VectricJob()&lt;br /&gt;
     if not job.Exists then&lt;br /&gt;
       DisplayMessageBox(&amp;quot;Error: Not finding a job loaded&amp;quot;)&lt;br /&gt;
       return false&lt;br /&gt;
     end&lt;br /&gt;
     local strlen = string.len(what)&lt;br /&gt;
     local strup = string.upper(what)&lt;br /&gt;
     local x = strlen&lt;br /&gt;
     local i = 1&lt;br /&gt;
     local y = &amp;quot;&amp;quot;&lt;br /&gt;
     local ptx = where&lt;br /&gt;
     group = ContourGroup(true)&lt;br /&gt;
     while i &amp;lt;=  x do&lt;br /&gt;
       y = string.byte(string.sub(strup, i, i))&lt;br /&gt;
       ptx = MonoFont(job, ptx, y, size, lay, ang)&lt;br /&gt;
       i = i + 1&lt;br /&gt;
     end -- while end;&lt;br /&gt;
     AddGroupToJob(job, group, lay)&lt;br /&gt;
     job:Refresh2DView()&lt;br /&gt;
     return true ;&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DrawWriter - Draws Upper and Lower case text on the drawing===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DrawWriter(what, where, size, lay, ang) -- Draws Upper and Lower case text on the drawing.&lt;br /&gt;
   --[[ How to use:&lt;br /&gt;
   |    local TextMessage = &amp;quot;Your Text Here&amp;quot;&lt;br /&gt;
   |    local TextPt = Point2D(3.5,3.8)&lt;br /&gt;
   |    local TextHight = 0.5&lt;br /&gt;
   |    local TextLayer = &amp;quot;Text Layer&amp;quot;&lt;br /&gt;
   |    local TextAng = 20.0&lt;br /&gt;
   |    DrawWriter(TextMessage, TextPt , TextHight , TextLayer, TextAng)&lt;br /&gt;
   |    -- ==Draw Writer==&lt;br /&gt;
   |    -- Utilizing a provided string of text, the program walks the string and reproduces each letter (parametrically) on the drawing using vectors.&lt;br /&gt;
   function main()&lt;br /&gt;
       -- create a layer with passed name if it doesn't already exist&lt;br /&gt;
     local job = VectricJob()&lt;br /&gt;
     if not job.Exists then&lt;br /&gt;
          DisplayMessageBox(&amp;quot;No job loaded&amp;quot;)&lt;br /&gt;
          return false;&lt;br /&gt;
     end&lt;br /&gt;
     local TextMessage = &amp;quot;Aa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm Nn Oo Pp Qq Rr Ss Tt Uu Vv Ww Xx Yy Zz 1 2 3 4 5 6 7 8 9 0 ! @ # $ % &amp;amp; * ( ) { } [ ] ? , . : ; '' ' _ - + = ~ ^ &amp;lt; &amp;gt; |&amp;quot;&lt;br /&gt;
     local TextPt = Point2D(0.1, 2.0)&lt;br /&gt;
     local TextHight = 0.25&lt;br /&gt;
     local TextLayer = &amp;quot;Gadget Text&amp;quot;&lt;br /&gt;
     local TextAng = 10.0&lt;br /&gt;
     DrawWriter(TextMessage, TextPt, TextHight, TextLayer, TextAng)&lt;br /&gt;
     job:Refresh2DView()&lt;br /&gt;
     return true&lt;br /&gt;
   end&lt;br /&gt;
   --]]&lt;br /&gt;
   -- =========================================================================&lt;br /&gt;
   local function Polar2D(pt, ang, dis)&lt;br /&gt;
     return Point2D((pt.X + dis * math.cos(math.rad(ang))), (pt.Y + dis * math.sin(math.rad(ang))))&lt;br /&gt;
   end&lt;br /&gt;
   -- =========================================================================&lt;br /&gt;
   local function MonoFont(job, pt, letter, scl, lay, ang)&lt;br /&gt;
     scl = (scl * 0.5) ;&lt;br /&gt;
     local pA0 = pt ;&lt;br /&gt;
     local pA1  = Polar2D(pt, ang + 90.0000, (0.2500 * scl)) ;  local pA2   = Polar2D(pt, ang + 90.0000, (0.5000 * scl)) ;&lt;br /&gt;
     local pA3  = Polar2D(pt, ang + 90.0000, (0.7500 * scl)) ;  local pA4   = Polar2D(pt, ang + 90.0000, (1.0000 * scl)) ;&lt;br /&gt;
     local pA5  = Polar2D(pt, ang + 90.0000, (1.2500 * scl)) ;  local pA6   = Polar2D(pt, ang + 90.0000, (1.5000 * scl)) ;&lt;br /&gt;
     local pA7  = Polar2D(pt, ang + 90.0000, (1.7500 * scl)) ;  local pA8   = Polar2D(pt, ang + 90.0000, (2.0000 * scl)) ;&lt;br /&gt;
     local pA9  = Polar2D(pt, ang + 90.0000, (2.2500 * scl)) ;  local pA10  = Polar2D(pt, ang + 90.0000, (2.5000 * scl)) ;&lt;br /&gt;
     local pB0  = Polar2D(pt, ang +  0.0000, (0.2500 * scl)) ;  local pB1   = Polar2D(pt, ang + 45.0000, (0.3536 * scl)) ;&lt;br /&gt;
     local pB2  = Polar2D(pt, ang + 63.4352, (0.5590 * scl)) ;  local pB3   = Polar2D(pt, ang + 71.5651, (0.7906 * scl)) ;&lt;br /&gt;
     local pB4  = Polar2D(pt, ang + 75.9638, (1.0308 * scl)) ;  local pB5   = Polar2D(pt, ang + 78.6901, (1.2748 * scl)) ;&lt;br /&gt;
     local pB6  = Polar2D(pt, ang + 80.5376, (1.5207 * scl)) ;  local pB7   = Polar2D(pt, ang + 81.8699, (1.7678 * scl)) ;&lt;br /&gt;
     local pB8  = Polar2D(pt, ang + 82.8750, (2.0156 * scl)) ;  local pB10  = Polar2D(pt, ang + 84.2894, (2.5125 * scl)) ;&lt;br /&gt;
     local pC0  = Polar2D(pt, ang +  0.0000, (0.5000 * scl)) ;  local pC1   = Polar2D(pt, ang + 26.5650, (0.5590 * scl)) ;&lt;br /&gt;
     local pC2  = Polar2D(pt, ang + 45.0000, (0.7071 * scl)) ;  local pC3   = Polar2D(pt, ang + 56.3099, (0.9014 * scl)) ;&lt;br /&gt;
     local pC4  = Polar2D(pt, ang + 63.4342, (1.1180 * scl)) ;  local pC5   = Polar2D(pt, ang + 68.1993, (1.3463 * scl)) ;&lt;br /&gt;
     local pC6  = Polar2D(pt, ang + 71.5650, (1.5811 * scl)) ;  local pC7   = Polar2D(pt, ang + 63.4342, (1.1180 * scl)) ;&lt;br /&gt;
     local pC8  = Polar2D(pt, ang + 75.9640, (2.0616 * scl)) ;  local pC10  = Polar2D(pt, ang + 78.6899, (2.5495 * scl)) ;&lt;br /&gt;
     local pD0  = Polar2D(pt, ang +  0.0000, (0.6250 * scl)) ;  local pD1   = Polar2D(pt, ang + 21.8014, (0.6731 * scl)) ;&lt;br /&gt;
     local pD2  = Polar2D(pt, ang + 33.6901, (0.9014 * scl)) ;  local pD4   = Polar2D(pt, ang + 57.9946, (1.1792 * scl)) ;&lt;br /&gt;
     local pD7  = Polar2D(pt, ang + 70.3462, (1.8583 * scl)) ;  local pD8   = Polar2D(pt, ang + 72.6460, (2.0954 * scl)) ;&lt;br /&gt;
     local pE0  = Polar2D(pt, ang +  0.0000, (0.7500 * scl)) ;  local pE1   = Polar2D(pt, ang + 18.4346, (0.7906 * scl)) ;&lt;br /&gt;
     local pE2  = Polar2D(pt, ang + 33.6901, (0.9014 * scl)) ;  local pE3   = Polar2D(pt, ang + 45.0000, (1.0607 * scl)) ;&lt;br /&gt;
     local pE5  = Polar2D(pt, ang + 59.0371, (1.4578 * scl)) ;  local pE6   = Polar2D(pt, ang + 63.4349, (1.6771 * scl)) ;&lt;br /&gt;
     local pE7  = Polar2D(pt, ang + 66.4349, (1.9039 * scl)) ;  local pE8   = Polar2D(pt, ang + 69.4440, (2.1360 * scl)) ;&lt;br /&gt;
     local pF0  = Polar2D(pt, ang +  0.0000, (1.0000 * scl)) ;  local pF1   = Polar2D(pt, ang + 14.0360, (1.0308 * scl)) ;&lt;br /&gt;
     local pF2  = Polar2D(pt, ang + 26.5651, (1.1180 * scl)) ;  local pF3   = Polar2D(pt, ang + 36.8699, (1.2500 * scl)) ;&lt;br /&gt;
     local pF4  = Polar2D(pt, ang + 45.0000, (1.4142 * scl)) ;  local pF5   = Polar2D(pt, ang + 51.3425, (1.6006 * scl)) ;&lt;br /&gt;
     local pF6  = Polar2D(pt, ang + 56.3099, (1.8025 * scl)) ;  local pF7   = Polar2D(pt, ang + 60.2551, (2.0156 * scl)) ;&lt;br /&gt;
     local pF8  = Polar2D(pt, ang + 63.4349, (2.2361 * scl)) ;  local pG0   = Polar2D(pt, ang +  0.0000, (1.2500 * scl)) ;&lt;br /&gt;
     local pG1  = Polar2D(pt, ang + 11.3099, (1.2748 * scl)) ;  local pG2   = Polar2D(pt, ang + 21.8014, (1.3463 * scl)) ;&lt;br /&gt;
     local pG3  = Polar2D(pt, ang + 30.9638, (1.4577 * scl)) ;  local pG4   = Polar2D(pt, ang + 38.6598, (1.6008 * scl)) ;&lt;br /&gt;
     local pG5  = Polar2D(pt, ang + 45.0000, (1.7678 * scl)) ;  local pG6   = Polar2D(pt, ang + 50.1944, (1.9526 * scl)) ;&lt;br /&gt;
     local pG7  = Polar2D(pt, ang + 54.4623, (2.1506 * scl)) ;  local pG8   = Polar2D(pt, ang + 57.9946, (2.3585 * scl)) ;&lt;br /&gt;
     local pG10 = Polar2D(pt,59.0362, (2.9155 * scl))        ;  local pH0   = Polar2D(pt, ang +  0.0000, (1.5000 * scl)) ;&lt;br /&gt;
     local pH10 = Polar2D(pt,63.4349, (2.7951 * scl))        ;  local layer = job.LayerManager:GetLayerWithName(lay) ;&lt;br /&gt;
     local line = Contour(0.0) ;&lt;br /&gt;
    -- ------------------------------------------------------------------------&lt;br /&gt;
     if letter == 32 then&lt;br /&gt;
       pH0 = pH0&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 33 then&lt;br /&gt;
       line:AppendPoint(pB0) ;  line:LineTo(pE0) ;  line:LineTo(pE2) ;  line:LineTo(pB2) ;  line:LineTo(pB0) ;  group:AddTail(line) ;&lt;br /&gt;
       line = Contour(0.0) line:AppendPoint(pB3) ;  line:LineTo(pE3) ;  line:LineTo(pE8) ;  line:LineTo(pB8) ;  line:LineTo(pB3) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 34 then&lt;br /&gt;
       line:AppendPoint(pA7) ;  line:LineTo(pB10) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pB7) ;  line:LineTo(pC10) ;&lt;br /&gt;
       group:AddTail(line) ;  pH0 = pE0&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 35 then&lt;br /&gt;
       line:AppendPoint(pA2) ;  line:LineTo(pG2) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA6) ;&lt;br /&gt;
       line:LineTo(pG6) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pB0) ;  line:LineTo(pB8) ;  group:AddTail(line) ;&lt;br /&gt;
       line = Contour(0.0) ;  line:AppendPoint(pF0) ;  line:LineTo(pF8) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 36 then&lt;br /&gt;
       line:AppendPoint(pA1) ;  line:LineTo(pB0) ;  line:LineTo(pF0) ;  line:LineTo(pG1) ;  line:LineTo(pG3) ;  line:LineTo(pF4) ;&lt;br /&gt;
       line:LineTo(pB4) ;  line:LineTo(pA5) ;  line:LineTo(pA7) ;  line:LineTo(pB8) ;  line:LineTo(pF8) ;  line:LineTo(pG7) ;  group:AddTail(line) ;&lt;br /&gt;
       line = Contour(0.0) ;  line:AppendPoint(pC0) ;  line:LineTo(pE0) ;  line:LineTo(pE8) ;  line:LineTo(pC8) ;  line:LineTo(pC0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 37 then&lt;br /&gt;
       line:AppendPoint(pC6) ;  line:LineTo(pC8) ;  line:LineTo(pA8) ;  line:LineTo(pA6) ;  line:LineTo(pE6) ;  line:LineTo(pG8) ;&lt;br /&gt;
       line:LineTo(pA0) ;  line:LineTo(pC2) ;  line:LineTo(pG2) ;  line:LineTo(pG0) ;  line:LineTo(pE0) ;  line:LineTo(pE2) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 38 then&lt;br /&gt;
       line:AppendPoint(pG2) ;  line:LineTo(pG1) ;  line:LineTo(pF0) ;  line:LineTo(pB0) ;  line:LineTo(pA1) ;  line:LineTo(pA3) ;&lt;br /&gt;
       line:LineTo(pE6) ;  line:LineTo(pE7) ;  line:LineTo(pD8) ;  line:LineTo(pB8) ;  line:LineTo(pA7) ;  line:LineTo(pA6) ;  line:LineTo(pG0) ;&lt;br /&gt;
       group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 39 then&lt;br /&gt;
       line:AppendPoint(pA7) ;  line:LineTo(pB10) ;  group:AddTail(line) ;  pH0 = pC0&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 40 then&lt;br /&gt;
       line:AppendPoint(pB8) ;  line:LineTo(pA5) ;  line:LineTo(pA3) ;  line:LineTo(pB0) ;  group:AddTail(line) ;  pH0 = pD0&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 41 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pB5) ;  line:LineTo(pB3) ;  line:LineTo(pA0) ;  group:AddTail(line) ;  pH0 = pG0&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 42 then&lt;br /&gt;
       line:AppendPoint(pA2) ;  line:LineTo(pG6) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA6) ;  line:LineTo(pG2) ;&lt;br /&gt;
       group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA4) ;  line:LineTo(pG4) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pD7) ;&lt;br /&gt;
       line:LineTo(pD1) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 43 then&lt;br /&gt;
       line:AppendPoint(pA4) ;  line:LineTo(pG4) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pD1) ;  line:LineTo(pD7) ;&lt;br /&gt;
       group:AddTail(line)&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 44 then&lt;br /&gt;
       line:AppendPoint(pC0) ;  line:LineTo(pE2) ;  line:LineTo(pC2) ;  line:LineTo(pC4) ;  line:LineTo(pF4) ;  line:LineTo(pF2) ;&lt;br /&gt;
       line:LineTo(pD0) ;  line:LineTo(pC0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 45 then&lt;br /&gt;
       line:AppendPoint(pA4) ;  line:LineTo(pG4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 46 then&lt;br /&gt;
       line:AppendPoint(pA1) ;  line:LineTo(pB1) ;  line:LineTo(pB0) ;  line:LineTo(pA0) ;  line:LineTo(pA1) ;  group:AddTail(line) ;  pH0 = pD0 ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 47 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pF8) ;  group:AddTail(line) ;  pH0 = pG0 ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 48 then&lt;br /&gt;
       line:AppendPoint(pB0) ;  line:LineTo(pA2) ;  line:LineTo(pA6) ;  line:LineTo(pB8) ;  line:LineTo(pF8) ;  line:LineTo(pG6) ;&lt;br /&gt;
       line:LineTo(pG2) ;  line:LineTo(pF0) ;  line:LineTo(pB0) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pG8) ;  line:LineTo(pA0) ; group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 49 then&lt;br /&gt;
       line:AppendPoint(pA6) ;  line:LineTo(pD8) ;  line:LineTo(pD0) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA0) ;&lt;br /&gt;
       line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 50 then&lt;br /&gt;
       line:AppendPoint(pA6) ;  line:LineTo(pA7) ;  line:LineTo(pB8) ;  line:LineTo(pF8) ;  line:LineTo(pG7) ;  line:LineTo(pG5) ;&lt;br /&gt;
       line:LineTo(pA2) ;  line:LineTo(pA0) ;  line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 51 then&lt;br /&gt;
       line:AppendPoint(pA7) ;  line:LineTo(pB8) ;  line:LineTo(pF8) ;  line:LineTo(pG7) ;  line:LineTo(pG5) ;  line:LineTo(pF4) ;&lt;br /&gt;
       line:LineTo(pG3) ;  line:LineTo(pG1) ;  line:LineTo(pF0) ;  line:LineTo(pB0) ;  line:LineTo(pA1) ;  group:AddTail(line) ;  line = Contour(0.0) ;&lt;br /&gt;
       line:AppendPoint(pF4) ;  line:LineTo(pB4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 52 then&lt;br /&gt;
       line:AppendPoint(pF0) ;  line:LineTo(pF8) ;  line:LineTo(pA2) ;  line:LineTo(pG2) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 53 then&lt;br /&gt;
       line:AppendPoint(pG8) ;  line:LineTo(pA8) ;  line:LineTo(pA5) ;  line:LineTo(pF4) ;  line:LineTo(pG3) ;  line:LineTo(pG1) ;&lt;br /&gt;
       line:LineTo(pF0) ;  line:LineTo(pB0) ;  line:LineTo(pA1) ;  line:LineTo(pA2) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 54 then&lt;br /&gt;
       line:AppendPoint(pG7) ;  line:LineTo(pF8) ;  line:LineTo(pB8) ;  line:LineTo(pA7) ;  line:LineTo(pA1) ;  line:LineTo(pB0) ;&lt;br /&gt;
       line:LineTo(pF0) ;  line:LineTo(pG1) ;  line:LineTo(pG3) ;  line:LineTo(pF4) ;  line:LineTo(pB4) ;  line:LineTo(pA2) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 55 then&lt;br /&gt;
       line:AppendPoint(pB0) ;  line:LineTo(pG8) ;  line:LineTo(pA8) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 56 then&lt;br /&gt;
       line:AppendPoint(pA1) ;  line:LineTo(pB0) ;  line:LineTo(pF0) ;  line:LineTo(pG1) ;  line:LineTo(pG3) ;  line:LineTo(pF4) ;&lt;br /&gt;
       line:LineTo(pG5) ;  line:LineTo(pG7) ;  line:LineTo(pF8) ;  line:LineTo(pB8) ;  line:LineTo(pA7) ;  line:LineTo(pA5) ;  line:LineTo(pB4) ;&lt;br /&gt;
       line:LineTo(pA3) ;  line:LineTo(pA1) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pB4) ;  line:LineTo(pF4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 57 then&lt;br /&gt;
       line:AppendPoint(pA1) ;  line:LineTo(pB0) ;  line:LineTo(pF0) ;  line:LineTo(pG3) ;  line:LineTo(pG7) ;  line:LineTo(pF8) ;&lt;br /&gt;
       line:LineTo(pB8) ;  line:LineTo(pA7) ;  line:LineTo(pA5) ;  line:LineTo(pB4) ;  line:LineTo(pF4) ;  line:LineTo(pG5) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 58 then&lt;br /&gt;
       line:AppendPoint(pB8) ;  line:LineTo(pA8) ;  line:LineTo(pA7) ;  line:LineTo(pB7) ;  line:LineTo(pB8) ;  line:LineTo(pA8) ;&lt;br /&gt;
       group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA1) ;  line:LineTo(pB1) ;  line:LineTo(pB0) ;  line:LineTo(pA0) ;  line:LineTo(pA1) ;&lt;br /&gt;
       group:AddTail(line) ;  pH0 = pD0 ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 59 then&lt;br /&gt;
       line:AppendPoint(pB8) ;  line:LineTo(pA8) ;  line:LineTo(pA7) ;  line:LineTo(pB7) ;  line:LineTo(pB8) ;  line:LineTo(pA8) ;&lt;br /&gt;
       group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pB3) ;  line:LineTo(pB4) ;  line:LineTo(pA4) ;  line:LineTo(pA3) ;  line:LineTo(pB3) ;&lt;br /&gt;
       line:LineTo(pA0) ;  group:AddTail(line) ;  pH0 = pD0 ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 60 then&lt;br /&gt;
       line:AppendPoint(pF8) ;  line:LineTo(pA4) ;  line:LineTo(pG0) ;  group:AddTail(line)&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 61 then&lt;br /&gt;
       line:AppendPoint(pA2) ;  line:LineTo(pG2) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA6) ;&lt;br /&gt;
       line:LineTo(pG6) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 62 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pF4) ;  line:LineTo(pA0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 63 then&lt;br /&gt;
       line:AppendPoint(pB5) ;  line:LineTo(pA6) ;  line:LineTo(pA7) ;  line:LineTo(pB8) ;  line:LineTo(pE8) ;  line:LineTo(pF7) ;&lt;br /&gt;
       line:LineTo(pF5) ;  line:LineTo(pC3) ;  line:LineTo(pC2) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pB0) ;  line:LineTo(pE0) ;&lt;br /&gt;
       line:LineTo(pE1) ;  line:LineTo(pB1) ;  line:LineTo(pB0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 64 then&lt;br /&gt;
       line:AppendPoint(pG0) ;  line:LineTo(pB0) ;  line:LineTo(pA2) ;  line:LineTo(pA6) ;  line:LineTo(pB8) ;  line:LineTo(pF8) ;&lt;br /&gt;
       line:LineTo(pG6) ;  line:LineTo(pG3) ;  line:LineTo(pE2) ;  line:LineTo(pB2) ;  line:LineTo(pB5) ;  line:LineTo(pE5) ;  line:LineTo(pE2) ;&lt;br /&gt;
       group:AddTail(line)&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 65 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pD8) ;  line:LineTo(pG0) ;  line:LineTo(pF3) ;  line:LineTo(pB3) ;&lt;br /&gt;
       line:LineTo(pA0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 66 then&lt;br /&gt;
       line:AppendPoint(pA4) ;  line:LineTo(pF4) ;  line:LineTo(pG5) ;  line:LineTo(pG7) ;  line:LineTo(pF8) ;  line:LineTo(pA8) ;&lt;br /&gt;
       line:LineTo(pA0) ;  line:LineTo(pF0) ;  line:LineTo(pG1) ;  line:LineTo(pG3) ;  line:LineTo(pF4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 67 then&lt;br /&gt;
       line:AppendPoint(pG2) ;  line:LineTo(pF0) ;  line:LineTo(pB0) ;  line:LineTo(pA2) ;  line:LineTo(pA6) ;  line:LineTo(pB8) ;&lt;br /&gt;
       line:LineTo(pF8) ;  line:LineTo(pG6) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 68 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pF0) ;  line:LineTo(pG2) ;  line:LineTo(pG6) ;  line:LineTo(pF8) ;  line:LineTo(pA8) ;&lt;br /&gt;
       line:LineTo(pA0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 69 then&lt;br /&gt;
       line:AppendPoint(pG0) ;  line:LineTo(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pF8) ;  group:AddTail(line) ;  line = Contour(0.0) ;&lt;br /&gt;
       line:AppendPoint(pA4) ;  line:LineTo(pD4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 70 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pG8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA4) ;&lt;br /&gt;
       line:LineTo(pF4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 71 then&lt;br /&gt;
       line:AppendPoint(pG6) ;  line:LineTo(pG7) ;  line:LineTo(pF8) ;  line:LineTo(pB8) ;  line:LineTo(pA6) ;  line:LineTo(pA2) ;&lt;br /&gt;
       line:LineTo(pB0) ;  line:LineTo(pF0) ;  line:LineTo(pG2) ;  line:LineTo(pG3) ;  line:LineTo(pE3) ;  line:LineTo(pE2) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 72 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pG0) ;  line:LineTo(pG8) ;&lt;br /&gt;
       group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA4) ;  line:LineTo(pG4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 73 then&lt;br /&gt;
       line:AppendPoint(pB0) ;  line:LineTo(pB8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA0) ;  line:LineTo(pC0) ;&lt;br /&gt;
       group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA8) ;  line:LineTo(pC8) ;  group:AddTail(line) ;  pH0 = pE0 ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 74 then&lt;br /&gt;
       line:AppendPoint(pA2) ;  line:LineTo(pB0) ;  line:LineTo(pF0) ;  line:LineTo(pG2) ;  line:LineTo(pG8) ;  line:LineTo(pC8) ;&lt;br /&gt;
       group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 75 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA2) ;  line:LineTo(pG7) ;&lt;br /&gt;
       group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pD4) ;  line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 76 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pA0) ;  line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 77 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pD4) ;  line:LineTo(pG8) ;  line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 78 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pF0) ;  line:LineTo(pF8) ;  group:AddTail(line) ;  pH0 = pG0 ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 79 then&lt;br /&gt;
       line:AppendPoint(pB0) ;  line:LineTo(pA2) ;  line:LineTo(pA6) ;  line:LineTo(pB8) ;  line:LineTo(pF8) ;  line:LineTo(pG6) ;&lt;br /&gt;
       line:LineTo(pG2) ;  line:LineTo(pF0) ;  line:LineTo(pB0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 80 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pF8) ;  line:LineTo(pG7) ;  line:LineTo(pG5) ;  line:LineTo(pF4) ;&lt;br /&gt;
       line:LineTo(pA4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 81 then&lt;br /&gt;
       line:AppendPoint(pB0) ;  line:LineTo(pA2) ;  line:LineTo(pA6) ;  line:LineTo(pB8) ;  line:LineTo(pF8) ;  line:LineTo(pG6) ;&lt;br /&gt;
       line:LineTo(pG2) ;  line:LineTo(pF0) ;  line:LineTo(pB0) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pG0) ;  line:LineTo(pD4) ; group:AddTail(line)&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 82 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pF8) ;  line:LineTo(pG7) ;  line:LineTo(pG5) ;  line:LineTo(pF4) ;&lt;br /&gt;
       line:LineTo(pA4) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pD4) ;  line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 83 then&lt;br /&gt;
       line:AppendPoint(pG5) ;  line:LineTo(pG6) ;  line:LineTo(pF8) ;  line:LineTo(pB8) ;  line:LineTo(pA6) ;  line:LineTo(pA5) ;&lt;br /&gt;
       line:LineTo(pG3) ;  line:LineTo(pG2) ;  line:LineTo(pF0) ;  line:LineTo(pB0) ;  line:LineTo(pA2) ;  line:LineTo(pA3) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 84 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pG8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pD8) ;&lt;br /&gt;
       line:LineTo(pD0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 85 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pA2) ;  line:LineTo(pB0) ;  line:LineTo(pF0) ;  line:LineTo(pG2) ;  line:LineTo(pG8) ;&lt;br /&gt;
       group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 86 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pD0) ;  line:LineTo(pG8) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 87 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pB0) ;  line:LineTo(pD4) ;  line:LineTo(pF0) ;  line:LineTo(pG8) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 88 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pG8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA8) ;&lt;br /&gt;
       line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 89 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pD4) ;  line:LineTo(pG8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pD0) ;&lt;br /&gt;
       line:LineTo(pD4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 90 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pG8) ;  line:LineTo(pA0) ;  line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
 &lt;br /&gt;
     if letter == 91 then&lt;br /&gt;
       line:AppendPoint(pC0) ;  line:LineTo(pB0) ;  line:LineTo(pB8) ;  line:LineTo(pC8) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 92 then&lt;br /&gt;
       line:AppendPoint(pA4) ;  line:LineTo(pG4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 93 then&lt;br /&gt;
       line:AppendPoint(pE0) ;  line:LineTo(pF0) ;  line:LineTo(pF8) ;  line:LineTo(pE8) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 94 then&lt;br /&gt;
       line:AppendPoint(pD8) ;  line:LineTo(pG6) ;  line:LineTo(pG5) ;  line:LineTo(pD7) ;  line:LineTo(pA5) ;  line:LineTo(pA6) ;&lt;br /&gt;
       line:LineTo(pD8) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 95 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pF0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 96 then&lt;br /&gt;
       line:AppendPoint(pA4) ;  line:LineTo(pG4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     -- Start of Lower Case&lt;br /&gt;
     if letter == 97 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pD8) ;  line:LineTo(pG0) ;  line:LineTo(pF3) ;  line:LineTo(pB3) ;&lt;br /&gt;
       line:LineTo(pA0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 98 then&lt;br /&gt;
       line:AppendPoint(pA4) ;  line:LineTo(pF4) ;  line:LineTo(pG5) ;  line:LineTo(pG7) ;  line:LineTo(pF8) ;  line:LineTo(pA8) ;&lt;br /&gt;
       line:LineTo(pA0) ;  line:LineTo(pF0) ;  line:LineTo(pG1) ;  line:LineTo(pG3) ;  line:LineTo(pF4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 99 then&lt;br /&gt;
       line:AppendPoint(pG2) ;  line:LineTo(pF0) ;  line:LineTo(pB0) ;  line:LineTo(pA2) ;  line:LineTo(pA6) ;  line:LineTo(pB8) ;&lt;br /&gt;
       line:LineTo(pF8) ;  line:LineTo(pG6) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 100 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pF0) ;  line:LineTo(pG2) ;  line:LineTo(pG6) ;  line:LineTo(pF8) ;  line:LineTo(pA8) ;&lt;br /&gt;
       line:LineTo(pA0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 101 then&lt;br /&gt;
       line:AppendPoint(pG0) ;  line:LineTo(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pF8) ;  group:AddTail(line) ;  line = Contour(0.0) ;&lt;br /&gt;
       line:AppendPoint(pA4) ;  line:LineTo(pD4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 102 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pG8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA4) ;&lt;br /&gt;
       line:LineTo(pF4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 103 then&lt;br /&gt;
       line:AppendPoint(pG6) ;  line:LineTo(pG7) ;  line:LineTo(pF8) ;  line:LineTo(pB8) ;  line:LineTo(pA6) ;  line:LineTo(pA2) ;&lt;br /&gt;
       line:LineTo(pB0) ;  line:LineTo(pF0) ;  line:LineTo(pG2) ;  line:LineTo(pG3) ;  line:LineTo(pE3) ;  line:LineTo(pE2) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 104 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pG0) ;  line:LineTo(pG8) ;&lt;br /&gt;
       group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA4) ;  line:LineTo(pG4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 105 then&lt;br /&gt;
       line:AppendPoint(pB0) ;  line:LineTo(pB8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA0) ;  line:LineTo(pC0) ;&lt;br /&gt;
       group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA8) ;  line:LineTo(pC8) ;  group:AddTail(line) ;  pH0 = pE0 ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 106 then&lt;br /&gt;
       line:AppendPoint(pA2) ;  line:LineTo(pB0) ;  line:LineTo(pF0) ;  line:LineTo(pG2) ;  line:LineTo(pG8) ;  line:LineTo(pC8) ;&lt;br /&gt;
       group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 107 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA2) ;  line:LineTo(pG7) ;&lt;br /&gt;
       group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pD4) ;  line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 108 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pA0) ;  line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 109 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pD4) ;  line:LineTo(pG8) ;  line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 110 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pF0) ;  line:LineTo(pF8) ;  group:AddTail(line) ;  pH0 = pG0 ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 111 then&lt;br /&gt;
       line:AppendPoint(pB0) ;  line:LineTo(pA2) ;  line:LineTo(pA6) ;  line:LineTo(pB8) ;  line:LineTo(pF8) ;  line:LineTo(pG6) ;&lt;br /&gt;
       line:LineTo(pG2) ;  line:LineTo(pF0) ;  line:LineTo(pB0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 112 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pF8) ;  line:LineTo(pG7) ;  line:LineTo(pG5) ;  line:LineTo(pF4) ;&lt;br /&gt;
       line:LineTo(pA4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 113 then&lt;br /&gt;
       line:AppendPoint(pB0) ;  line:LineTo(pA2) ;  line:LineTo(pA6) ;  line:LineTo(pB8) ;  line:LineTo(pF8) ;  line:LineTo(pG6) ;&lt;br /&gt;
       line:LineTo(pG2) ;  line:LineTo(pF0) ;  line:LineTo(pB0) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pG0) ;  line:LineTo(pD4) ; group:AddTail(line)&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 114 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA8) ;  line:LineTo(pF8) ;  line:LineTo(pG7) ;  line:LineTo(pG5) ;  line:LineTo(pF4) ;&lt;br /&gt;
       line:LineTo(pA4) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pD4) ;  line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 115 then&lt;br /&gt;
       line:AppendPoint(pG5) ;  line:LineTo(pG6) ;  line:LineTo(pF8) ;  line:LineTo(pB8) ;  line:LineTo(pA6) ;  line:LineTo(pA5) ;&lt;br /&gt;
       line:LineTo(pG3) ;  line:LineTo(pG2) ;  line:LineTo(pF0) ;  line:LineTo(pB0) ;  line:LineTo(pA2) ;  line:LineTo(pA3) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 116 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pG8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pD8) ;&lt;br /&gt;
       line:LineTo(pD0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 117 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pA2) ;  line:LineTo(pB0) ;  line:LineTo(pF0) ;  line:LineTo(pG2) ;  line:LineTo(pG8) ;&lt;br /&gt;
       group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 118 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pD0) ;  line:LineTo(pG8) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 119 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pB0) ;  line:LineTo(pD4) ;  line:LineTo(pF0) ;  line:LineTo(pG8) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 120 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pG8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pA8) ;&lt;br /&gt;
       line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 121 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pD4) ;  line:LineTo(pG8) ;  group:AddTail(line) ;  line = Contour(0.0) ;  line:AppendPoint(pD0) ;&lt;br /&gt;
       line:LineTo(pD4) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 122 then&lt;br /&gt;
       line:AppendPoint(pA8) ;  line:LineTo(pG8) ;  line:LineTo(pA0) ;  line:LineTo(pG0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     -- End of Lower Case&lt;br /&gt;
     if letter == 123 then&lt;br /&gt;
       line:AppendPoint(pD0) ;  line:LineTo(pC0) ;  line:LineTo(pB1) ;  line:LineTo(pB2) ;  line:LineTo(pC3) ;  line:LineTo(pA4) ;&lt;br /&gt;
       line:LineTo(pC5) ;  line:LineTo(pB6) ;  line:LineTo(pB7) ;  line:LineTo(pC8) ;  line:LineTo(pD8) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 124 then&lt;br /&gt;
       line:AppendPoint(pA0) ;  line:LineTo(pA10) ;  line:LineTo(pC10) ;  line:LineTo(pC0) ;  line:LineTo(pA0) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 125 then&lt;br /&gt;
       line:AppendPoint(pD0) ;  line:LineTo(pE0) ;  line:LineTo(pF1) ;  line:LineTo(pF2) ;  line:LineTo(pE3) ;  line:LineTo(pG4) ;&lt;br /&gt;
       line:LineTo(pE5) ;  line:LineTo(pF6) ;  line:LineTo(pF7) ;  line:LineTo(pE8) ;  line:LineTo(pD8) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     if letter == 126 then&lt;br /&gt;
       line:AppendPoint(pA2) ;  line:LineTo(pA3) ;  line:LineTo(pB5) ;  line:LineTo(pF3) ;  line:LineTo(pG5) ;&lt;br /&gt;
       line:LineTo(pG4) ;  line:LineTo(pF2) ;  line:LineTo(pB4) ;  line:LineTo(pA2) ;  group:AddTail(line) ;&lt;br /&gt;
     end&lt;br /&gt;
     return pH0&lt;br /&gt;
   end -- function end&lt;br /&gt;
 &lt;br /&gt;
   -- =========================================================================&lt;br /&gt;
   local function AddGroupToJob(job, group, layer_name)&lt;br /&gt;
      --  create a CadObject to represent the  group&lt;br /&gt;
     local cad_object = CreateCadGroup(group);&lt;br /&gt;
      -- create a layer with passed name if it doesnt already exist&lt;br /&gt;
     local layer = job.LayerManager:GetLayerWithName(layer_name)&lt;br /&gt;
      -- and add our object to it&lt;br /&gt;
     layer:AddObject(cad_object, true)&lt;br /&gt;
     return cad_object&lt;br /&gt;
   end -- end function&lt;br /&gt;
 &lt;br /&gt;
   -- =========================================================================&lt;br /&gt;
     local job = VectricJob()&lt;br /&gt;
     if not job.Exists then&lt;br /&gt;
       DisplayMessageBox(&amp;quot;Error: Not finding a job loaded&amp;quot;)&lt;br /&gt;
       return false&lt;br /&gt;
     end&lt;br /&gt;
     local strlen = string.len(what)&lt;br /&gt;
     local strup = what&lt;br /&gt;
     local x = strlen&lt;br /&gt;
     local i = 1&lt;br /&gt;
     local y = &amp;quot;&amp;quot;&lt;br /&gt;
     local ptx = where&lt;br /&gt;
     group = ContourGroup(true)&lt;br /&gt;
     while i &amp;lt;=  x do&lt;br /&gt;
       y = string.byte(string.sub(strup, i, i))&lt;br /&gt;
       if (y &amp;gt;= 97) and (y &amp;lt;= 122) then -- Lower case&lt;br /&gt;
         ptx = MonoFont(job, ptx, y, (size * 0.75), lay, ang)&lt;br /&gt;
         ptx = Polar2D(ptx, ang, size * 0.05)&lt;br /&gt;
       else -- Upper case&lt;br /&gt;
         ptx = MonoFont(job, ptx, y, size, lay, ang)&lt;br /&gt;
         ptx = Polar2D(ptx, ang, size * 0.07)&lt;br /&gt;
       end&lt;br /&gt;
       i = i + 1&lt;br /&gt;
     end -- while end;&lt;br /&gt;
     AddGroupToJob(job, group, lay)&lt;br /&gt;
     job:Refresh2DView()&lt;br /&gt;
     return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Holer - Draws two Holes and groups them===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Draws circles based on a layout.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function Holer(pt, ang, dst, dia, lay)&lt;br /&gt;
       local job = VectricJob()&lt;br /&gt;
       if not job.Exists then&lt;br /&gt;
         DisplayMessageBox(&amp;quot;Error: No job loaded&amp;quot;)&lt;br /&gt;
         return false&lt;br /&gt;
       end&lt;br /&gt;
     --Caller: Holer(ptx, anx, BaseDim.HoleSpace, Milling.ShelfPinRadius, Milling.LNSideShelfPinDrill .. &amp;quot;-Base&amp;quot;)&lt;br /&gt;
       local function AddGroupToJob(job, group, layer_name)&lt;br /&gt;
         local cad_object = CreateCadGroup(group);&lt;br /&gt;
         local layer = job.LayerManager:GetLayerWithName(layer_name)&lt;br /&gt;
         layer:AddObject(cad_object, true)&lt;br /&gt;
         return cad_object&lt;br /&gt;
       end&lt;br /&gt;
     local group = ContourGroup(true)&lt;br /&gt;
     group:AddTail(CreateCircle(pt.x, pt.y, dia, 0.0, 0.0))&lt;br /&gt;
     pt = Polar2D(pt, ang, dst)&lt;br /&gt;
     group:AddTail(CreateCircle(pt.x, pt.y, dia, 0.0, 0.0))&lt;br /&gt;
     AddGroupToJob(job, group, lay)&lt;br /&gt;
     return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Data Export Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
 &lt;br /&gt;
===LogWriter===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
&lt;br /&gt;
Writes a Log items to the log file.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function LogWriter(LogName, xText)&lt;br /&gt;
  -- Adds a new xText Line to a app log file&lt;br /&gt;
  -- local LogName = Door.CSVPath .. &amp;quot;\\&amp;quot; .. Door.RuntimeLog .. &amp;quot;.txt&amp;quot;&lt;br /&gt;
  local fileW = io.open(LogName,  &amp;quot;a&amp;quot;)&lt;br /&gt;
  if fileW then&lt;br /&gt;
    fileW:write(xText .. &amp;quot;\n&amp;quot;)&lt;br /&gt;
    fileW:close()&lt;br /&gt;
  end -- if end&lt;br /&gt;
  Maindialog:UpdateLabelField(&amp;quot;Door.Alert&amp;quot;, &amp;quot;Note: Errors are logged in the CSF file folder.&amp;quot;)&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
===Write_CSV===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
Writes the values to a csv format file.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function Write_CSV(xFilename) -- Writes the values to a csv format file&lt;br /&gt;
 -- Usage: Write_CSV(&amp;quot;C:\\Path\\MyName.csv&amp;quot;)&lt;br /&gt;
 -- Door.CSVPath = dialog:GetTextField(&amp;quot;DoorCSVPath&amp;quot;)&lt;br /&gt;
 -- local filename = Path .. &amp;quot;\\&amp;quot; .. Name .. &amp;quot;.csv&amp;quot;&lt;br /&gt;
  local filename = xFilename&lt;br /&gt;
  local file = io.open(filename, &amp;quot;w&amp;quot;)&lt;br /&gt;
  if file then  -- if the file was opened&lt;br /&gt;
    file:write(&amp;quot;Count,Height,Width\n&amp;quot;)  -- Header Line&lt;br /&gt;
    if Door.Unit then&lt;br /&gt;
      file:write(&amp;quot;1,110,595\n&amp;quot;);    file:write(&amp;quot;1,150,75\n&amp;quot;);     file:write(&amp;quot;1,175,395\n&amp;quot;);     file:write(&amp;quot;1,140,495\n&amp;quot;)&lt;br /&gt;
      file:write(&amp;quot;1,175,445\n&amp;quot;);    file:write(&amp;quot;1,175,595\n&amp;quot;);    file:write(&amp;quot;2,200,100\n&amp;quot;);     file:write(&amp;quot;3,250,125\n&amp;quot;)&lt;br /&gt;
      file:write(&amp;quot;1,300,150\n&amp;quot;);    file:write(&amp;quot;2,350,175\n&amp;quot;);    file:write(&amp;quot;3,400,200\n&amp;quot;);     file:write(&amp;quot;1,450,225\n&amp;quot;)&lt;br /&gt;
      file:write(&amp;quot;2,500,250\n&amp;quot;);    file:write(&amp;quot;3,550,275\n&amp;quot;);    file:write(&amp;quot;1,600,300\n&amp;quot;);     file:write(&amp;quot;2,650,325\n&amp;quot;)&lt;br /&gt;
      file:write(&amp;quot;3,700,350\n&amp;quot;);    file:write(&amp;quot;1,750,375\n&amp;quot;);    file:write(&amp;quot;2,800,400\n&amp;quot;);     file:write(&amp;quot;3,850,425\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;1,900,450\n&amp;quot;);    file:write(&amp;quot;2,950,475\n&amp;quot;);    file:write(&amp;quot;3,1000,500\n&amp;quot;);    file:write(&amp;quot;1,1050,525\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;2,1100,550\n&amp;quot;);   file:write(&amp;quot;3,1150,575\n&amp;quot;);   file:write(&amp;quot;1,1200,600\n&amp;quot;);    file:write(&amp;quot;2,1250,625\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;3,1300,650\n&amp;quot;);   file:write(&amp;quot;1,1350,675\n&amp;quot;);   file:write(&amp;quot;2,1400,700\n&amp;quot;);    file:write(&amp;quot;3,1450,725\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;1,1500,750\n&amp;quot;);   file:write(&amp;quot;2,1550,775\n&amp;quot;);   file:write(&amp;quot;3,1600,800\n&amp;quot;);    file:write(&amp;quot;1,1650,825\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;2,1700,850\n&amp;quot;);   file:write(&amp;quot;3,1750,875\n&amp;quot;);   file:write(&amp;quot;1,1800,900\n&amp;quot;);    file:write(&amp;quot;2,1850,925\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;3,1900,950\n&amp;quot;);   file:write(&amp;quot;1,1950,975\n&amp;quot;);   file:write(&amp;quot;2,2000,1000\n&amp;quot;);   file:write(&amp;quot;3,2050,1025\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;1,2100,1050\n&amp;quot;);  file:write(&amp;quot;2,2150,1075\n&amp;quot;);  file:write(&amp;quot;3,2200,1100\n&amp;quot;);   file:write(&amp;quot;1,2250,1125\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;2,2300,1150\n&amp;quot;);  file:write(&amp;quot;3,2350,1175\n&amp;quot;);  file:write(&amp;quot;1,2400,1200\n&amp;quot;);   file:write(&amp;quot;2,2450,1225\n&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      file:write(&amp;quot;1,04.5000,23.2500\n&amp;quot;);  file:write(&amp;quot;1,06.0000,03.3125\n&amp;quot;);  file:write(&amp;quot;1,06.5000,15.5000\n&amp;quot;);  file:write(&amp;quot;1,05.3750,19.5000\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;1,07.1875,17.5000\n&amp;quot;);  file:write(&amp;quot;1,06.1875,23.5000\n&amp;quot;);  file:write(&amp;quot;2,07.8750,03.8750\n&amp;quot;);  file:write(&amp;quot;3,09.8750,05.0000\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;1,11.7500,05.8750\n&amp;quot;);  file:write(&amp;quot;2,13.7500,06.6750\n&amp;quot;);  file:write(&amp;quot;3,15.7500,07.8750\n&amp;quot;);  file:write(&amp;quot;1,17.1250,08.8250\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;2,19.5000,09.5000\n&amp;quot;);  file:write(&amp;quot;3,21.1250,10.3750\n&amp;quot;);  file:write(&amp;quot;1,23.6250,11.1250\n&amp;quot;);  file:write(&amp;quot;2,25.5000,12.1250\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;3,27.6250,13.7500\n&amp;quot;);  file:write(&amp;quot;1,29.5000,14.7500\n&amp;quot;);  file:write(&amp;quot;2,31.4375,15.7500\n&amp;quot;);  file:write(&amp;quot;3,33.4375,16.7500\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;1,35.4375,17.7500\n&amp;quot;);  file:write(&amp;quot;2,37.4375,18.6250\n&amp;quot;);  file:write(&amp;quot;3,39.3750,19.6250\n&amp;quot;);  file:write(&amp;quot;1,41.3750,20.6250\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;2,43.3750,21.6250\n&amp;quot;);  file:write(&amp;quot;3,45.1875,22.6250\n&amp;quot;);  file:write(&amp;quot;1,47.2500,23.6250\n&amp;quot;);  file:write(&amp;quot;2,49.1875,24.6250\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;3,51.1250,25.5000\n&amp;quot;);  file:write(&amp;quot;1,53.1250,26.5000\n&amp;quot;);  file:write(&amp;quot;2,55.1250,27.5000\n&amp;quot;);  file:write(&amp;quot;3,57.1250,28.5000\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;1,59.1250,29.5000\n&amp;quot;);  file:write(&amp;quot;2,61.2500,30.5000\n&amp;quot;);  file:write(&amp;quot;3,62.9375,31.4375\n&amp;quot;);  file:write(&amp;quot;1,64.9375,32.4375\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;2,66.9375,33.4375\n&amp;quot;);  file:write(&amp;quot;3,68.8125,34.4375\n&amp;quot;);  file:write(&amp;quot;1,70.8750,35.3750\n&amp;quot;);  file:write(&amp;quot;2,72.9375,36.4375\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;3,74.8750,37.4375\n&amp;quot;);  file:write(&amp;quot;1,76.9375,38.3750\n&amp;quot;);  file:write(&amp;quot;2,78.7500,39.3750\n&amp;quot;);  file:write(&amp;quot;3,80.7500,40.3750\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;1,82.6250,41.3750\n&amp;quot;);  file:write(&amp;quot;2,84.6250,42.3750\n&amp;quot;);  file:write(&amp;quot;3,86.6250,43.3750\n&amp;quot;);  file:write(&amp;quot;1,88.5000,44.2500\n&amp;quot;);&lt;br /&gt;
      file:write(&amp;quot;2,90.6250,45.2500\n&amp;quot;);  file:write(&amp;quot;3,92.6250,46.2500\n&amp;quot;);  file:write(&amp;quot;1,94.4375,47.2500\n&amp;quot;);  file:write(&amp;quot;2,95.4375,48.2500\n&amp;quot;)&lt;br /&gt;
    end -- if end&lt;br /&gt;
    file:close() -- closes the open file&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return  true&lt;br /&gt;
end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Text File Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
&lt;br /&gt;
===LengthOfFile===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns file line count&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function LengthOfFile(filename)&lt;br /&gt;
    Returns: number]]&lt;br /&gt;
    local len = 0&lt;br /&gt;
    if FileExists(filename) then&lt;br /&gt;
      local file = io.open(filename)&lt;br /&gt;
      if file then&lt;br /&gt;
      for _ in file:lines() do&lt;br /&gt;
        len = len + 1&lt;br /&gt;
      end&lt;br /&gt;
      file:close()&lt;br /&gt;
    end -- if end&lt;br /&gt;
    end&lt;br /&gt;
    return len&lt;br /&gt;
end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===NameValidater - Checks File Name for Valid Chars===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns file line count&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function NameValidater(FileName)&lt;br /&gt;
    local MyTrue = true&lt;br /&gt;
    local strlen = string.len(FileName)&lt;br /&gt;
    local strup = string.upper(FileName)&lt;br /&gt;
    local i = 1&lt;br /&gt;
    local y = &amp;quot;&amp;quot;&lt;br /&gt;
    while i &amp;lt;=  strlen do&lt;br /&gt;
      y = string.byte(string.sub(strup, i, i))&lt;br /&gt;
      if y == 32 then   --  Space&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
      elseif y == 45 then  -- Dash&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
      elseif y == 127 then  -- Delete&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
      elseif y == 126 then  -- Delete&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
&lt;br /&gt;
       elseif y == 123 then  -- Open brace&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
      elseif y == 124 then  -- Pipe&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
      elseif y == 125 then  -- Close brace&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
&lt;br /&gt;
      elseif  -- Illegal Filename Characters&lt;br /&gt;
      (y == 33) or -- !	Exclamation mark&lt;br /&gt;
      (y == 34) or -- &amp;quot;	Double Quotes&lt;br /&gt;
      (y == 35) or -- #	Hash&lt;br /&gt;
      (y == 36) or -- $	Dollar&lt;br /&gt;
      (y == 37) or -- %	Percent&lt;br /&gt;
      (y == 38) or -- &amp;amp;	Ampersand&lt;br /&gt;
      (y == 39) or -- '	Apostrophe&lt;br /&gt;
      (y == 42) or -- *	Asterisk&lt;br /&gt;
      (y == 43) or -- +	Plus&lt;br /&gt;
      (y == 44) or -- ,	Comma&lt;br /&gt;
      (y == 47) or -- /	Slash&lt;br /&gt;
      (y == 58) or -- :	Colon&lt;br /&gt;
      (y == 59) or -- ;	Semi-colon&lt;br /&gt;
      (y == 60) or -- &amp;lt;	Less than&lt;br /&gt;
      (y == 62) or -- &amp;gt;	Greater than&lt;br /&gt;
      (y == 63) or -- ?	Question mark&lt;br /&gt;
      (y == 64) or -- @	At&lt;br /&gt;
      (y == 92) or -- \	Backslash&lt;br /&gt;
      (y == 96) or -- `	Single Quotes&lt;br /&gt;
      (y == 123) or -- { Open brace&lt;br /&gt;
      (y == 124) or -- | Pipe&lt;br /&gt;
      (y == 125)    -- } Close brace&lt;br /&gt;
      then&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
      elseif (y &amp;lt;= 31) then -- Control Codes&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
      elseif (y &amp;gt;= 48) and (y &amp;lt;= 57) then -- Numbers&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
      elseif (y &amp;gt;= 65) and (y &amp;lt;= 90) then -- Uppercase A to Z&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
      elseif (y &amp;gt;= 97) and (y &amp;lt;= 122) then -- Lowercase A to Z&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
      elseif (y &amp;gt;= 65) and (y &amp;lt;= 90) then -- Uppercase A to Z&lt;br /&gt;
        MyTrue = false&lt;br /&gt;
        break&lt;br /&gt;
      end -- if end&lt;br /&gt;
      i = i + 1  end -- while end;&lt;br /&gt;
    return MyTrue&lt;br /&gt;
end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CopyFileFromTo===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
Copy Old File to Newfile&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function CopyFileFromTo(OldFile, NewFile)&lt;br /&gt;
    if FileExists(NewFile) then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;File copy &amp;quot; .. File .. &amp;quot; failed. \n\nFile found at: &amp;quot; .. NewFile  .. &amp;quot;\n&amp;quot; )&lt;br /&gt;
      return false&lt;br /&gt;
    elseif not FileExists(OldFile) then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;File copy of &amp;quot; .. File .. &amp;quot; failed. \n\nFile not found at: &amp;quot; .. OldFile .. &amp;quot;\n&amp;quot; )&lt;br /&gt;
      return false&lt;br /&gt;
    else&lt;br /&gt;
      local fileR = io.open(OldFile)      -- reader file&lt;br /&gt;
      local fileW = io.open(NewFile, &amp;quot;w&amp;quot;) -- writer file&lt;br /&gt;
      if fileR and fileW then  -- if both files are open&lt;br /&gt;
        for Line in fileR:lines() do&lt;br /&gt;
          fileW:write(Line .. &amp;quot;\n&amp;quot;)&lt;br /&gt;
        end -- for end&lt;br /&gt;
      end&lt;br /&gt;
      if fileR then fileR:close() end&lt;br /&gt;
      if fileW then fileW:close() end&lt;br /&gt;
      return true&lt;br /&gt;
    end -- for end&lt;br /&gt;
end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===ValidateName===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns True if the file name is safe to use&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function ValidateName(FileName) &lt;br /&gt;
  local MyTrue = true&lt;br /&gt;
  local strlen = string.len(FileName)&lt;br /&gt;
  local strup = string.upper(FileName)&lt;br /&gt;
  local i = 1&lt;br /&gt;
  local y = &amp;quot;&amp;quot;&lt;br /&gt;
  while i &amp;lt;=  strlen do&lt;br /&gt;
    y = string.byte(string.sub(strup, i, i))&lt;br /&gt;
    if y == 32 then -- Space&lt;br /&gt;
      MyTrue = true&lt;br /&gt;
    elseif y == 45 then -- hyphn&lt;br /&gt;
      MyTrue = true&lt;br /&gt;
    elseif (y &amp;gt;= 48) and (y &amp;lt;= 57) then -- numbers&lt;br /&gt;
      MyTrue = true&lt;br /&gt;
    elseif (y &amp;gt;= 65) and (y &amp;lt;= 90) then -- Uppercase&lt;br /&gt;
      MyTrue = true&lt;br /&gt;
    else&lt;br /&gt;
      MyTrue = false&lt;br /&gt;
      break&lt;br /&gt;
    end -- if end&lt;br /&gt;
    i = i + 1&lt;br /&gt;
  end -- while end&lt;br /&gt;
  return MyTrue&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===FileExists===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns True if file is found&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function FileExists(name)  &lt;br /&gt;
  -- call = ans = FileExists(&amp;quot;sample.txt&amp;quot;)&lt;br /&gt;
    local f=io.open(name,&amp;quot;r&amp;quot;)&lt;br /&gt;
    if f~=nil then io.close(f) return true else io.close(f) return false end&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===FileAccess===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns true if file is available for update.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function FileAccess(FileName) &lt;br /&gt;
    if (not(os.rename(FileName, FileName))) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, FileName, &amp;quot;The Gadget cannot access the &amp;quot;.. FileName ..&lt;br /&gt;
        &amp;quot; The OS has blocked write access. &amp;quot; ..&lt;br /&gt;
        &amp;quot;Verify the full path is correct and No application has the file open. &amp;quot;, &amp;quot;(1405)&amp;quot;)&lt;br /&gt;
        return false&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end -- if end&lt;br /&gt;
end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===IsDir===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns true if path is found&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function IsDir(path)                                  -- &lt;br /&gt;
  local function exists(file)&lt;br /&gt;
    local ok, err, code = os.rename(file, file)&lt;br /&gt;
    if not ok then&lt;br /&gt;
      if code == 13 then&lt;br /&gt;
        return true&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    return ok, err&lt;br /&gt;
  end&lt;br /&gt;
  return exists(path..&amp;quot;/&amp;quot;)&lt;br /&gt;
end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Sheetlabel===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns file line count of a txt (assic) file&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function Sheetlabel(Wpt, xTextHeight,  xThickness, xType, YY) -- Constructs sheet label&lt;br /&gt;
  local pt1Text = Point2D()&lt;br /&gt;
  local Pang    = 0.0&lt;br /&gt;
  local Tang    = 0.0&lt;br /&gt;
  if YY then&lt;br /&gt;
    pt1Text = Polar2D(Polar2D(Wpt, 90.0,  YY), 90.0,  6.0 * JimAndi.Cal)&lt;br /&gt;
    Pang = 270.0&lt;br /&gt;
    Tang = 0.0&lt;br /&gt;
  else&lt;br /&gt;
    if Material.Orientation == &amp;quot;V&amp;quot; then&lt;br /&gt;
      pt1Text = Polar2D(Wpt, 90.0, Milling.MaterialBlockWidth + (4.0 * JimAndi.Cal))&lt;br /&gt;
    else&lt;br /&gt;
      pt1Text = Polar2D(Wpt, 90.0,  Milling.MaterialBlockHeight + (4.0 * JimAndi.Cal))&lt;br /&gt;
    end&lt;br /&gt;
    Pang = 270.0&lt;br /&gt;
    Tang = 0.0&lt;br /&gt;
  end&lt;br /&gt;
  DrawWriter(Project.ProgramName, pt1Text, Milling.TextHeight * 3.0, JimAndi.LNDrawNotes, Tang)&lt;br /&gt;
  pt1Text = Polar2D(pt1Text, Pang, Milling.TextHeight * 3.35)&lt;br /&gt;
  DrawWriter(&amp;quot;Cabinet ID: &amp;quot; .. Project.DrawerID, pt1Text, JimAndi.TextHeight * 2.0, JimAndi.LNDrawNotes, Tang)&lt;br /&gt;
  pt1Text = Polar2D(pt1Text, Pang, Milling.TextHeight * 2.75)&lt;br /&gt;
  DrawWriter(&amp;quot;Cabinet Name: &amp;quot; .. Project.CabinetName, pt1Text, JimAndi.TextHeight * 2.0, JimAndi.LNDrawNotes, Tang)&lt;br /&gt;
  pt1Text = Polar2D(pt1Text, Pang, Milling.TextHeight * 2.75)&lt;br /&gt;
  if xThickness then&lt;br /&gt;
    DrawWriter(&amp;quot;Material: &amp;quot; .. xThickness .. &amp;quot; &amp;quot; .. xType, pt1Text, JimAndi.TextHeight * 2.0, JimAndi.LNDrawNotes, Tang)&lt;br /&gt;
  end -- if end&lt;br /&gt;
end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DiskRights===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
Returns true if you have write access to path.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function DiskRights(path)                             -- &lt;br /&gt;
  local xx = io.open(path, &amp;quot;w&amp;quot;)&lt;br /&gt;
  if xx == nil then&lt;br /&gt;
      io.close()&lt;br /&gt;
      return false&lt;br /&gt;
  else&lt;br /&gt;
      xx:close()&lt;br /&gt;
      return true&lt;br /&gt;
  end&lt;br /&gt;
end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Geometry Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
&lt;br /&gt;
===SheetNew===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
&lt;br /&gt;
Adds a new sheet to the drawing&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function SheetNew()                                     -- Adds a new sheet to the drawing&lt;br /&gt;
  if GetVersion() &amp;gt;= 10.5 then then&lt;br /&gt;
    local layer_manager = Milling.job.LayerManager&lt;br /&gt;
    -- get current sheet count - note sheet 0 the default sheet counts as one sheet&lt;br /&gt;
    local orig_num_sheets = layer_manager.NumberOfSheets&lt;br /&gt;
    -- get current active sheet index&lt;br /&gt;
    local orig_active_sheet_index = layer_manager.ActiveSheetIndex&lt;br /&gt;
    -- set active sheet to last sheet&lt;br /&gt;
    local num_sheets = layer_manager.NumberOfSheets&lt;br /&gt;
    layer_manager.ActiveSheetIndex = num_sheets - 1&lt;br /&gt;
    -- Add a new sheet&lt;br /&gt;
    layer_manager:AddNewSheet()&lt;br /&gt;
    -- set active sheet to last sheet we just added&lt;br /&gt;
    num_sheets = layer_manager.NumberOfSheets&lt;br /&gt;
    layer_manager.ActiveSheetIndex = num_sheets - 1&lt;br /&gt;
    Milling.job:Refresh2DView()&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end  &amp;lt;/nowiki&amp;gt; &lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetDiameterAndCentre===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function GetDiameterAndCentre(cadcontour, point2d)&lt;br /&gt;
  local contour = cadcontour:GetContour()&lt;br /&gt;
  local arc = contour:GetFirstSpan()&lt;br /&gt;
  local point3d = Point3D();&lt;br /&gt;
  arc = CastSpanToArcSpan(arc)&lt;br /&gt;
  local diameter = arc:RadiusAndCentre(point3d) * 2.0&lt;br /&gt;
  point2d = Point2D(point3d.x, point3d.y)&lt;br /&gt;
  -- MessageBox(&amp;quot;Diameter = &amp;quot; .. diameter)&lt;br /&gt;
  return diameter, point2d&lt;br /&gt;
end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===IsCircle===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function IsCircle(cadcontour)                           -- Returns True if conture is a circle&lt;br /&gt;
  local contour = cadcontour:GetContour()&lt;br /&gt;
  -- Does it consist only of arcs?&lt;br /&gt;
  if contour.ContainsBeziers then&lt;br /&gt;
    return false&lt;br /&gt;
  end&lt;br /&gt;
  if not contour.ContainsArcs then&lt;br /&gt;
    return false&lt;br /&gt;
  end&lt;br /&gt;
  -- Does is contain 4 contours?&lt;br /&gt;
  if contour.Count ~= 4 then&lt;br /&gt;
    return false&lt;br /&gt;
  end&lt;br /&gt;
  -- Check the arcs end and initial points make a square.&lt;br /&gt;
  local arcs = {}&lt;br /&gt;
  local count = 1;&lt;br /&gt;
  local pos = contour:GetHeadPosition()&lt;br /&gt;
  local object&lt;br /&gt;
  while pos ~= nil do&lt;br /&gt;
    object, pos = contour:GetNext(pos)&lt;br /&gt;
    arcs[count] = object&lt;br /&gt;
    count = count + 1&lt;br /&gt;
  end&lt;br /&gt;
  local x_1 =(arcs[1]).StartPoint2D.x&lt;br /&gt;
  local y_1 =(arcs[1]).StartPoint2D.y&lt;br /&gt;
  local x_3 =(arcs[3]).StartPoint2D.x&lt;br /&gt;
  local y_3 =(arcs[3]).StartPoint2D.y&lt;br /&gt;
  local x_2 =(arcs[2]).StartPoint2D.x&lt;br /&gt;
  local y_2 =(arcs[2]).StartPoint2D.y&lt;br /&gt;
  local x_4 =(arcs[4]).StartPoint2D.x&lt;br /&gt;
  local y_4 =(arcs[4]).StartPoint2D.y&lt;br /&gt;
  local horizontal_distance = (x_1 - x_3)*(x_1 - x_3) + (y_1 - y_3)*(y_1 - y_3)&lt;br /&gt;
  local vertical_distance = (x_4 - x_2)*(x_4 - x_2) + (y_2 - y_4)*(y_2 - y_4)&lt;br /&gt;
  if math.abs(horizontal_distance - vertical_distance) &amp;gt; 0.04 then&lt;br /&gt;
    return false&lt;br /&gt;
  end&lt;br /&gt;
  -- Check the bulge factor is 90&lt;br /&gt;
  local bulge = 0;&lt;br /&gt;
  for _, arc_span in ipairs(arcs) do&lt;br /&gt;
    bulge = CastSpanToArcSpan(arc_span).Bulge;&lt;br /&gt;
    if math.abs(math.abs(bulge)  - g_bulge90) &amp;gt; 0.04 then&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  return true&lt;br /&gt;
end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===SheetSet===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function SheetSet(Name)                    -- Move focus to a named sheet&lt;br /&gt;
  local job = VectricJob()&lt;br /&gt;
  local sheet_manager = job.SheetManager&lt;br /&gt;
  local sheet_ids = sheet_manager:GetSheetIds()&lt;br /&gt;
  for id in sheet_ids do&lt;br /&gt;
    if(sheet_manager:GetSheetName(id) == Name) then&lt;br /&gt;
    sheet_manager.ActiveSheetId = id&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===SheetNextSize===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function SheetNextSize(X, Y)               -- Make New Sheet to size (x, y)&lt;br /&gt;
  if X == nil then&lt;br /&gt;
    X = Milling.MaterialBlockWidth&lt;br /&gt;
  else&lt;br /&gt;
    X = X + (2 * Milling.Cal)&lt;br /&gt;
  end&lt;br /&gt;
  if Y == nil then&lt;br /&gt;
    Y = Milling.MaterialBlockHeight&lt;br /&gt;
  else&lt;br /&gt;
    Y = Y + (2 * Milling.Cal)&lt;br /&gt;
  end&lt;br /&gt;
  Milling.Sheet = Milling.Sheet + 1&lt;br /&gt;
  local sheet_manager = Milling.job.SheetManager&lt;br /&gt;
  local sheet_ids = sheet_manager:GetSheetIds()&lt;br /&gt;
  for id in sheet_ids do&lt;br /&gt;
    if(sheet_manager:GetSheetName(id) == &amp;quot;Sheet 1&amp;quot;) then&lt;br /&gt;
     sheet_manager:CreateSheets(1, id, Box2D(Point2D(0, 0), Point2D(X, Y)))&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  SheetSet(&amp;quot;Sheet &amp;quot; .. tostring(Milling.Sheet))&lt;br /&gt;
  return true&lt;br /&gt;
end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetPolarAngle===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function GetPolarAngle(Start, Corner, End)           -- Returns the Polar Angle&lt;br /&gt;
  local function GetPolarDirection(point1, point2)   &lt;br /&gt;
    local ang = math.abs(math.deg(math.atan((point2.Y - point1.Y) / (point2.X - point1.X))))&lt;br /&gt;
    if point1.X &amp;lt; point2.X then&lt;br /&gt;
      if point1.Y &amp;lt; point2.Y then&lt;br /&gt;
        ang = ang + 0.0&lt;br /&gt;
      else&lt;br /&gt;
        ang = 360.0 - ang&lt;br /&gt;
      end -- if end&lt;br /&gt;
    else&lt;br /&gt;
      if point1.Y &amp;lt; point2.Y then&lt;br /&gt;
        ang = 180.0 - ang&lt;br /&gt;
      else&lt;br /&gt;
        ang = ang + 180.0&lt;br /&gt;
      end -- if end&lt;br /&gt;
    end -- if end&lt;br /&gt;
    if ang &amp;gt;=360 then&lt;br /&gt;
      ang = ang -360.0&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return ang&lt;br /&gt;
  end -- function end&lt;br /&gt;
  return  math.abs(GetPolarDirection(Corner, Start) - GetPolarDirection(Corner, End))&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetOrientation===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function GetOrientation(point1, point2)                 -- Orientation of left, right, up or down&lt;br /&gt;
  if DecimalPlaces(point1.X,8) == DecimalPlaces(point2.X,8) then&lt;br /&gt;
    if point1.Y &amp;lt; point2.Y then&lt;br /&gt;
      return 90.0&lt;br /&gt;
    else&lt;br /&gt;
      return 270.0&lt;br /&gt;
    end&lt;br /&gt;
  elseif DecimalPlaces(point1.Y,8) == DecimalPlaces(point2.Y,8) then&lt;br /&gt;
    if point1.X &amp;lt; point2.X then&lt;br /&gt;
      return 0.0&lt;br /&gt;
    else&lt;br /&gt;
      return 180.0&lt;br /&gt;
    end&lt;br /&gt;
  else&lt;br /&gt;
    return nil&lt;br /&gt;
  end&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetPolarDirection===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function GetPolarDirection(point1, point2)              -- Retuens and amgle from two points&lt;br /&gt;
  local ang = math.abs(math.deg(math.atan((point2.Y - point1.Y) / (point2.X - point1.X))))&lt;br /&gt;
  if point1.X &amp;lt; point2.X then&lt;br /&gt;
    if point1.Y &amp;lt; point2.Y then&lt;br /&gt;
      ang = ang + 0.0&lt;br /&gt;
    else&lt;br /&gt;
      ang = 360.0 - ang&lt;br /&gt;
    end -- if end&lt;br /&gt;
  else&lt;br /&gt;
    if point1.Y &amp;lt; point2.Y then&lt;br /&gt;
      ang = 180.0 - ang&lt;br /&gt;
    else&lt;br /&gt;
      ang = ang + 180.0&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- if end&lt;br /&gt;
  if ang &amp;gt;=360 then&lt;br /&gt;
    ang = ang -360.0&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return ang&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CenterArc===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function CenterArc(A, B, RadiusD)                       -- Returns 2DPoint from Arc point and Radius&lt;br /&gt;
  local radius = ((tonumber(RadiusD) or 0) * g_var.scl)&lt;br /&gt;
  local horda = (A - B).Length&lt;br /&gt;
  if math.abs(radius) &amp;lt; (horda / 2) and radius ~= 0 then&lt;br /&gt;
--D(&amp;quot;Too small radius &amp;quot; .. radius .. &amp;quot;\nreplaced by the smallest possible &amp;quot; .. (horda / 2))&lt;br /&gt;
    radius = (horda / 2)&lt;br /&gt;
  end&lt;br /&gt;
  return Point2D(((A.x + B.x) / 2 + (B.y - A.y) * math.sqrt(math.abs(radius) ^ 2 - (horda / 2) ^ 2) / horda), ((A.y + B.y) / 2 + (A.x - B.x) * math.sqrt(math.abs(radius) ^ 2 - (horda / 2) ^ 2) / horda))&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Polar2D===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
&lt;br /&gt;
The Polar2D function will calculate a new point in space based on a Point of reference, Angle of direction, and Projected distance. Returns 2DPoint from Known Point, Angle direction, and Projected distance.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function Polar2D(pt, ang, dis)                        &lt;br /&gt;
-- The Polar2D function will calculate a new point in space based on a Point of reference, Angle of direction, and Projected distance.&lt;br /&gt;
-- ::''Returns a 2Dpoint(x, y)''&lt;br /&gt;
  return Point2D((pt.X + dis * math.cos(math.rad(ang))), (pt.Y + dis * math.sin(math.rad(ang))))&lt;br /&gt;
end -- End Function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetDistance===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
&lt;br /&gt;
Returns Double from two Points&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function GetDistance(objA, objB)                        -- Returns Double from two Points&lt;br /&gt;
  local xDist = objB.x - objA.x&lt;br /&gt;
  local yDist = objB.y - objA.y&lt;br /&gt;
  return math.sqrt((xDist ^ 2) + (yDist ^ 2))&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetAngle===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  -- ===========================================================]]&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;function GetAngle(point1, point2)&lt;br /&gt;
  local ang = math.abs(math.deg(math.atan((point2.Y - point1.Y) / (point2.X - point1.X))))&lt;br /&gt;
  if point1.X &amp;lt; point2.X then&lt;br /&gt;
    if point1.Y &amp;lt; point2.Y then&lt;br /&gt;
      ang = ang + 0.0&lt;br /&gt;
    else&lt;br /&gt;
      ang = 360.0 - ang&lt;br /&gt;
    end -- if end&lt;br /&gt;
  else&lt;br /&gt;
    if point1.Y &amp;lt; point2.Y then&lt;br /&gt;
      ang = 180.0 - ang&lt;br /&gt;
    else&lt;br /&gt;
      ang = ang + 180.0&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- if end&lt;br /&gt;
  if ang &amp;gt;=360.0 then&lt;br /&gt;
    ang = ang -360.0&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return ang&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Arc2Bulge===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  -- ===========================================================]]&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;function Arc2Bulge(p1, p2, Rad)                         -- Returns the Bulge factor for an arc&lt;br /&gt;
  local chord = math.sqrt(((p2.x - p1.x) ^ 2) + ((p2.y - p1.y) ^ 2))&lt;br /&gt;
  local seg = (Rad - (0.5 * (math.sqrt((4.0 * Rad^2) - chord^2))))&lt;br /&gt;
  local bulge = (2 * seg) / chord&lt;br /&gt;
  return bulge&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===TrigIt===&lt;br /&gt;
Calculates Right Angle&lt;br /&gt;
&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function TrigIt()                                       -- Calculates Right Angle&lt;br /&gt;
-- ==Trig Function==&lt;br /&gt;
-- VECTRIC LUA SCRIPT&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
-- Gadgets are an entirely optional add-in to Vectric's core software products.&lt;br /&gt;
-- They are provided 'as-is', without any express or implied warranty, and you&lt;br /&gt;
--   make use of them entirely at your own risk.&lt;br /&gt;
-- In no event will the author(s) or Vectric Ltd. be held liable for any damages&lt;br /&gt;
--   arising from their use.&lt;br /&gt;
-- Permission is granted to anyone to use this software for any purpose,&lt;br /&gt;
-- including commercial applications, and to alter it and redistribute it freely,&lt;br /&gt;
-- subject to the following restrictions:&lt;br /&gt;
-- 1. The origin of this software must not be misrepresented; you must not&lt;br /&gt;
--    claim that you wrote the original software.&lt;br /&gt;
-- 2. If you use this software in a product, an acknowledgement in the product&lt;br /&gt;
--    documentation would be appreciated but is not required.&lt;br /&gt;
-- 3. Altered source versions must be plainly marked as such, and must not be&lt;br /&gt;
--    misrepresented as being the original software.&lt;br /&gt;
-- 4. This notice may not be removed or altered from any source distribution.&lt;br /&gt;
--&lt;br /&gt;
-- Right Triangle TrigFunction is written by Jim Anderson of Houston Texas 2020&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
-- Code Debugger&lt;br /&gt;
-- require(&amp;quot;mobdebug&amp;quot;).start()&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
-- Global Variables --&lt;br /&gt;
    Trig = {}&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
  function TrigTest() -- Test the All Right Angle&lt;br /&gt;
    TrigClear()&lt;br /&gt;
    Trig.A  =  0.0&lt;br /&gt;
    Trig.B  =  0.0&lt;br /&gt;
    Trig.C  = 90.0&lt;br /&gt;
    Trig.Opp =  3.0  -- Rise  or (B2C)&lt;br /&gt;
    Trig.Adj =  4.0  -- Base  or (A2C)&lt;br /&gt;
    Trig.Hyp =  0.0  -- Slope or (A2B)&lt;br /&gt;
    Trig.Slope =  0.0&lt;br /&gt;
    Trig.Area =  0.0&lt;br /&gt;
    Trig.OutRadius =  0.0&lt;br /&gt;
    Trig.InRadius =  0.0&lt;br /&gt;
    Trig.Parameter =  0.0&lt;br /&gt;
    TrigIt()&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Test 1: \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.A  =  &amp;quot; .. tostring(Trig.A) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.B  =  &amp;quot; .. tostring(Trig.B) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.C  =  &amp;quot; .. tostring(Trig.C) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Opp = * &amp;quot; .. tostring(Trig.Opp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Adj = * &amp;quot; .. tostring(Trig.Adj) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Hyp =  &amp;quot; .. tostring(Trig.Hyp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Slope =  &amp;quot; .. tostring(Trig.Slope) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Area =  &amp;quot; .. tostring(Trig.Area) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Parameter =  &amp;quot; .. tostring(Trig.Parameter) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.OutRadius =  &amp;quot; .. tostring(Trig.OutRadius) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.InRadius =  &amp;quot; .. tostring(Trig.InRadius) .. &amp;quot; \n&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    -- =====================================================]]&lt;br /&gt;
    TrigClear()&lt;br /&gt;
    Trig.A  =  0.0&lt;br /&gt;
    Trig.B  =  0.0&lt;br /&gt;
    Trig.C  = 90.0&lt;br /&gt;
    Trig.Opp =  0.0  -- Rise  or (B2C)&lt;br /&gt;
    Trig.Adj =  4.0  -- Base  or (A2C)&lt;br /&gt;
    Trig.Hyp =  5.0  -- Slope or (A2B)&lt;br /&gt;
    Trig.Slope =  0.0&lt;br /&gt;
    Trig.Area =  0.0&lt;br /&gt;
    Trig.OutRadius =  0.0&lt;br /&gt;
    Trig.InRadius =  0.0&lt;br /&gt;
    Trig.Parameter =  0.0&lt;br /&gt;
    TrigIt()&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Test 2: \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.A  =  &amp;quot; .. tostring(Trig.A) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.B  =  &amp;quot; .. tostring(Trig.B) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.C  =  &amp;quot; .. tostring(Trig.C) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Opp = * &amp;quot; .. tostring(Trig.Opp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Adj = * &amp;quot; .. tostring(Trig.Adj) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Hyp =  &amp;quot; .. tostring(Trig.Hyp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Slope =  &amp;quot; .. tostring(Trig.Slope) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Area =  &amp;quot; .. tostring(Trig.Area) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Parameter =  &amp;quot; .. tostring(Trig.Parameter) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.OutRadius =  &amp;quot; .. tostring(Trig.OutRadius) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.InRadius =  &amp;quot; .. tostring(Trig.InRadius) .. &amp;quot; \n&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    -- =====================================================]]&lt;br /&gt;
    TrigClear()&lt;br /&gt;
    Trig.A  =  0.0&lt;br /&gt;
    Trig.B  =  0.0&lt;br /&gt;
    Trig.C  = 90.0&lt;br /&gt;
    Trig.Opp =  3.0  -- Rise  or (B2C)&lt;br /&gt;
    Trig.Adj =  0.0  -- Base  or (A2C)&lt;br /&gt;
    Trig.Hyp =  5.0  -- Slope or (A2B)&lt;br /&gt;
    Trig.Slope =  0.0&lt;br /&gt;
    Trig.Area =  0.0&lt;br /&gt;
    Trig.OutRadius =  0.0&lt;br /&gt;
    Trig.InRadius =  0.0&lt;br /&gt;
    Trig.Parameter =  0.0&lt;br /&gt;
    TrigIt()&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Test 3: \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.A  =  &amp;quot; .. tostring(Trig.A) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.B  =  &amp;quot; .. tostring(Trig.B) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.C  =  &amp;quot; .. tostring(Trig.C) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Opp = * &amp;quot; .. tostring(Trig.Opp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Adj =  &amp;quot; .. tostring(Trig.Adj) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Hyp = * &amp;quot; .. tostring(Trig.Hyp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Slope =  &amp;quot; .. tostring(Trig.Slope) .. &amp;quot; on 12 inch \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Area =  &amp;quot; .. tostring(Trig.Area) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Parameter =  &amp;quot; .. tostring(Trig.Parameter) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.OutRadius =  &amp;quot; .. tostring(Trig.OutRadius) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.InRadius =  &amp;quot; .. tostring(Trig.InRadius) .. &amp;quot; \n&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    -- =====================================================]]&lt;br /&gt;
    TrigClear()&lt;br /&gt;
    Trig.A  =  36.86897645844&lt;br /&gt;
    Trig.B  =  0.0&lt;br /&gt;
    Trig.C  = 90.0&lt;br /&gt;
    Trig.Opp =  3.0  -- Rise  or (B2C)&lt;br /&gt;
    Trig.Adj =  0.0  -- Base  or (A2C)&lt;br /&gt;
    Trig.Hyp =  0.0  -- Slope or (A2B)&lt;br /&gt;
    Trig.Slope =  0.0&lt;br /&gt;
    Trig.Area =  0.0&lt;br /&gt;
    Trig.OutRadius =  0.0&lt;br /&gt;
    Trig.InRadius =  0.0&lt;br /&gt;
    Trig.Parameter =  0.0&lt;br /&gt;
    TrigIt()&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Test 4: \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.A  = * &amp;quot; .. tostring(Trig.A) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.B  =  &amp;quot; .. tostring(Trig.B) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.C  =  &amp;quot; .. tostring(Trig.C) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Opp = * &amp;quot; .. tostring(Trig.Opp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Adj =  &amp;quot; .. tostring(Trig.Adj) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Hyp =  &amp;quot; .. tostring(Trig.Hyp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Slope =  &amp;quot; .. tostring(Trig.Slope) .. &amp;quot; on 12 inch \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Area =  &amp;quot; .. tostring(Trig.Area) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Parameter =  &amp;quot; .. tostring(Trig.Parameter) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.OutRadius =  &amp;quot; .. tostring(Trig.OutRadius) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.InRadius =  &amp;quot; .. tostring(Trig.InRadius) .. &amp;quot; \n&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    -- =====================================================]]&lt;br /&gt;
    TrigClear()&lt;br /&gt;
    Trig.A  =  36.86897645844&lt;br /&gt;
    Trig.B  =  0.0&lt;br /&gt;
    Trig.C  = 90.0&lt;br /&gt;
    Trig.Opp =  0.0  -- Rise  or (B2C)&lt;br /&gt;
    Trig.Adj =  4.0  -- Base  or (A2C)&lt;br /&gt;
    Trig.Hyp =  0.0  -- Slope or (A2B)&lt;br /&gt;
    Trig.Slope =  0.0&lt;br /&gt;
    Trig.Area =  0.0&lt;br /&gt;
    Trig.OutRadius =  0.0&lt;br /&gt;
    Trig.InRadius =  0.0&lt;br /&gt;
    Trig.Parameter =  0.0&lt;br /&gt;
    TrigIt()&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Test 5: \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.A  = * &amp;quot; .. tostring(Trig.A) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.B  =  &amp;quot; .. tostring(Trig.B) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.C  =  &amp;quot; .. tostring(Trig.C) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Opp =  &amp;quot; .. tostring(Trig.Opp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Adj = * &amp;quot; .. tostring(Trig.Adj) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Hyp =  &amp;quot; .. tostring(Trig.Hyp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Slope =  &amp;quot; .. tostring(Trig.Slope) .. &amp;quot; on 12 inch \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Area =  &amp;quot; .. tostring(Trig.Area) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Parameter =  &amp;quot; .. tostring(Trig.Parameter) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.OutRadius =  &amp;quot; .. tostring(Trig.OutRadius) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.InRadius =  &amp;quot; .. tostring(Trig.InRadius) .. &amp;quot; \n&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    -- =====================================================]]&lt;br /&gt;
    TrigClear()&lt;br /&gt;
    Trig.A  =  36.86897645844&lt;br /&gt;
    Trig.B  =  0.0&lt;br /&gt;
    Trig.C  = 90.0&lt;br /&gt;
    Trig.Opp =  0.0  -- Rise  or (B2C)&lt;br /&gt;
    Trig.Adj =  0.0  -- Base  or (A2C)&lt;br /&gt;
    Trig.Hyp =  5.0  -- Slope or (A2B)&lt;br /&gt;
    Trig.Slope =  0.0&lt;br /&gt;
    Trig.Area =  0.0&lt;br /&gt;
    Trig.OutRadius =  0.0&lt;br /&gt;
    Trig.InRadius =  0.0&lt;br /&gt;
    Trig.Parameter =  0.0&lt;br /&gt;
    TrigIt()&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Test 6: \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.A  = * &amp;quot; .. tostring(Trig.A) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.B  =  &amp;quot; .. tostring(Trig.B) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.C  =  &amp;quot; .. tostring(Trig.C) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Opp =  &amp;quot; .. tostring(Trig.Opp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Adj =  &amp;quot; .. tostring(Trig.Adj) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Hyp = * &amp;quot; .. tostring(Trig.Hyp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Slope =  &amp;quot; .. tostring(Trig.Slope) .. &amp;quot; on 12 inch \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Area =  &amp;quot; .. tostring(Trig.Area) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Parameter =  &amp;quot; .. tostring(Trig.Parameter) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.OutRadius =  &amp;quot; .. tostring(Trig.OutRadius) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.InRadius =  &amp;quot; .. tostring(Trig.InRadius) .. &amp;quot; \n&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    TrigClear()&lt;br /&gt;
    Trig.A  =  0.0&lt;br /&gt;
    Trig.B  =  0.0&lt;br /&gt;
    Trig.C  = 90.0&lt;br /&gt;
    Trig.Opp =  3.0  -- Rise  or (B2C)&lt;br /&gt;
    Trig.Adj =  0.0  -- Base  or (A2C)&lt;br /&gt;
    Trig.Hyp =  0.0  -- Slope or (A2B)&lt;br /&gt;
    Trig.Slope =  9.0&lt;br /&gt;
    Trig.Area =  0.0&lt;br /&gt;
    Trig.OutRadius =  0.0&lt;br /&gt;
    Trig.InRadius =  0.0&lt;br /&gt;
    Trig.Parameter =  0.0&lt;br /&gt;
    TrigIt()&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Test 7: \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.A  =  &amp;quot; .. tostring(Trig.A) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.B  =  &amp;quot; .. tostring(Trig.B) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.C  =  &amp;quot; .. tostring(Trig.C) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Opp = * &amp;quot; .. tostring(Trig.Opp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Adj =  &amp;quot; .. tostring(Trig.Adj) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Hyp =  &amp;quot; .. tostring(Trig.Hyp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Slope = * &amp;quot; .. tostring(Trig.Slope) .. &amp;quot; on 12 inch \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Parameter =  &amp;quot; .. tostring(Trig.Parameter) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Area =  &amp;quot; .. tostring(Trig.Area) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Parameter =  &amp;quot; .. tostring(Trig.Parameter) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Circumscribing =  &amp;quot; .. tostring(Trig.Circumscribing) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
    &amp;quot; Trig.Inscribing =  &amp;quot; .. tostring(Trig.Inscribing) .. &amp;quot; \n&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    -- =====================================================]]&lt;br /&gt;
    TrigClear()&lt;br /&gt;
    Trig.A  =  0.0&lt;br /&gt;
    Trig.B  =  0.0&lt;br /&gt;
    Trig.C  = 90.0&lt;br /&gt;
    Trig.Opp =  0.0  -- Rise  or (B2C)&lt;br /&gt;
    Trig.Adj =  0.0  -- Base  or (A2C)&lt;br /&gt;
    Trig.Hyp =  0.0  -- Slope or (A2B)&lt;br /&gt;
    Trig.Slope =  9.0&lt;br /&gt;
    Trig.Area =  0.0&lt;br /&gt;
    Trig.OutRadius =  0.0&lt;br /&gt;
    Trig.InRadius =  0.0&lt;br /&gt;
    Trig.Parameter =  0.0&lt;br /&gt;
    TrigIt()&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Test Error: \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.A  =  &amp;quot; .. tostring(Trig.A) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.B  =  &amp;quot; .. tostring(Trig.B) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.C  =  &amp;quot; .. tostring(Trig.C) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.Opp = * &amp;quot; .. tostring(Trig.Opp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.Adj =  &amp;quot; .. tostring(Trig.Adj) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.Hyp =  &amp;quot; .. tostring(Trig.Hyp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.Slope = * &amp;quot; .. tostring(Trig.Slope) .. &amp;quot; on 12 inch \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.Parameter =  &amp;quot; .. tostring(Trig.Parameter) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.Area =  &amp;quot; .. tostring(Trig.Area) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.Parameter =  &amp;quot; .. tostring(Trig.Parameter) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.Circumscribing =  &amp;quot; .. tostring(Trig.Circumscribing) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
      &amp;quot; Trig.Inscribing =  &amp;quot; .. tostring(Trig.Inscribing) .. &amp;quot; \n&amp;quot;&lt;br /&gt;
    )&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end --&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
  function TrigClear()   -- Clears and resets Trig Table&lt;br /&gt;
    Trig.A  =  0.0&lt;br /&gt;
    Trig.B  =  0.0&lt;br /&gt;
    Trig.C  = 90.0&lt;br /&gt;
    Trig.Opp =  0.0  -- Rise  or (B2C)&lt;br /&gt;
    Trig.Adj =  0.0  -- Base  or (A2C)&lt;br /&gt;
    Trig.Hyp =  0.0  -- Slope or (A2B)&lt;br /&gt;
    Trig.Slope =  0.0&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
      local function BSA()&lt;br /&gt;
        Trig.B  = (Trig.C - Trig.A)&lt;br /&gt;
        Trig.Slope = math.tan(math.rad(Trig.A)) * 12.0&lt;br /&gt;
        Trig.Area =  (Trig.Opp * Trig.Adj) * 0.5&lt;br /&gt;
        Trig.Inscribing = ((Trig.Opp + Trig.Adj) - Trig.Hyp) * 0.5&lt;br /&gt;
        Trig.Circumscribing =  Trig.Hyp * 0.5&lt;br /&gt;
        Trig.Parameter = Trig.Opp + Trig.Adj + Trig.Hyp&lt;br /&gt;
      end&lt;br /&gt;
      if Trig.A == 0.0 and Trig.B &amp;gt; 0.0 and Trig.Slope == 0.0 then&lt;br /&gt;
        Trig.A = Trig.C - Trig.B&lt;br /&gt;
      elseif Trig.A == 0.0 and Trig.B == 0.0 and Trig.Slope &amp;gt; 0.0 then&lt;br /&gt;
        Trig.A = math.deg(math.atan(Trig.Slope / 12.0))&lt;br /&gt;
      end -- if end&lt;br /&gt;
-- test 4&lt;br /&gt;
      if (Trig.A &amp;gt; 0.0) and (Trig.Opp &amp;gt;  0.0) then -- A and Rise or (B2C)&lt;br /&gt;
        Trig.Adj =  Trig.Opp / (math.tan(math.rad(Trig.A)))&lt;br /&gt;
        Trig.Hyp = math.sqrt((Trig.Opp * Trig.Opp ) + ( Trig.Adj * Trig.Adj))&lt;br /&gt;
        BSA()&lt;br /&gt;
        return true&lt;br /&gt;
      -- test 6&lt;br /&gt;
      elseif (Trig.A &amp;gt; 0.0) and (Trig.Hyp &amp;gt;  0.0)  then -- A and Slope or (A2B)&lt;br /&gt;
        Trig.Adj = math.cos(math.rad(Trig.A)) * Trig.Hyp&lt;br /&gt;
        Trig.Opp = math.sqrt((Trig.Hyp * Trig.Hyp ) - ( Trig.Adj * Trig.Adj))&lt;br /&gt;
        BSA()&lt;br /&gt;
        return true&lt;br /&gt;
      -- test 5&lt;br /&gt;
      elseif (Trig.A &amp;gt; 0.0) and (Trig.Adj &amp;gt;  0.0)  then -- A and Base or (A2C)&lt;br /&gt;
        Trig.Opp = math.tan(math.rad(Trig.A)) * Trig.Adj&lt;br /&gt;
        Trig.Hyp = math.sqrt((Trig.Opp * Trig.Opp ) + ( Trig.Adj * Trig.Adj))&lt;br /&gt;
        BSA()&lt;br /&gt;
        return true&lt;br /&gt;
        -- test 1&lt;br /&gt;
      elseif (Trig.Opp &amp;gt;  0.0) and (Trig.Adj &amp;gt;  0.0) then -- Rise and Base&lt;br /&gt;
        Trig.Hyp = math.sqrt((Trig.Opp * Trig.Opp ) + ( Trig.Adj * Trig.Adj))&lt;br /&gt;
        Trig.A  = math.deg(math.atan(Trig.Opp / Trig.Adj))&lt;br /&gt;
        BSA()&lt;br /&gt;
        return true&lt;br /&gt;
      elseif (Trig.Adj &amp;gt;  0.0) and (Trig.Hyp &amp;gt;  0.0) then -- Rise and Slope&lt;br /&gt;
-- test 2&lt;br /&gt;
        Trig.Opp = math.sqrt((Trig.Hyp * Trig.Hyp ) - ( Trig.Adj * Trig.Adj))&lt;br /&gt;
        Trig.A  = math.deg(math.atan(Trig.Opp / Trig.Adj))&lt;br /&gt;
        BSA()&lt;br /&gt;
        return true&lt;br /&gt;
      elseif (Trig.Opp &amp;gt;  0.0) and (Trig.Hyp &amp;gt;  0.0) then -- Base and Slope&lt;br /&gt;
-- test 3&lt;br /&gt;
        Trig.Adj = math.sqrt((Trig.Hyp * Trig.Hyp ) - ( Trig.Opp * Trig.Opp))&lt;br /&gt;
        Trig.A  = math.deg(math.atan(Trig.Opp / Trig.Adj))&lt;br /&gt;
        BSA()&lt;br /&gt;
        return true&lt;br /&gt;
      else&lt;br /&gt;
        DisplayMessageBox(&amp;quot;Error: Trig Values did not match requirements: \n&amp;quot; ..&lt;br /&gt;
                          &amp;quot; Trig.A  =  &amp;quot; .. tostring(Trig.A) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
                          &amp;quot; Trig.B  =  &amp;quot; .. tostring(Trig.B) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
                          &amp;quot; Trig.C  =  &amp;quot; .. tostring(Trig.C) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
                          &amp;quot; Trig.Opp =  &amp;quot; .. tostring(Trig.Opp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
                          &amp;quot; Trig.Adj =  &amp;quot; .. tostring(Trig.Adj) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
                          &amp;quot; Trig.Hyp =  &amp;quot; .. tostring(Trig.Hyp) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
                          &amp;quot; Trig.Slope =  &amp;quot; .. tostring(Trig.Slope) .. &amp;quot; on 12 inch \n&amp;quot; ..&lt;br /&gt;
                          &amp;quot; Trig.Area =  &amp;quot; .. tostring(Trig.Area) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
                          &amp;quot; Trig.Parameter =  &amp;quot; .. tostring(Trig.Parameter) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
                          &amp;quot; Trig.OutRadius =  &amp;quot; .. tostring(Trig.OutRadius) .. &amp;quot; \n&amp;quot; ..&lt;br /&gt;
                          &amp;quot; Trig.InRadius =  &amp;quot; .. tostring(Trig.InRadius) .. &amp;quot; \n&amp;quot;&lt;br /&gt;
                          )&lt;br /&gt;
        return false&lt;br /&gt;
      end&lt;br /&gt;
    end -- function end&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
end -- Geometry Tools end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==INI File Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
These functions manipulate the INI files for the storage and retrieval of data.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===INI_NameStrip===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Convert string to the correct data type.&lt;br /&gt;
&lt;br /&gt;
Local Words = NameStrip(&amp;quot;KPSDFKSPSK - 34598923&amp;quot;, &amp;quot;-&amp;quot;) -- returns &amp;quot;KPSDFKSPSK&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''Source Code'''&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function INI_NameStrip(str, var)&lt;br /&gt;
    if &amp;quot;&amp;quot; == str then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error in string&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      if string.find(str, var) then&lt;br /&gt;
        local j = assert(string.find(str, var) - 1)&lt;br /&gt;
        return All_Trim(string.sub(str, 1, j))&lt;br /&gt;
      else&lt;br /&gt;
        return str&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_HeadStrip===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Convert string to the correct data type.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  function INI_HeadStrip(str, var)                            -- convert string to the correct data type&lt;br /&gt;
-- Local Words = HeadStrip(&amp;quot;LastName23 = Smith&amp;quot;, &amp;quot;=&amp;quot;) -- returns &amp;quot;Smith&amp;quot;&lt;br /&gt;
    if &amp;quot;&amp;quot; == str then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error in string&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      if string.find(str, var) then&lt;br /&gt;
        local j = assert(string.find(str, var) + 1)&lt;br /&gt;
        return All_Trim(string.sub(str, j))&lt;br /&gt;
      else&lt;br /&gt;
        return str&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_AreDupGroups===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Checks if there are duplicate groups.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function INI_AreDupGroups(xPath, xFile)&lt;br /&gt;
    local GroupNames = {}&lt;br /&gt;
    local CleanNames = {}&lt;br /&gt;
    local DupGroups  = {}&lt;br /&gt;
      GroupNames = INI_ReadGroups(xFile, aName)&lt;br /&gt;
      CleanNames = RemoveDups(GroupNames)&lt;br /&gt;
    if TableLength(GroupNames) == TableLength(CleanNames)then&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_FixDupGroups===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Find and fix duplicate groups&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_FixDupGroups(xPath, xFile)&lt;br /&gt;
    local GroupNames = {}&lt;br /&gt;
    local CleanNames = {}&lt;br /&gt;
    local DupGroups  = {}&lt;br /&gt;
      GroupNames = INI_ReadGroups(xFile, aName)&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_DeleteGroup===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Deletes only the first find of xGroup&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_DeleteGroup(xPath, xFile, xGroup)&lt;br /&gt;
-- Deletes old ini (.bak) file&lt;br /&gt;
-- Copy's the .ini to a backup (.bak) new file&lt;br /&gt;
-- Reads the new backup file and writes a new file to the xGroup value&lt;br /&gt;
-- Stops Writing lines until next Group is found&lt;br /&gt;
-- Writes to end of file&lt;br /&gt;
-- Call: DeleteGroup(&amp;quot;C:\\Users\\James\\OneDrive\\Documents\\DoorGadget\\Clients\\Marcin&amp;quot;, &amp;quot;ProjectList&amp;quot;, &amp;quot;Boston&amp;quot;)&lt;br /&gt;
    local OfileName = xPath .. &amp;quot;\\&amp;quot; .. xFile .. &amp;quot;.bak&amp;quot;&lt;br /&gt;
    if FileExists(OfileName) then&lt;br /&gt;
      os.remove(OfileName)&lt;br /&gt;
    end&lt;br /&gt;
    local NfileName = xPath .. &amp;quot;\\&amp;quot; .. xFile .. &amp;quot;.ini&amp;quot;&lt;br /&gt;
--    os.rename(NfileName, OfileName) -- makes backup copy file&lt;br /&gt;
    if CopyFileFromTo(NfileName, OfileName) then&lt;br /&gt;
      local fileR   = io.open(OfileName)&lt;br /&gt;
      local fileW   = io.open(NfileName,  &amp;quot;w&amp;quot;)&lt;br /&gt;
      local groups  = false&lt;br /&gt;
      local writit  = true&lt;br /&gt;
      local MyTxt   = &amp;quot;&amp;quot;&lt;br /&gt;
      local txt = &amp;quot;&amp;quot;&lt;br /&gt;
      if fileR and fileW then  -- files are open&lt;br /&gt;
        for Line in fileR:lines() do  -- read each line of the backup file&lt;br /&gt;
          txt = Line  -- copy line from file to txt&lt;br /&gt;
          if All_Trim(Line) == &amp;quot;[&amp;quot; .. All_Trim(xGroup) ..  MyTxt .. &amp;quot;]&amp;quot; then  -- look for a match&lt;br /&gt;
            groups = true&lt;br /&gt;
            txt = &amp;quot;&amp;quot;&lt;br /&gt;
          end -- if end&lt;br /&gt;
          if groups and MyTxt == &amp;quot;&amp;quot; then  -- if group is true turn off the write function&lt;br /&gt;
            writit = false&lt;br /&gt;
            if &amp;quot;[&amp;quot; == string.sub(All_Trim(txt), 1, 1) then  -- turns write function on if next group is found&lt;br /&gt;
              groups = false&lt;br /&gt;
              xGroup = &amp;quot;-&amp;quot;&lt;br /&gt;
              writit = true&lt;br /&gt;
              MyTxt   = &amp;quot;--&amp;quot;&lt;br /&gt;
            else&lt;br /&gt;
              writit = false&lt;br /&gt;
            end -- if end&lt;br /&gt;
          end -- if end&lt;br /&gt;
          if writit then&lt;br /&gt;
            fileW:write(txt .. &amp;quot;\n&amp;quot;)&lt;br /&gt;
            txt = &amp;quot;&amp;quot;&lt;br /&gt;
          end -- if end&lt;br /&gt;
        end -- for end&lt;br /&gt;
        os.remove(OfileName)&lt;br /&gt;
      end -- if end&lt;br /&gt;
      if fileR then fileR:close() end&lt;br /&gt;
      if fileW then fileW:close() end&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_RenameGroup===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Renames a group&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_RenameGroup(xOldGroup, xNewGroup)&lt;br /&gt;
--Deletes old ini Hardware.bak file&lt;br /&gt;
--Copys the ini file to a backup copy file&lt;br /&gt;
--Reads the backup file and writes a new ini file to the xGroup&lt;br /&gt;
--Writes new file with new group  to the new ini file&lt;br /&gt;
  local NfileName = Project.AppPath .. &amp;quot;\\&amp;quot; .. &amp;quot;EasyDrawerHardware&amp;quot; .. &amp;quot;.ini&amp;quot;&lt;br /&gt;
  local OfileName = Project.AppPath .. &amp;quot;\\&amp;quot; .. &amp;quot;EasyDrawerHardware&amp;quot; .. &amp;quot;.bak&amp;quot;&lt;br /&gt;
  os.remove(OfileName)&lt;br /&gt;
  CopyFileFromTo(NfileName, OfileName) -- makes backup file&lt;br /&gt;
  local fileR = io.open(OfileName)&lt;br /&gt;
  local fileW = io.open(NfileName, &amp;quot;w&amp;quot;)&lt;br /&gt;
  if fileR and fileW then&lt;br /&gt;
    local groups = false&lt;br /&gt;
    local txt = &amp;quot;&amp;quot;&lt;br /&gt;
    for Line in fileR:lines() do&lt;br /&gt;
      if All_Trim(Line) == &amp;quot;[&amp;quot; .. All_Trim(xOldGroup) .. txt .. &amp;quot;]&amp;quot; then -- Group&lt;br /&gt;
        fileW:write(xNewGroup .. &amp;quot;\n&amp;quot;)&lt;br /&gt;
        txt = &amp;quot;-&amp;quot;&lt;br /&gt;
      else&lt;br /&gt;
        fileW:write(Line .. &amp;quot;\n&amp;quot;)&lt;br /&gt;
      end -- if end&lt;br /&gt;
    end -- for end&lt;br /&gt;
    fileR:close()&lt;br /&gt;
    fileW:close()&lt;br /&gt;
    os.remove(OfileName)&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_DeleteItem===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Deleates a group&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_DeleteItem(xPath, xFile, xGroup, xItem)&lt;br /&gt;
-- Deletes old ini (.bak) file&lt;br /&gt;
-- Copys the .ini to a backup (.bak) new file&lt;br /&gt;
-- Reads the new backup file and writes a new file to the xGroup value&lt;br /&gt;
-- Stops Writing lines until next Group is found&lt;br /&gt;
-- Writes to end of file&lt;br /&gt;
-- DeleteGroup(&amp;quot;C:\\Users\\James\\OneDrive\\Documents\\DoorGadget\\Clients\\Marcin&amp;quot;, &amp;quot;ProjectList&amp;quot;, &amp;quot;Boston&amp;quot;)&lt;br /&gt;
  local NfileName = xPath .. &amp;quot;\\&amp;quot; .. xFile .. &amp;quot;.ini&amp;quot;&lt;br /&gt;
  local OfileName = xPath .. &amp;quot;\\&amp;quot; .. xFile .. &amp;quot;.bak&amp;quot;&lt;br /&gt;
  os.remove(OfileName)&lt;br /&gt;
  CopyFileFromTo(NfileName, OfileName) -- makes backup copy file&lt;br /&gt;
  local fileR = io.open(OfileName)&lt;br /&gt;
  local fileW = io.open(NfileName,  &amp;quot;w&amp;quot;)&lt;br /&gt;
  if fileR and fileW then&lt;br /&gt;
    local groups = false&lt;br /&gt;
    local writit = true&lt;br /&gt;
    local txt = &amp;quot;&amp;quot;&lt;br /&gt;
    for Line in fileR:lines() do&lt;br /&gt;
      txt = Line&lt;br /&gt;
      if All_Trim(Line) == &amp;quot;[&amp;quot; .. All_Trim(xGroup) .. &amp;quot;]&amp;quot; then&lt;br /&gt;
        groups = true&lt;br /&gt;
      end -- if end&lt;br /&gt;
      if groups then&lt;br /&gt;
  -- ===================&lt;br /&gt;
        if xItem == string.sub(Line, 1, string.len(xItem))  then  -- Item&lt;br /&gt;
          writit = false&lt;br /&gt;
          groups = false&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- if end&lt;br /&gt;
  -- ===================&lt;br /&gt;
      if writit then&lt;br /&gt;
        fileW:write(txt .. &amp;quot;\n&amp;quot;)&lt;br /&gt;
      end -- if end&lt;br /&gt;
      writit = true&lt;br /&gt;
    end -- for end&lt;br /&gt;
    os.remove(OfileName)&lt;br /&gt;
    fileR:close()&lt;br /&gt;
    fileW:close()&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_ValidateGroup===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Reads INI file and returns true if group is found&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_ValidateGroup(xFile, xGroup)&lt;br /&gt;
  -- Reads INI file and returns true if the group is found&lt;br /&gt;
  local fileR = io.open(xFile)&lt;br /&gt;
  local group = false&lt;br /&gt;
  for Line in fileR:lines() do&lt;br /&gt;
    if string.upper(All_Trim(Line)) == &amp;quot;[&amp;quot; .. string.upper(All_Trim(xGroup)) .. &amp;quot;]&amp;quot; then  -- Group&lt;br /&gt;
    group = true&lt;br /&gt;
    break&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- for end&lt;br /&gt;
  fileR:close()&lt;br /&gt;
  return group&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_ValidateItem===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Reads INI file and returns true if group and item is found&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_ValidateItem(xFile, xGroup, xItem)&lt;br /&gt;
    local fileR = io.open(xFile)&lt;br /&gt;
    if fileR then&lt;br /&gt;
      local group = false&lt;br /&gt;
      local item = false&lt;br /&gt;
      local ItemLen = string.len(xItem)&lt;br /&gt;
      for Line in fileR:lines() do&lt;br /&gt;
        if All_Trim(Line) == &amp;quot;[&amp;quot; ..  string.upper(All_Trim(xGroup)) .. &amp;quot;]&amp;quot; then  -- Group&lt;br /&gt;
        group = true&lt;br /&gt;
        end -- if end&lt;br /&gt;
        if group then&lt;br /&gt;
          if string.upper(xItem) == string.upper(string.sub(Line, 1, string.len(xItem)))  then  -- Item&lt;br /&gt;
            item = true&lt;br /&gt;
            break&lt;br /&gt;
          end -- if end&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- for end&lt;br /&gt;
      fileR:close()&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return group&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_StrValue===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Reads INI file and returns string value&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_StrValue(str, ty)&lt;br /&gt;
-- Convert string to the correct data type&lt;br /&gt;
    if nil == str then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error in Ini file - looking for a &amp;quot; .. ty .. &amp;quot; value&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      if &amp;quot;&amp;quot; == All_Trim(str) then&lt;br /&gt;
        DisplayMessageBox(&amp;quot;Error in Ini file - looking for a &amp;quot; .. ty .. &amp;quot; value&amp;quot;)&lt;br /&gt;
      else&lt;br /&gt;
        local j = (string.find(str, &amp;quot;=&amp;quot;) + 1)&lt;br /&gt;
        if ty == &amp;quot;D&amp;quot; then -- Double&lt;br /&gt;
          return tonumber(string.sub(str, j))&lt;br /&gt;
        end -- if end&lt;br /&gt;
        if ty == &amp;quot;I&amp;quot; then  -- Intiger&lt;br /&gt;
          return math.floor(tonumber(string.sub(str, j)))&lt;br /&gt;
        end -- if end&lt;br /&gt;
        if ty == &amp;quot;S&amp;quot; then  -- String&lt;br /&gt;
          return All_Trim(string.sub(str, j))&lt;br /&gt;
        end -- if end&lt;br /&gt;
        if ty == &amp;quot;B&amp;quot; then  -- Bool&lt;br /&gt;
          if &amp;quot;TRUE&amp;quot; == All_Trim(string.sub(str, j)) then&lt;br /&gt;
            return true&lt;br /&gt;
          else&lt;br /&gt;
            return false&lt;br /&gt;
          end -- if end&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- if end&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return nil&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_GetValue===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Reads INI file and returns value&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_GetValue(xPath, FileName, GroupName, ItemName, ValueType)&lt;br /&gt;
    -- ==INI_GetValue(xPath, FileName, GroupName, ItemName, ValueType)==&lt;br /&gt;
    -- Returns a value from a file, group, and Item&lt;br /&gt;
    -- Usage: XX.YY = GetIniValue(&amp;quot;C:/temp&amp;quot;, &amp;quot;ScrewDia&amp;quot;, &amp;quot;[Screws]&amp;quot;, &amp;quot;Diameter&amp;quot;, &amp;quot;D&amp;quot;)&lt;br /&gt;
    local filenameR = xPath .. &amp;quot;\\&amp;quot; .. FileName .. &amp;quot;.ini&amp;quot;&lt;br /&gt;
    local FL = LengthOfFile(filenameR)&lt;br /&gt;
    local file = io.open(filenameR, &amp;quot;r&amp;quot;)&lt;br /&gt;
    local dat = &amp;quot;.&amp;quot;&lt;br /&gt;
    local ItemNameLen = string.len(ItemName)&lt;br /&gt;
    if file then&lt;br /&gt;
      while (FL &amp;gt;= 1) do&lt;br /&gt;
        dat = string.upper(All_Trim(file:read()))&lt;br /&gt;
        if dat == &amp;quot;[&amp;quot; .. string.upper(GroupName) .. &amp;quot;]&amp;quot; then&lt;br /&gt;
          break&lt;br /&gt;
        else&lt;br /&gt;
          FL = FL - 1&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- while end&lt;br /&gt;
      while (FL &amp;gt;= 1) do&lt;br /&gt;
        dat = string.upper(All_Trim(file:read()))&lt;br /&gt;
        if string.upper(ItemName) == string.sub(dat, 1, ItemNameLen)  then&lt;br /&gt;
          break&lt;br /&gt;
        else&lt;br /&gt;
          FL = FL - 1&lt;br /&gt;
          if FL == 0 then&lt;br /&gt;
            dat = &amp;quot;Error - item not  found&amp;quot;&lt;br /&gt;
            break&lt;br /&gt;
          end -- if end&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- while end&lt;br /&gt;
      file:close()-- closes the open file&lt;br /&gt;
    end -- if end&lt;br /&gt;
    local XX = StrIniValue(dat, ValueType)&lt;br /&gt;
    return XX&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_GetIDFor===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Reads INI file and returns ID for a value&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_GetIDFor(xPath, FileName, GroupName, ItemValue)&lt;br /&gt;
    -- == INI_GetIDFor(xPath, FileName, GroupName, ItemValue) ==&lt;br /&gt;
    -- Returns a ItemID from a file, group, and ItemValue&lt;br /&gt;
    -- Usage: XX.YY = INI_GetIDFor(&amp;quot;C:/temp&amp;quot;, &amp;quot;UserList&amp;quot;, &amp;quot;[Users]&amp;quot;, &amp;quot;Anderson&amp;quot;)&lt;br /&gt;
    -- returns: &amp;quot;UserLastName22&amp;quot;&lt;br /&gt;
    local filenameR = xPath .. &amp;quot;\\&amp;quot; .. FileName .. &amp;quot;.ini&amp;quot;&lt;br /&gt;
    local FL = LengthOfFile(filenameR)&lt;br /&gt;
    local file = io.open(filenameR, &amp;quot;r&amp;quot;)&lt;br /&gt;
    if file then&lt;br /&gt;
      local dat = &amp;quot;.&amp;quot;&lt;br /&gt;
      local ItemValueLen = string.len(ItemValue)&lt;br /&gt;
      while (FL &amp;gt;= 1) do&lt;br /&gt;
        dat = string.upper(All_Trim(file:read()))&lt;br /&gt;
        if dat == &amp;quot;[&amp;quot; .. string.upper(GroupName) .. &amp;quot;]&amp;quot; then&lt;br /&gt;
          break&lt;br /&gt;
        else&lt;br /&gt;
          FL = FL - 1&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- while end&lt;br /&gt;
      while (FL &amp;gt;= 1) do&lt;br /&gt;
        dat = string.upper(All_Trim(file:read()))&lt;br /&gt;
        if string.upper(ItemValue) == HeadStrip(dat, &amp;quot;=&amp;quot;)  then&lt;br /&gt;
          break&lt;br /&gt;
        else&lt;br /&gt;
          FL = FL - 1&lt;br /&gt;
          if FL == 0 then&lt;br /&gt;
            dat = &amp;quot;Error - item not  found&amp;quot;&lt;br /&gt;
            break&lt;br /&gt;
          end -- if end&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- while end&lt;br /&gt;
      file:close()-- closes the open file&lt;br /&gt;
    end -- if end&lt;br /&gt;
    local XX = NameStrip(dat, &amp;quot;=&amp;quot;)&lt;br /&gt;
    return XX&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_ReadGroups===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Reads INI file group and returns true if found&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_ReadGroups(xFile, aName)&lt;br /&gt;
  --[[Reads INI and returns a list contain the [Headers] as Array&lt;br /&gt;
  IniFile = {} Global variables&lt;br /&gt;
  xPath = script_path&lt;br /&gt;
  ]]&lt;br /&gt;
    local filename = xFile&lt;br /&gt;
    local file = io.open(filename, &amp;quot;r&amp;quot;)&lt;br /&gt;
    if file then&lt;br /&gt;
      local fLength = (LengthOfFile(filename) - 1)&lt;br /&gt;
      local dat = All_Trim(file:read())&lt;br /&gt;
      while (fLength &amp;gt;= 1) do&lt;br /&gt;
        if &amp;quot;[&amp;quot; == string.sub(dat, 1, 1) then&lt;br /&gt;
          table.insert (aName, string.sub(dat, 2, -2))&lt;br /&gt;
        end&lt;br /&gt;
        dat = file:read()&lt;br /&gt;
        if dat then&lt;br /&gt;
          dat = All_Trim(dat)&lt;br /&gt;
        else&lt;br /&gt;
          file:close()-- closes the open file&lt;br /&gt;
          return true&lt;br /&gt;
        end&lt;br /&gt;
        fLength = fLength - 1&lt;br /&gt;
      end -- while&lt;br /&gt;
    end -- if&lt;br /&gt;
     if file then file:close() end&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_ProjectHeaderReader===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Reads INI file group and returns the INI Header values of a ini file and uploads to &amp;quot;IniFile&amp;quot; Array&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_ProjectHeaderReader(xPath)&lt;br /&gt;
    local filename = xPath .. &amp;quot;/CabinetProjects.ini&amp;quot;&lt;br /&gt;
    local file = io.open(filename, &amp;quot;r&amp;quot;)&lt;br /&gt;
    if file then&lt;br /&gt;
      local Cabing = (LengthOfFile(filename) - 1)&lt;br /&gt;
      local dat = All_Trim(file:read())&lt;br /&gt;
      while (Cabing &amp;gt;= 1) do&lt;br /&gt;
        if &amp;quot;[&amp;quot; == string.sub(dat, 1, 1) then&lt;br /&gt;
          table.insert (Projects, string.sub(dat, 2, -2))&lt;br /&gt;
        end&lt;br /&gt;
        dat = file:read()&lt;br /&gt;
        if dat then&lt;br /&gt;
          dat = All_Trim(dat)&lt;br /&gt;
        else&lt;br /&gt;
          return true&lt;br /&gt;
        end&lt;br /&gt;
        Cabing = Cabing - 1&lt;br /&gt;
      end&lt;br /&gt;
      file:close()&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_AddNewProject===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Appends a New Project to CabinetProjectQuestion.ini&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_AddNewProject(xPath, xGroup)&lt;br /&gt;
    local filename = xPath .. &amp;quot;/ProjectList.ini&amp;quot;&lt;br /&gt;
    local file = io.open(filename, &amp;quot;a&amp;quot;)&lt;br /&gt;
    if file then&lt;br /&gt;
      file:write(&amp;quot;[&amp;quot; .. All_Trim(xGroup) .. &amp;quot;] \n&amp;quot;)&lt;br /&gt;
      file:write(&amp;quot;load_date = &amp;quot; .. StartDate(true) .. &amp;quot; \n&amp;quot;)&lt;br /&gt;
      file:write(&amp;quot;#====================================== \n&amp;quot;)&lt;br /&gt;
      file:close()-- closes the open file&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_StdHeaderReader===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Gets the INI Header values of a ini file and uploads to &amp;quot;IniFile&amp;quot; Array&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_StdHeaderReader(xPath, Fname)&lt;br /&gt;
    local filename = xPath .. &amp;quot;\\&amp;quot; .. Fname .. &amp;quot;.ini&amp;quot;&lt;br /&gt;
    local file = io.open(filename, &amp;quot;r&amp;quot;)&lt;br /&gt;
    if file then&lt;br /&gt;
      local WallMilling = (LengthOfFile(filename) - 1)&lt;br /&gt;
      local dat = All_Trim(file:read())&lt;br /&gt;
      while (WallMilling &amp;gt;= 0) do&lt;br /&gt;
        if &amp;quot;[&amp;quot; == string.sub(dat, 1, 1) then&lt;br /&gt;
          table.insert (IniFile, string.sub(dat, 2, -2))&lt;br /&gt;
        end -- if end&lt;br /&gt;
        dat = file:read()&lt;br /&gt;
        if dat then&lt;br /&gt;
          dat = All_Trim(dat)&lt;br /&gt;
        else&lt;br /&gt;
          return true&lt;br /&gt;
        end -- if end&lt;br /&gt;
        WallMilling = WallMilling - 1&lt;br /&gt;
      end -- while end&lt;br /&gt;
      file:close()&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_ReadProjectinfo===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Reads an ini files group and sets the table.names&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_ReadProjectinfo(Table, xPath, xGroup, xFile)&lt;br /&gt;
    Table.ProjectContactEmail       = GetIniValue(xPath, xFile, xGroup, &amp;quot;ProjectQuestion.ProjectContactEmail&amp;quot;, &amp;quot;S&amp;quot;)&lt;br /&gt;
    Table.ProjectContactName        = GetIniValue(xPath, xFile, xGroup, &amp;quot;ProjectQuestion.ProjectContactName&amp;quot;, &amp;quot;S&amp;quot;)&lt;br /&gt;
    Table.ProjectContactPhoneNumber = GetIniValue(xPath, xFile, xGroup, &amp;quot;ProjectQuestion.ProjectContactPhoneNumber&amp;quot;, &amp;quot;S&amp;quot;)&lt;br /&gt;
    Table.ProjectName               = GetIniValue(xPath, xFile, xGroup, &amp;quot;ProjectQuestion.ProjectName&amp;quot;, &amp;quot;S&amp;quot;)&lt;br /&gt;
    Table.ProjectPath               = GetIniValue(xPath, xFile, xGroup, &amp;quot;ProjectQuestion.ProjectPath&amp;quot;, &amp;quot;S&amp;quot;)&lt;br /&gt;
    Table.StartDate                 = GetIniValue(xPath, xFile, xGroup, &amp;quot;ProjectQuestion.StartDate&amp;quot;, &amp;quot;S&amp;quot;)&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_UpdateItem===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Deletes old ini (.bak) file&lt;br /&gt;
&lt;br /&gt;
Copys the .ini to a backup (.bak) new file&lt;br /&gt;
&lt;br /&gt;
Reads the new backup file and writes a new file to the xGroup&lt;br /&gt;
&lt;br /&gt;
Writes new xValue for the for the xItem&lt;br /&gt;
&lt;br /&gt;
Reads and writes a new file to end of file&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_UpdateItem(xPath, xFile, xGroup, xItem, xValue)&lt;br /&gt;
    local NfileName = xPath .. &amp;quot;\\&amp;quot; .. xFile .. &amp;quot;.ini&amp;quot;&lt;br /&gt;
    local OfileName = xPath .. &amp;quot;\\&amp;quot; .. xFile .. &amp;quot;.bak&amp;quot;&lt;br /&gt;
    os.remove(OfileName)&lt;br /&gt;
    if CopyFileFromTo(NfileName, OfileName) then-- makes backup file&lt;br /&gt;
      local fileR = io.open(OfileName)&lt;br /&gt;
      local fileW = io.open(NfileName,  &amp;quot;w&amp;quot;)&lt;br /&gt;
      if fileR and fileW then&lt;br /&gt;
        local groups = false&lt;br /&gt;
        local txt = &amp;quot;&amp;quot;&lt;br /&gt;
        for Line in fileR:lines() do&lt;br /&gt;
          txt = Line&lt;br /&gt;
          if All_Trim(Line) == &amp;quot;[&amp;quot; .. All_Trim(xGroup) .. &amp;quot;]&amp;quot; then -- Group&lt;br /&gt;
            groups = true&lt;br /&gt;
          end -- if end&lt;br /&gt;
          if xItem == string.sub(Line, 1, string.len(xItem))  then  -- Item&lt;br /&gt;
            if groups then&lt;br /&gt;
              txt = xItem .. &amp;quot; = &amp;quot; .. xValue&lt;br /&gt;
              groups = false&lt;br /&gt;
            end -- if end&lt;br /&gt;
          end -- if end&lt;br /&gt;
          fileW:write(txt .. &amp;quot;\n&amp;quot;)&lt;br /&gt;
          txt = &amp;quot;&amp;quot;&lt;br /&gt;
        end -- for end&lt;br /&gt;
        os.remove(OfileName)&lt;br /&gt;
        fileR:close()&lt;br /&gt;
        fileW:close()&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_ReadProject===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Reads the ini file for project data&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_ReadProject(xPath, xFile, xGroup)&lt;br /&gt;
  -- Milling = {}&lt;br /&gt;
    Milling.LayerNameBackPocket          = GetIniValue(xPath, xFile, xGroup, &amp;quot;Milling.LayerNameBackPocket&amp;quot;, &amp;quot;S&amp;quot;)&lt;br /&gt;
    Milling.LayerNameTopBottomCenterDado = GetIniValue(xPath, xFile, xGroup, &amp;quot;Milling.LayerNameTopBottomCenterDado&amp;quot;, &amp;quot;S&amp;quot;)&lt;br /&gt;
    Milling.LayerNameDrawNotes           = GetIniValue(xPath, xFile, xGroup, &amp;quot;Milling.LayerNameDrawNotes&amp;quot;, &amp;quot;S&amp;quot;)&lt;br /&gt;
    Milling.LayerNameDrawFaceFrame       = GetIniValue(xPath, xFile, xGroup, &amp;quot;Milling.LayerNameDrawFaceFrame&amp;quot;, &amp;quot;S&amp;quot;)&lt;br /&gt;
    Milling.BackPocketDepthWall          = GetIniValue(xPath, xFile, xGroup, &amp;quot;Milling.BackPocketDepthWall&amp;quot;, &amp;quot;N&amp;quot;)&lt;br /&gt;
    Milling.BlindDadoSetbackWall         = GetIniValue(xPath, xFile, xGroup, &amp;quot;Milling.BlindDadoSetbackWall&amp;quot;, &amp;quot;N&amp;quot;)&lt;br /&gt;
    Milling.CabDepthWall                 = GetIniValue(xPath, xFile, xGroup, &amp;quot;Milling.CabDepthWall&amp;quot;, &amp;quot;N&amp;quot;)&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===INI_TestDeleteDups===&lt;br /&gt;
[[File:TopOfPage.png|right|30px|link=JimAndi Toolbox]]&lt;br /&gt;
Reads the ini file for dups and deletes&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function INI_TestDeleteDups()&lt;br /&gt;
    --[[ Requires 3 global variables&lt;br /&gt;
    clean  = {}&lt;br /&gt;
    dups   = {}&lt;br /&gt;
    Names  = {}&lt;br /&gt;
    ]]&lt;br /&gt;
    local myPath = &amp;quot;C:\\Users\\CNC\\Documents\\test&amp;quot;&lt;br /&gt;
    local myName = &amp;quot;Tester&amp;quot;&lt;br /&gt;
    local myfile = &amp;quot;C:\\Users\\CNC\\Documents\\test\\Tester.ini&amp;quot;&lt;br /&gt;
    INI_ReadGroups(myfile, Names)&lt;br /&gt;
    FindDups(Names, dups, clean)&lt;br /&gt;
    for i,v in ipairs(dups) do&lt;br /&gt;
      INI_DeleteGroup(myPath, myName, v)&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
 end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Data Import Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is used to import data to a gadget.&lt;br /&gt;
&lt;br /&gt;
===Read_CSV===&lt;br /&gt;
Reads a CSV file based on header and format (Requires modifications per usage)&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function Read_CSV(xFile, Header)&lt;br /&gt;
  --Read_CSV(Door.CSVFile, true)&lt;br /&gt;
  local fileR = io.open(xFile)&lt;br /&gt;
  local xLine = &amp;quot;&amp;quot;&lt;br /&gt;
  local result = {}&lt;br /&gt;
  if fileR then&lt;br /&gt;
    for Line in fileR:lines() do&lt;br /&gt;
      xLine = Line&lt;br /&gt;
      if Header then&lt;br /&gt;
        Header = false&lt;br /&gt;
      else&lt;br /&gt;
        xLine = All_Trim(Line)&lt;br /&gt;
        for match in (xLine..&amp;quot;,&amp;quot;):gmatch(&amp;quot;(.-)&amp;quot;..&amp;quot;,&amp;quot;) do&lt;br /&gt;
          table.insert(result, match)&lt;br /&gt;
        end -- for end&lt;br /&gt;
        Door.Count     = tonumber(result[1])&lt;br /&gt;
        Door.Height    = tonumber(result[2])&lt;br /&gt;
        Door.Width     = tonumber(result[3])&lt;br /&gt;
&lt;br /&gt;
        result = {}&lt;br /&gt;
        while Door.Count &amp;gt; 0 do&lt;br /&gt;
          if      Door.Style == StyleA.Name then&lt;br /&gt;
            DoorStyleA()&lt;br /&gt;
          elseif  Door.Style == StyleB.Name then&lt;br /&gt;
            DoorStyleB()&lt;br /&gt;
          elseif  Door.Style == StyleC.Name then&lt;br /&gt;
            DoorStyleC()&lt;br /&gt;
          elseif  Door.Style == StyleE.Name then&lt;br /&gt;
            DoorStyleE()&lt;br /&gt;
          elseif  Door.Style == StyleF.Name then&lt;br /&gt;
            DoorStyleF()&lt;br /&gt;
          elseif  Door.Style == StyleG.Name then&lt;br /&gt;
            DoorStyleG()&lt;br /&gt;
          else&lt;br /&gt;
            DisplayMessageBox(&amp;quot;No Style Select!&amp;quot;)&lt;br /&gt;
          end --if end&lt;br /&gt;
          Door.Count =  Door.Count - 1&lt;br /&gt;
        end -- for end&lt;br /&gt;
      end --if end&lt;br /&gt;
      Door.Record = Door.Record + 1&lt;br /&gt;
      MyProgressBar:SetPercentProgress(ProgressAmount(Door.Record))&lt;br /&gt;
    end --for end&lt;br /&gt;
  end --if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Job Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function ValidJob()&lt;br /&gt;
  -- A better error message&lt;br /&gt;
    local job = VectricJob()&lt;br /&gt;
    if not job.Exists then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error: Cannot run Gadget, no drawing found \n&amp;quot; ..&lt;br /&gt;
                        &amp;quot;Please create a new file (drawing) and \n&amp;quot; ..&lt;br /&gt;
                        &amp;quot;specify the material dimensions \n&amp;quot;&lt;br /&gt;
      )&lt;br /&gt;
      return false&lt;br /&gt;
    else&lt;br /&gt;
      return true&lt;br /&gt;
    end  -- if end&lt;br /&gt;
  end -- ValidJob end&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===MoveSetectedVectors===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function MoveSetectedVectors(job, NewBasePoint)&lt;br /&gt;
    local Selection = job.Selection&lt;br /&gt;
    if Selection.IsEmpty then&lt;br /&gt;
      MessageBox(&amp;quot;LayoutImportedVectors: No vectors selected!&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    local MySelection = Selection:GetBoundingBox();&lt;br /&gt;
    if not NewBasePoint then&lt;br /&gt;
      NewBasePoint = Point2D(0,0)&lt;br /&gt;
    end&lt;br /&gt;
    local MyNewLocatioin = BasePoint - MySelection.BLC&lt;br /&gt;
    local Txform = TranslationMatrix2D(MyNewLocatioin)&lt;br /&gt;
    Selection:Transform(Txform)&lt;br /&gt;
    return true&lt;br /&gt;
  end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===FixPath===&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function FixPath(path)                                -- Lua Returns a fixed path&lt;br /&gt;
    return path:gsub(&amp;quot;%\\&amp;quot;, &amp;quot;/&amp;quot;)&lt;br /&gt;
  end -- function end&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
  function FixPath(myPath) {                            -- JavaScript Tool Returns a fixed path&lt;br /&gt;
    /* myPath  = &amp;quot;C:\\User\\Bob\\Home\\Drawings&amp;quot;; */&lt;br /&gt;
    /* NewPath = &amp;quot;C:/User/Bob/Home/Drawings&amp;quot;; */&lt;br /&gt;
    var NewPath = &amp;quot;&amp;quot;;&lt;br /&gt;
    var myLetter = &amp;quot;&amp;quot;;&lt;br /&gt;
    var CheckPathLen = myPath.length;&lt;br /&gt;
    for (let i = 0; i &amp;lt; myPath.length; i++) {&lt;br /&gt;
      myLetter = myPath.charAt(i)&lt;br /&gt;
      if myLetter.charCodeAt(0) == 92 {&lt;br /&gt;
        NewPath = NewPath + &amp;quot;/&amp;quot;;&lt;br /&gt;
      } else {&lt;br /&gt;
        NewPath = NewPath + myLetter;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    return NewPath;&lt;br /&gt;
  }&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===RotateSetectedVectors===&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function RotateSetectedVectors(job, NewBasePoint, NewAngle)&lt;br /&gt;
    local Selection = job.Selection&lt;br /&gt;
    if not NewBasePoint then&lt;br /&gt;
      NewBasePoint = Point2D(0,0)&lt;br /&gt;
    end -- if end&lt;br /&gt;
    if not NewAngle then&lt;br /&gt;
      NewAngle = 0.0&lt;br /&gt;
    end -- if end&lt;br /&gt;
    if Selection.IsEmpty then&lt;br /&gt;
      MessageBox(&amp;quot;Error: Rotation function: No vectors selected!&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    local MySelection = Selection:GetBoundingBox();&lt;br /&gt;
    local MyNewLocatioin = BasePoint - MySelection.BLC&lt;br /&gt;
    local Txform = RotationMatrix2D(NewBasePoint, NewAngle)&lt;br /&gt;
    Selection:Transform(Txform)&lt;br /&gt;
    return true&lt;br /&gt;
  end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetUnits===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function GetUnits(UTable)                               -- returns Drawing Units data&lt;br /&gt;
    local mtl_block = MaterialBlock()&lt;br /&gt;
    if mtl_block.InMM then&lt;br /&gt;
      UTable.Units  = &amp;quot;Drawing Units: mm&amp;quot;&lt;br /&gt;
      UTable.Unit = true&lt;br /&gt;
      UTable.UnitCheck = {&amp;quot;metric&amp;quot;, &amp;quot;kilometer&amp;quot;, &amp;quot;kilometers&amp;quot;, &amp;quot;kh&amp;quot;, &amp;quot;meter&amp;quot;, &amp;quot;meters&amp;quot;, &amp;quot;m&amp;quot;, &amp;quot;decimeter&amp;quot;, &amp;quot;decimeters&amp;quot;, &amp;quot;dm&amp;quot;, &amp;quot;centimeter&amp;quot;, &amp;quot;centimeters&amp;quot;, &amp;quot;cm&amp;quot;, &amp;quot;millimeter&amp;quot;, &amp;quot;millimeters&amp;quot;, &amp;quot;mm&amp;quot;}&lt;br /&gt;
      UTable.Cal = 25.4&lt;br /&gt;
    else&lt;br /&gt;
      UTable.Units  = &amp;quot;Drawing Units: inches&amp;quot;&lt;br /&gt;
      UTable.Unit = false&lt;br /&gt;
      UTable.UnitCheck = {&amp;quot;imperial&amp;quot;, &amp;quot;miles&amp;quot;, &amp;quot;mile&amp;quot;, &amp;quot;mi&amp;quot;, &amp;quot;yards&amp;quot;, &amp;quot;yard&amp;quot;, &amp;quot;yd&amp;quot;, &amp;quot;feet&amp;quot;, &amp;quot;foot&amp;quot;, &amp;quot;ft&amp;quot;, &amp;quot;inches&amp;quot;, &amp;quot;inch&amp;quot;, &amp;quot;in&amp;quot;, &amp;quot;fractions&amp;quot;, &amp;quot;fraction&amp;quot;}&lt;br /&gt;
      UTable.Cal = 1.0&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
  end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CheckTheUnits===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function CheckTheUnits(UTable, Value)                     -- Checks if the unit of messure in of drawing units&lt;br /&gt;
  local goodtogo = false&lt;br /&gt;
  for i=1, #UTable.UnitCheck  do&lt;br /&gt;
    if string.upper(Value) == string.upper(UTable.UnitCheck[i]) then&lt;br /&gt;
      goodtogo = true&lt;br /&gt;
      break&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- for end&lt;br /&gt;
  if goodtogo then&lt;br /&gt;
    return true&lt;br /&gt;
  else&lt;br /&gt;
    return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetMatlBlk===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function GetMatlBlk(Table)&lt;br /&gt;
    local mtl_block = MaterialBlock()&lt;br /&gt;
    if mtl_block.InMM then&lt;br /&gt;
      Table.Units = &amp;quot;Drawing Units: mm&amp;quot;&lt;br /&gt;
      Table.Unit = true&lt;br /&gt;
    else&lt;br /&gt;
      Table.Units = &amp;quot;Drawing Units: inches&amp;quot;&lt;br /&gt;
      Table.Unit = false&lt;br /&gt;
    end&lt;br /&gt;
    if mtl_block.Width&amp;gt; mtl_block.Height then&lt;br /&gt;
      Table.MaterialThickness = mtl_block.Height&lt;br /&gt;
      Table.MaterialLength = mtl_block.Width&lt;br /&gt;
      Table.Orantation = &amp;quot;H&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      Table.MaterialThickness = mtl_block.Width&lt;br /&gt;
      Table.MaterialLength = mtl_block.Height&lt;br /&gt;
      Table.Orantation = &amp;quot;V&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    Table.FrontThickness = Dovetail.MaterialThickness&lt;br /&gt;
    Table.SideThickness = Dovetail.MaterialThickness&lt;br /&gt;
    if mtl_block.Height == mtl_block.Width then&lt;br /&gt;
        MessageBox(&amp;quot;Error! Material block cannot square&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
  end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetBoxJointMaterialSettings===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function GetBoxJointMaterialSettings(Table)&lt;br /&gt;
    local mtl_block = MaterialBlock()&lt;br /&gt;
    --local units&lt;br /&gt;
    if mtl_block.InMM then&lt;br /&gt;
      Table.Units = &amp;quot;Drawing Units: mm&amp;quot;&lt;br /&gt;
      Table.Unit = true&lt;br /&gt;
    else&lt;br /&gt;
      Table.Units = &amp;quot;Drawing Units: inches&amp;quot;&lt;br /&gt;
      Table.Unit = false&lt;br /&gt;
    end&lt;br /&gt;
    if mtl_block.Width &amp;gt; mtl_block.Height then&lt;br /&gt;
      Table.MaterialThickness = mtl_block.Height&lt;br /&gt;
      Table.MaterialLength = mtl_block.Width&lt;br /&gt;
      Table.Orantation = &amp;quot;H&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      Table.MaterialThickness = mtl_block.Width&lt;br /&gt;
      Table.MaterialLength = mtl_block.Height&lt;br /&gt;
      Table.Orantation = &amp;quot;V&amp;quot;&lt;br /&gt;
    end&lt;br /&gt;
    if mtl_block.Height == mtl_block.Width then&lt;br /&gt;
      MessageBox(&amp;quot;Error! Material block cannot square&amp;quot;)&lt;br /&gt;
    end&lt;br /&gt;
    -- Display material XY origin&lt;br /&gt;
    local xy_origin_text = &amp;quot;invalid&amp;quot;&lt;br /&gt;
    local xy_origin = mtl_block.XYOrigin&lt;br /&gt;
    if  xy_origin == MaterialBlock.BLC then&lt;br /&gt;
        Table.xy_origin_text = &amp;quot;Bottom Left Corner&amp;quot;&lt;br /&gt;
      if Table.Orantation == &amp;quot;V&amp;quot; then&lt;br /&gt;
        Table.Direction1 = 90.0&lt;br /&gt;
        Table.Direction2 = 0.0&lt;br /&gt;
        Table.Direction3 = 270.0&lt;br /&gt;
        Table.Direction4 = 180.0&lt;br /&gt;
        Table.Bulge = 1.0&lt;br /&gt;
      else&lt;br /&gt;
        Table.Direction1 = 0.0&lt;br /&gt;
        Table.Direction2 = 90.0&lt;br /&gt;
        Table.Direction3 = 180.0&lt;br /&gt;
        Table.Direction4 = 270.0&lt;br /&gt;
        Table.Bulge = -1.0&lt;br /&gt;
      end&lt;br /&gt;
    elseif xy_origin == MaterialBlock.BRC then&lt;br /&gt;
      Table.xy_origin_text = &amp;quot;Bottom Right Corner&amp;quot;&lt;br /&gt;
      if Table.Orantation == &amp;quot;V&amp;quot; then&lt;br /&gt;
        Table.Direction1 = 90.0&lt;br /&gt;
        Table.Direction2 = 180.0&lt;br /&gt;
        Table.Direction3 = 270.0&lt;br /&gt;
        Table.Direction4 = 0.0&lt;br /&gt;
        Table.Bulge = -1.0&lt;br /&gt;
      else&lt;br /&gt;
        Table.Direction1 = 180.0&lt;br /&gt;
        Table.Direction2 = 90.0&lt;br /&gt;
        Table.Direction3 = 0.0&lt;br /&gt;
        Table.Direction4 = 270.0&lt;br /&gt;
        Table.Bulge = 1.0&lt;br /&gt;
      end&lt;br /&gt;
    elseif xy_origin == MaterialBlock.TRC then&lt;br /&gt;
      Table.xy_origin_text = &amp;quot;Top Right Corner&amp;quot;&lt;br /&gt;
      if Table.Orantation == &amp;quot;V&amp;quot; then&lt;br /&gt;
        Table.Direction1 = 270.0&lt;br /&gt;
        Table.Direction2 = 180.0&lt;br /&gt;
        Table.Direction3 = 90.0&lt;br /&gt;
        Table.Direction4 = 0.0&lt;br /&gt;
        Table.Bulge = 1.0&lt;br /&gt;
      else&lt;br /&gt;
        Table.Direction1 = 180.0&lt;br /&gt;
        Table.Direction2 = 270.0&lt;br /&gt;
        Table.Direction3 = 0.0&lt;br /&gt;
        Table.Direction4 = 90.0&lt;br /&gt;
        Table.Bulge = -1.0&lt;br /&gt;
      end&lt;br /&gt;
    elseif xy_origin == MaterialBlock.TLC then&lt;br /&gt;
      Table.xy_origin_text = &amp;quot;Top Left Corner&amp;quot;&lt;br /&gt;
      if Table.Orantation == &amp;quot;V&amp;quot; then&lt;br /&gt;
        Table.Direction1 = 270.0&lt;br /&gt;
        Table.Direction2 = 0.0&lt;br /&gt;
        Table.Direction3 = 90.0&lt;br /&gt;
        Table.Direction4 = 180.0&lt;br /&gt;
        Table.Bulge = -1.0&lt;br /&gt;
      else&lt;br /&gt;
        Table.Direction1 = 0.0&lt;br /&gt;
        Table.Direction2 = 270.0&lt;br /&gt;
        Table.Direction3 = 180.0&lt;br /&gt;
        Table.Direction4 = 90.0&lt;br /&gt;
        Table.Bulge = 1.0&lt;br /&gt;
      end&lt;br /&gt;
    elseif xy_origin == MaterialBlock.CENTRE then  -- NOTE: English spelling for Centre!&lt;br /&gt;
      Table.xy_origin_text = &amp;quot;Center&amp;quot;&lt;br /&gt;
      if Table.Orantation == &amp;quot;V&amp;quot; then&lt;br /&gt;
        Table.Direction1 = 0.0&lt;br /&gt;
        Table.Direction2 = 0.0&lt;br /&gt;
        Table.Direction3 = 0.0&lt;br /&gt;
        Table.Direction4 = 0.0&lt;br /&gt;
        Table.Bulge = 1.0&lt;br /&gt;
      else&lt;br /&gt;
        Table.Direction1 = 0.0&lt;br /&gt;
        Table.Direction2 = 0.0&lt;br /&gt;
        Table.Direction3 = 0.0&lt;br /&gt;
        Table.Direction4 = 0.0&lt;br /&gt;
        Table.Bulge = -1.0&lt;br /&gt;
      end&lt;br /&gt;
        MessageBox(&amp;quot;Error! &amp;quot; .. xy_origin_text .. &amp;quot; Must be set at a corner of the Material&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
        Table.xy_origin_text = &amp;quot;Unknown XY origin value!&amp;quot;&lt;br /&gt;
        MessageBox(&amp;quot;Error! &amp;quot; .. xy_origin_text .. &amp;quot; Must be set at a corner of the Material&amp;quot;)&lt;br /&gt;
      if Table.Orantation == &amp;quot;V&amp;quot; then&lt;br /&gt;
        Table.Direction1 = 0&lt;br /&gt;
        Table.Direction2 = 0&lt;br /&gt;
        Table.Direction3 = 0&lt;br /&gt;
        Table.Direction4 = 0&lt;br /&gt;
      else&lt;br /&gt;
        Table.Direction1 = 0&lt;br /&gt;
        Table.Direction2 = 0&lt;br /&gt;
        Table.Direction3 = 0&lt;br /&gt;
        Table.Direction4 = 0&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    -- Setup Fingers and Gaps&lt;br /&gt;
    Table.NoFingers0 = 1 + (Rounder(BoxJoint.MaterialLength / BoxJoint.MaterialThickness, 0))&lt;br /&gt;
    Table.NoFingers2 = Rounder(BoxJoint.NoFingers0 / 2, 0)&lt;br /&gt;
    Table.FingerSize = BoxJoint.MaterialLength /  BoxJoint.NoFingers0&lt;br /&gt;
    Table.NoFingers1 = BoxJoint.NoFingers0 - BoxJoint.NoFingers2&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetMaterialSettings===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function GetMaterialSettings(Table)&lt;br /&gt;
  local MaterialBlock = MaterialBlock()&lt;br /&gt;
  Table.MaterialBlockThickness = MaterialBlock.Thickness&lt;br /&gt;
  Table.xy_origin = MaterialBlock.XYOrigin&lt;br /&gt;
  if MaterialBlock.InMM then&lt;br /&gt;
    Table.Units  = &amp;quot;Drawing Units: mm&amp;quot;&lt;br /&gt;
    Table.Unit = true&lt;br /&gt;
    Table.Cal = 25.4&lt;br /&gt;
  else&lt;br /&gt;
    Table.Units  = &amp;quot;Drawing Units: inches&amp;quot;&lt;br /&gt;
    Table.Unit = false&lt;br /&gt;
    Table.Cal = 1.0&lt;br /&gt;
  end&lt;br /&gt;
  --local units&lt;br /&gt;
	if MaterialBlock.Width &amp;gt; MaterialBlock.Height then&lt;br /&gt;
    Table.Orantation = &amp;quot;H&amp;quot; -- Horizontal&lt;br /&gt;
	elseif MaterialBlock.Width &amp;lt; MaterialBlock.Height then&lt;br /&gt;
    Table.Orantation = &amp;quot;V&amp;quot;  -- Vertical&lt;br /&gt;
  else&lt;br /&gt;
    Table.Orantation = &amp;quot;S&amp;quot; -- Squair&lt;br /&gt;
	end&lt;br /&gt;
  if Table.xy_origin == MaterialBlock.BLC then&lt;br /&gt;
    Table.XYorigin = &amp;quot;Bottom Left Corner&amp;quot;&lt;br /&gt;
  elseif Table.xy_origin == MaterialBlock.BRC then&lt;br /&gt;
    Table.XYorigin = &amp;quot;Bottom Right Corner&amp;quot;&lt;br /&gt;
  elseif Table.xy_origin == MaterialBlock.TRC then&lt;br /&gt;
    Table.XYorigin = &amp;quot;Top Right Corner&amp;quot;&lt;br /&gt;
  else&lt;br /&gt;
    Table.XYorigin = &amp;quot;Top Left Corner&amp;quot;&lt;br /&gt;
  end -- if end&lt;br /&gt;
  Table.UnitDisplay  = &amp;quot;Note: Units: (&amp;quot; .. Table.Units ..&amp;quot;)&amp;quot;&lt;br /&gt;
  return true&lt;br /&gt;
end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===IsSingleSided===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function IsSingleSided(Table)&lt;br /&gt;
    local SingleSided = Table.job.IsSingleSided&lt;br /&gt;
    if not SingleSided then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error: Job must be a single sided job&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end  -- if end&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===IsDoubleSided===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function IsDoubleSided(Table)&lt;br /&gt;
  if not Table.job.IsDoubleSided then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Error: Job must be a Double Sided Project&amp;quot;)&lt;br /&gt;
    return false&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end  -- if end&lt;br /&gt;
end-- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===ShowSetting===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function ShowSetting(Table)&lt;br /&gt;
  local name = &amp;quot;&amp;quot;&lt;br /&gt;
      DisplayMessageBox(&lt;br /&gt;
    name .. &amp;quot; MaterialThickness = &amp;quot; .. tostring(Table.MaterialThickness) ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    name .. &amp;quot; BottleRad         = &amp;quot; .. tostring(Table.BottleRad)         ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    name .. &amp;quot; SideLenght        = &amp;quot; .. tostring(Table.SideLenght)        ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    name .. &amp;quot; SideHight         = &amp;quot; .. tostring(Table.SideHight)         ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    name .. &amp;quot; EndLenght         = &amp;quot; .. tostring(Table.EndLenght)         ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    name .. &amp;quot; EndHight          = &amp;quot; .. tostring(Table.EndHight)          ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    name .. &amp;quot; TopLenght         = &amp;quot; .. tostring(Table.TopLenght)         ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    name .. &amp;quot; TopWidht          = &amp;quot; .. tostring(Table.TopWidht)          ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    name .. &amp;quot; HandleLenght      = &amp;quot; .. tostring(Table.HandleLenght)      ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    name .. &amp;quot; HandleWidht       = &amp;quot; .. tostring(Table.HandleWidht)       ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    name .. &amp;quot; HandleRad         = &amp;quot; .. tostring(Table.HandleRad)         ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    name .. &amp;quot; MillingBitRad     = &amp;quot; .. tostring(Table.MillingBitRad)     ..&amp;quot;\n&amp;quot; ..&lt;br /&gt;
    &amp;quot;\n&amp;quot;)&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===MakeLayers===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function MakeLayers()&lt;br /&gt;
  local Red, Green, Blue = 0, 0, 0&lt;br /&gt;
  local function GetColor(str) -- returns color value for a Color Name&lt;br /&gt;
    local sx = str&lt;br /&gt;
    local Red = 0&lt;br /&gt;
    local Green = 0&lt;br /&gt;
    local Blue = 0&lt;br /&gt;
    local Colors = {}&lt;br /&gt;
    Colors.Black = &amp;quot;0,0,0&amp;quot;&lt;br /&gt;
    Colors.Red = &amp;quot;255,0,0&amp;quot;&lt;br /&gt;
    Colors.Blue = &amp;quot;0,0,255&amp;quot;&lt;br /&gt;
    Colors.Yellow = &amp;quot;255,255,0&amp;quot;&lt;br /&gt;
    Colors.Cyan = &amp;quot;0,255,255&amp;quot;&lt;br /&gt;
    Colors.Magenta = &amp;quot;255,0,255&amp;quot;&lt;br /&gt;
    Colors.Green = &amp;quot;0,128,0&amp;quot;&lt;br /&gt;
    if &amp;quot;&amp;quot; == str then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error: Empty string passed&amp;quot;)&lt;br /&gt;
    else&lt;br /&gt;
      str = Colors[str]&lt;br /&gt;
      if &amp;quot;string&amp;quot; == type(str) then&lt;br /&gt;
        if string.find(str, &amp;quot;,&amp;quot;) then&lt;br /&gt;
          Red   = tonumber(string.sub(str, 1, assert(string.find(str, &amp;quot;,&amp;quot;) - 1)))&lt;br /&gt;
          str  = string.sub(str, assert(string.find(str, &amp;quot;,&amp;quot;) + 1))&lt;br /&gt;
          Green = tonumber(string.sub(str, 1, assert(string.find(str, &amp;quot;,&amp;quot;) - 1)))&lt;br /&gt;
          Blue  = tonumber(string.sub(str, assert(string.find(str, &amp;quot;,&amp;quot;) + 1)))&lt;br /&gt;
        end&lt;br /&gt;
      else&lt;br /&gt;
        DisplayMessageBox(&amp;quot;Error: Color &amp;quot; .. sx .. &amp;quot; not Found&amp;quot; )&lt;br /&gt;
        Red = 0&lt;br /&gt;
        Green = 0&lt;br /&gt;
        Blue = 0&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    return Red, Green, Blue&lt;br /&gt;
  end&lt;br /&gt;
  local layer = Milling.job.LayerManager:GetLayerWithName(Milling.LNBackPocket)&lt;br /&gt;
        Red, Green, Blue = GetColor(Milling.LNBackPocketColor)&lt;br /&gt;
        layer:SetColor (Red, Green, Blue)&lt;br /&gt;
        layer = Milling.job.LayerManager:GetLayerWithName(Milling.LNBackProfile)&lt;br /&gt;
        Red, Green, Blue = GetColor(Milling.LNBackProfileColor)&lt;br /&gt;
        layer:SetColor (Red, Green, Blue)&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===MyLayerClear===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function MyLayerClear(LayerName)&lt;br /&gt;
  local Mylayer = Milling.job.LayerManager:GetLayerWithName(LayerName)&lt;br /&gt;
     if Mylayer.IsEmpty then&lt;br /&gt;
        Milling.job.LayerManager:RemoveLayer(Mylayer)&lt;br /&gt;
     end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===LayerClear===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function LayerClear()                       --  calling MyLayerClear&lt;br /&gt;
  MyLayerClear(Milling.LNBackPocket  .. &amp;quot;-Wall&amp;quot;)&lt;br /&gt;
  MyLayerClear(Milling.LNBackPocket  .. &amp;quot;-Base&amp;quot;)&lt;br /&gt;
  MyLayerClear(Milling.LNBackProfile .. &amp;quot;-Wall&amp;quot;)&lt;br /&gt;
  MyLayerClear(Milling.LNBackProfile .. &amp;quot;-Base&amp;quot;)&lt;br /&gt;
  MyLayerClear(&amp;quot;PartLabels&amp;quot;)&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Logic and Test Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
These functions are named as per there function or action.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CheckNumber===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function CheckNumber(num)&lt;br /&gt;
  if type(num) == &amp;quot;number&amp;quot; then&lt;br /&gt;
    return true&lt;br /&gt;
  else&lt;br /&gt;
   return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===AboveZero===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function AboveZero(num)&lt;br /&gt;
  if (type(num) == &amp;quot;number&amp;quot;) and (num &amp;gt; 0.0)then&lt;br /&gt;
    return true&lt;br /&gt;
  else&lt;br /&gt;
   return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
end -- function end&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===IsNumber()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function IsNumber(Val)                     --Return true if Val is number&lt;br /&gt;
    if tonumber(x) ~= nil then&lt;br /&gt;
      return true&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return false&lt;br /&gt;
  end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===IsEven()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function IsEven(IsEven_Number)             -- Returns True/False if number is even&lt;br /&gt;
    if (IsEven_Number % 2 == 0) then&lt;br /&gt;
      return true&lt;br /&gt;
    else&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===IsOdd()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function IsOdd(IsOdd_Number)                          -- Returns True/False if number is odd&lt;br /&gt;
    if(IsOdd_Number%2 == 0) then&lt;br /&gt;
      return false&lt;br /&gt;
    end -- end if&lt;br /&gt;
    return true&lt;br /&gt;
  end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===IsNegative()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function IsNegative(x)                     -- Returns True/False if number is a negative number  &lt;br /&gt;
  if x &amp;gt;=0.0 then&lt;br /&gt;
    return false&lt;br /&gt;
  else&lt;br /&gt;
    return true&lt;br /&gt;
  end -- if end&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
===IsAllNumber()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function IsAllNumber(str)                  -- Returns True/False if finds all numbers in string&lt;br /&gt;
  local out = true                                     &lt;br /&gt;
  local let = &amp;quot;&amp;quot;&lt;br /&gt;
  for i = 1, #str do&lt;br /&gt;
    let = str:byte(i)&lt;br /&gt;
    if (let ~= 48) and (let ~= 49) and (let ~= 50) and (let ~= 51) and&lt;br /&gt;
       (let ~= 52) and (let ~= 53) and (let ~= 54) and (let ~= 55) and&lt;br /&gt;
       (let ~= 56) and (let ~= 57) and (let ~= 46) then&lt;br /&gt;
      out = false&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- for end&lt;br /&gt;
  return out        -- send out the return&lt;br /&gt;
end  -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===NonNumber()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function NonNumber(Val)                    -- Return true if val is not number&lt;br /&gt;
    if tonumber(x) ~= nil then&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return true&lt;br /&gt;
  end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===NumberType()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function NumberType(Val)                   -- Return true if val is not number&lt;br /&gt;
    if math.type(x) == &amp;quot;integer&amp;quot; then&lt;br /&gt;
      return &amp;quot;integer&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
      return &amp;quot;float&amp;quot;&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Math Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===ArcSegment()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function ArcSegment(p1, p2, Rad)                       -- Returns the Arc Segment&lt;br /&gt;
  local chord = math.sqrt(((p2.x - p1.x) ^ 2) + ((p2.y - p1.y) ^ 2))&lt;br /&gt;
  local segment = (Rad - (0.5 * (math.sqrt((4.0 * Rad^2) - chord^2))))&lt;br /&gt;
  return segment&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===D(x) Doubles x===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function D(x)                                           -- Returns double the value&lt;br /&gt;
  return x * 2.0&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===H(x) Halfs x===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function H(x)                                           -- Returns half the value&lt;br /&gt;
  return x * 0.5&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===C(x) Returns x by scale===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function C(x)                                           -- Returns scale value&lt;br /&gt;
  return x * Project.Cal&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===ChordSag2Radius()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function ChordSag2Radius (Chr, Seg)                     -- Returns the Rad from Chord and Seg&lt;br /&gt;
  local rad = ((((Chr * Chr)/(Seg * 4)) + Seg) / 2.0)&lt;br /&gt;
  return rad&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===RadSag2Chord()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function RadSag2Chord(Rad, Seg)                         -- Returns the Chord from Rad and Seg&lt;br /&gt;
  local Ang = 2 * math.acos(1 - (Seg/Rad))&lt;br /&gt;
  local Chord = (2 * Rad) * math.sin(Ang * 0.5)&lt;br /&gt;
  return Chord&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===RadChord2Segment()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function RadChord2Segment (Rad, Chord)       -- Returns the Arc Segment from Rad and Chord&lt;br /&gt;
  local segment = (Rad - (0.5 * (math.sqrt((4.0 * Rad^2) - Chord^2))))&lt;br /&gt;
  return segment&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===RoundTo()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function RoundTo(Num, Per)                   -- Returns the number from&lt;br /&gt;
  local Head = Num &amp;lt; 0 and math.ceil(Num) or math.floor(Num)&lt;br /&gt;
  local Tail = Num - Head&lt;br /&gt;
  local Value = Head + tonumber(string.sub(tostring(Tail), 1, Per + 2))&lt;br /&gt;
  return Value&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===Round()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function Round(x)&lt;br /&gt;
  return x&amp;gt;=0 and math.floor(x+0.5) or math.ceil(x-0.5)&lt;br /&gt;
end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DecimalPlaces()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DecimalPlaces(Dnum, Plac)&lt;br /&gt;
  return tonumber(string.sub(tostring(Dnum)  .. &amp;quot;000000000000000000000000000000000000&amp;quot;,1, string.len(tostring(math.floor(Dnum))) + 1 + Plac))&lt;br /&gt;
end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===ToInteger()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function ToInteger( x )&lt;br /&gt;
    local num = tonumber( x )&lt;br /&gt;
    return num &amp;lt; 0 and math.ceil( num ) or math.floor( num )&lt;br /&gt;
end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===TrigIt===&lt;br /&gt;
Finds all 5 properties of a triangle&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function TrigIt(A, B, AB, AC, BC)&lt;br /&gt;
-- Sub Function to help other functions&lt;br /&gt;
-- Call = A, B, AB, AC, BC = Trig(A, B, AB, AC, BC)&lt;br /&gt;
-- C is the corner, A = small ang and B is the big angle&lt;br /&gt;
-- returns all values&lt;br /&gt;
-- A, B = angles&lt;br /&gt;
-- C = 90.0 Deg&lt;br /&gt;
-- B to C (BC) is Run - Base - adjacent&lt;br /&gt;
-- A to C (AC) is Rise - Height - opposite&lt;br /&gt;
-- A to B (AB) is Slope - hypotenuse&lt;br /&gt;
    if (B &amp;gt; 0.0) and (A == 0.0) then&lt;br /&gt;
      A = math.deg(math.rad(90) - math.rad(B))&lt;br /&gt;
    end&lt;br /&gt;
    if (A &amp;gt; 0.0) and (B == 0.0) then&lt;br /&gt;
      B = math.deg(math.rad(90) - math.rad(A))&lt;br /&gt;
    end&lt;br /&gt;
    if  (AC &amp;gt; 0.0) and (BC &amp;gt; 0.0) then&lt;br /&gt;
      AB = math.sqrt((AC ^ 2) + (BC ^ 2))&lt;br /&gt;
      A = math.deg(math.atan(BC/AC))&lt;br /&gt;
      B = math.deg(math.rad(90) - math.rad(A))&lt;br /&gt;
    elseif (AB &amp;gt; 0.0) and (BC &amp;gt; 0.0) then&lt;br /&gt;
      AB = math.sqrt((AB ^ 2) - (BC ^ 2))&lt;br /&gt;
      A = math.deg(math.atan(BC/AC))&lt;br /&gt;
      B = math.deg(math.rad(90) - math.rad(A))&lt;br /&gt;
    elseif (AB &amp;gt; 0.0) and (AC &amp;gt; 0.0) then&lt;br /&gt;
      AB = math.sqrt((AB ^ 2) - (AC ^ 2))&lt;br /&gt;
      A = math.deg(math.atan(BC/AC))&lt;br /&gt;
      B = math.deg(math.rad(90) - math.rad(A))&lt;br /&gt;
    elseif (A &amp;gt; 0.0) and (AC &amp;gt; 0.0) then&lt;br /&gt;
      AB = AC / math.cos(math.rad(A))&lt;br /&gt;
      BC = AB * math.sin(math.rad(A))&lt;br /&gt;
    elseif (A &amp;gt; 0.0) and (BC &amp;gt; 0.0) then&lt;br /&gt;
      AB = BC / math.sin(math.rad(A))&lt;br /&gt;
      AC = AB * math.cos(math.rad(A))&lt;br /&gt;
    elseif (A &amp;gt; 0.0) and (AB &amp;gt; 0.0) then&lt;br /&gt;
      BC = AB * math.sin(math.rad(A))&lt;br /&gt;
      AC = AB * math.cos(math.rad(A))&lt;br /&gt;
    else&lt;br /&gt;
      MessageBox(&amp;quot;Error: No Missing Value&amp;quot;)&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return A, B, AB, AC, BC&lt;br /&gt;
  end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
==Registry Read and Write Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DocVarChk()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DocVarChk(Name, Value)&lt;br /&gt;
  local job = VectricJob()&lt;br /&gt;
  local document_variable_list = job.DocumentVariables&lt;br /&gt;
  return document_variable_list:DocumentVariableExists(Name)&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DocVarGet()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DocVarGet(Name)&lt;br /&gt;
  local job = VectricJob()&lt;br /&gt;
  local document_variable_list = job.DocumentVariables&lt;br /&gt;
  return document_variable_list:GetDocumentVariable(Name, 0.0)&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===DocVarSet()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function DocVarSet(Name, Value)&lt;br /&gt;
  local job = VectricJob()&lt;br /&gt;
  local document_variable_list = job.DocumentVariables&lt;br /&gt;
  return document_variable_list:SetDocumentVariable(Name, Value)&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===RegistryReadMaterial()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function RegistryReadMaterial()                -- Read from Registry Material values for LUA Bit&lt;br /&gt;
  local RegistryRead              = Registry(&amp;quot;Material&amp;quot;)&lt;br /&gt;
  Milling.SafeZGap                = Rounder(RegistryRead:GetString(&amp;quot;SafeZGap&amp;quot;,              &amp;quot;0.500&amp;quot;), 4)&lt;br /&gt;
  Milling.StartZGap               = Rounder(RegistryRead:GetString(&amp;quot;StartZGap&amp;quot;,             &amp;quot;0.500&amp;quot;), 4)&lt;br /&gt;
  Milling.HomeX                   = Rounder(RegistryRead:GetString(&amp;quot;HomeX&amp;quot;,                 &amp;quot;0.000&amp;quot;), 4)&lt;br /&gt;
  Milling.HomeY                   = Rounder(RegistryRead:GetString(&amp;quot;HomeY&amp;quot;,                 &amp;quot;0.000&amp;quot;), 4)&lt;br /&gt;
  Milling.HomeZGap                = Rounder(RegistryRead:GetString(&amp;quot;HomeZGap&amp;quot;,              &amp;quot;0.750&amp;quot;), 4)&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===RegistryLastTenFiles()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function RegistryLastTenFiles(FileName)        -- Adds to the top ten Log file list&lt;br /&gt;
  local Registry = Registry(RegName)&lt;br /&gt;
  LogFile.File10 = Registry:GetString(&amp;quot;LogFile.File09&amp;quot;, &amp;quot;No Log Yet&amp;quot; )&lt;br /&gt;
  LogFile.File09 = Registry:GetString(&amp;quot;LogFile.File08&amp;quot;, &amp;quot;No Log Yet&amp;quot; )&lt;br /&gt;
  LogFile.File08 = Registry:GetString(&amp;quot;LogFile.File07&amp;quot;, &amp;quot;No Log Yet&amp;quot; )&lt;br /&gt;
  LogFile.File07 = Registry:GetString(&amp;quot;LogFile.File06&amp;quot;, &amp;quot;No Log Yet&amp;quot; )&lt;br /&gt;
  LogFile.File06 = Registry:GetString(&amp;quot;LogFile.File05&amp;quot;, &amp;quot;No Log Yet&amp;quot; )&lt;br /&gt;
  LogFile.File05 = Registry:GetString(&amp;quot;LogFile.File04&amp;quot;, &amp;quot;No Log Yet&amp;quot; )&lt;br /&gt;
  LogFile.File04 = Registry:GetString(&amp;quot;LogFile.File03&amp;quot;, &amp;quot;No Log Yet&amp;quot; )&lt;br /&gt;
  LogFile.File03 = Registry:GetString(&amp;quot;LogFile.File02&amp;quot;, &amp;quot;No Log Yet&amp;quot; )&lt;br /&gt;
  LogFile.File02 = Registry:GetString(&amp;quot;LogFile.File01&amp;quot;, &amp;quot;No Log Yet&amp;quot; )&lt;br /&gt;
  LogFile.File01 = FileName&lt;br /&gt;
  return FileName&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===RegistryRead()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function RegistryRead()                        -- Read from Registry values&lt;br /&gt;
  local RegistryRead = Registry(&amp;quot;RegName&amp;quot;)&lt;br /&gt;
  local Yes_No       = RegistryRead:GetBool(&amp;quot;BaseDim.Yes_No&amp;quot;, ture)&lt;br /&gt;
  local CabHeight    = RegistryRead:GetDouble(&amp;quot;BaseDim.CabHeight&amp;quot;, 35.500)&lt;br /&gt;
  local CabCount     = RegistryRead:GetInt(&amp;quot;BaseDim.CabCount&amp;quot;, 36)&lt;br /&gt;
  local Name         = RegistryRead:GetString(&amp;quot;BaseDim.Name&amp;quot;, &amp;quot;Words&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  Milling.MillTool1.FeedRate                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool1.FeedRate&amp;quot;,              30.000)&lt;br /&gt;
  Milling.MillTool1.InMM                    = RegistryRead:GetBool(&amp;quot;Milling.MillTool1.InMM &amp;quot;,                   false)&lt;br /&gt;
  Milling.MillTool1.Name                    = RegistryRead:GetString(&amp;quot;Milling.MillTool1.Name&amp;quot;,                  &amp;quot;No Tool Selected&amp;quot;)&lt;br /&gt;
  Milling.MillTool1.BitType                 = RegistryRead:GetString(&amp;quot;Milling.MillTool1.BitType&amp;quot;,               &amp;quot;END_MILL&amp;quot;) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
  Milling.MillTool1.RateUnits               = RegistryRead:GetInt(&amp;quot;Milling.MillTool1.RateUnits&amp;quot;,                4)&lt;br /&gt;
  Milling.MillTool1.SpindleSpeed            = RegistryRead:GetInt(&amp;quot;Milling.MillTool1.SpindleSpeed&amp;quot;,             20000)&lt;br /&gt;
  Milling.MillTool1.ToolNumber              = RegistryRead:GetInt(&amp;quot;Milling.MillTool1.ToolNumber&amp;quot;,               1)&lt;br /&gt;
  Milling.MillTool1.Stepdown                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool1.Stepdown&amp;quot;,              0.2000)&lt;br /&gt;
  Milling.MillTool1.Stepover                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool1.Stepover&amp;quot;,              0.0825)&lt;br /&gt;
  Milling.MillTool1.ToolDia                 = RegistryRead:GetDouble(&amp;quot;Milling.MillTool1.ToolDia&amp;quot;,               0.1250)&lt;br /&gt;
  Milling.MillTool1.PlungeRate              = RegistryRead:GetDouble(&amp;quot;Milling.MillTool1.PlungeRate&amp;quot;,            15.000)&lt;br /&gt;
&lt;br /&gt;
  Milling.MillTool2.FeedRate                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool2.FeedRate&amp;quot;,              30.000)&lt;br /&gt;
  Milling.MillTool2.InMM                    = RegistryRead:GetBool(&amp;quot;Milling.MillTool2.InMM &amp;quot;,                   false)&lt;br /&gt;
  Milling.MillTool2.Name                    = RegistryRead:GetString(&amp;quot;Milling.MillTool2.Name&amp;quot;,                  &amp;quot;No Tool Selected&amp;quot;)&lt;br /&gt;
  Milling.MillTool2.BitType                 = RegistryRead:GetString(&amp;quot;Milling.MillTool2.BitType&amp;quot;,               &amp;quot;BALL_NOSE&amp;quot;) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
  Milling.MillTool2.RateUnits               = RegistryRead:GetInt(&amp;quot;Milling.MillTool2.RateUnits&amp;quot;,                4)&lt;br /&gt;
  Milling.MillTool2.SpindleSpeed            = RegistryRead:GetInt(&amp;quot;Milling.MillTool2.SpindleSpeed&amp;quot;,             20000)&lt;br /&gt;
  Milling.MillTool2.ToolNumber              = RegistryRead:GetInt(&amp;quot;Milling.MillTool2.ToolNumber&amp;quot;,               2)&lt;br /&gt;
  Milling.MillTool2.Stepdown                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool2.Stepdown&amp;quot;,              0.2000)&lt;br /&gt;
  Milling.MillTool2.Stepover                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool2.Stepover&amp;quot;,              0.0825)&lt;br /&gt;
  Milling.MillTool2.ToolDia                 = RegistryRead:GetDouble(&amp;quot;Milling.MillTool2.ToolDia&amp;quot;,               0.1250)&lt;br /&gt;
  Milling.MillTool2.PlungeRate              = RegistryRead:GetDouble(&amp;quot;Milling.MillTool2.PlungeRate&amp;quot;,            15.000)&lt;br /&gt;
&lt;br /&gt;
  Milling.MillTool3.FeedRate                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool3.FeedRate&amp;quot;,              30.000)&lt;br /&gt;
  Milling.MillTool3.InMM                    = RegistryRead:GetBool(&amp;quot;Milling.MillTool3.InMM&amp;quot;,                    false)&lt;br /&gt;
  Milling.MillTool3.Name                    = RegistryRead:GetString(&amp;quot;Milling.MillTool3.Name&amp;quot;,                  &amp;quot;No Tool Selected&amp;quot;)&lt;br /&gt;
  Milling.MillTool3.BitType                 = RegistryRead:GetString(&amp;quot;Milling.MillTool3.BitType&amp;quot;,               &amp;quot;END_MILL&amp;quot;)  -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
  Milling.MillTool3.RateUnits               = RegistryRead:GetInt(&amp;quot;Milling.MillTool3.RateUnits&amp;quot;,                4)&lt;br /&gt;
  Milling.MillTool3.SpindleSpeed            = RegistryRead:GetInt(&amp;quot;Milling.MillTool3.SpindleSpeed&amp;quot;,             20000)&lt;br /&gt;
  Milling.MillTool3.ToolNumber              = RegistryRead:GetInt(&amp;quot;Milling.MillTool3.ToolNumber&amp;quot;,               3)&lt;br /&gt;
  Milling.MillTool3.Stepdown                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool3.Stepdown&amp;quot;,              0.2000)&lt;br /&gt;
  Milling.MillTool3.Stepover                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool3.Stepover&amp;quot;,              0.0825)&lt;br /&gt;
  Milling.MillTool3.ToolDia                 = RegistryRead:GetDouble(&amp;quot;Milling.MillTool3.ToolDia&amp;quot;,               0.1250)&lt;br /&gt;
  Milling.MillTool3.PlungeRate              = RegistryRead:GetDouble(&amp;quot;Milling.MillTool3.PlungeRate&amp;quot;,            15.000)&lt;br /&gt;
&lt;br /&gt;
  Milling.MillTool4.FeedRate                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool4.FeedRate&amp;quot;,              30.000)&lt;br /&gt;
  Milling.MillTool4.InMM                    = RegistryRead:GetBool(&amp;quot;Milling.MillTool4.InMM &amp;quot;,                   false)&lt;br /&gt;
  Milling.MillTool4.Name                    = RegistryRead:GetString(&amp;quot;Milling.MillTool4.Name&amp;quot;,                  &amp;quot;No Tool Selected&amp;quot;)&lt;br /&gt;
  Milling.MillTool4.PlungeRate              = RegistryRead:GetDouble(&amp;quot;Milling.MillTool4.PlungeRate&amp;quot;,            15.000)&lt;br /&gt;
  Milling.MillTool4.RateUnits               = RegistryRead:GetInt(&amp;quot;Milling.MillTool4.RateUnits&amp;quot;,                4)&lt;br /&gt;
  Milling.MillTool4.SpindleSpeed            = RegistryRead:GetInt(&amp;quot;Milling.MillTool4.SpindleSpeed&amp;quot;,             20000)&lt;br /&gt;
  Milling.MillTool4.Stepdown                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool4.Stepdown&amp;quot;,              0.2000)&lt;br /&gt;
  Milling.MillTool4.Stepover                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool4.Stepover&amp;quot;,              0.0825)&lt;br /&gt;
  Milling.MillTool4.ToolDia                 = RegistryRead:GetDouble(&amp;quot;Milling.MillTool4.ToolDia&amp;quot;,               0.1250)&lt;br /&gt;
  Milling.MillTool4.ToolNumber              = RegistryRead:GetInt(&amp;quot;Milling.MillTool4.ToolNumber&amp;quot;,               5)&lt;br /&gt;
&lt;br /&gt;
  Milling.MillTool5.FeedRate                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool5.FeedRate&amp;quot;,              30.000)&lt;br /&gt;
  Milling.MillTool5.InMM                    = RegistryRead:GetBool(&amp;quot;Milling.MillTool5.InMM &amp;quot;,                   false)&lt;br /&gt;
  Milling.MillTool5.Name                    = RegistryRead:GetString(&amp;quot;Milling.MillTool5.Name&amp;quot;,                  &amp;quot;No Tool Selected&amp;quot;)&lt;br /&gt;
  Milling.MillTool5.PlungeRate              = RegistryRead:GetDouble(&amp;quot;Milling.MillTool5.PlungeRate&amp;quot;,            15.000)&lt;br /&gt;
  Milling.MillTool5.RateUnits               = RegistryRead:GetInt(&amp;quot;Milling.MillTool5.RateUnits&amp;quot;,                4)&lt;br /&gt;
  Milling.MillTool5.SpindleSpeed            = RegistryRead:GetInt(&amp;quot;Milling.MillTool5.SpindleSpeed&amp;quot;,             20000)&lt;br /&gt;
  Milling.MillTool5.Stepdown                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool5.Stepdown&amp;quot;,              0.2000)&lt;br /&gt;
  Milling.MillTool5.Stepover                = RegistryRead:GetDouble(&amp;quot;Milling.MillTool5.Stepover&amp;quot;,              0.0825)&lt;br /&gt;
  Milling.MillTool5.ToolDia                 = RegistryRead:GetDouble(&amp;quot;Milling.MillTool5.ToolDia&amp;quot;,               0.1250)&lt;br /&gt;
  Milling.MillTool5.ToolNumber              = RegistryRead:GetInt(&amp;quot;Milling.MillTool5.ToolNumber&amp;quot;,               6)&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===RegistryWrite()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function RegistryWrite()                       -- Write to Registry values&lt;br /&gt;
  local RegistryWrite = Registry(&amp;quot;RegName&amp;quot;)&lt;br /&gt;
  local RegValue&lt;br /&gt;
  RegValue = RegistryWrite:SetBool(&amp;quot;ProjectQuestion.CabinetName&amp;quot;, true)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;BaseDim.CabDepth&amp;quot;, 23.0000)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;BaseDim.CabHeight&amp;quot;, 35)&lt;br /&gt;
  RegValue = RegistryWrite:SetString(&amp;quot;BaseDim.CabLength&amp;quot;, &amp;quot;Words&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool1.FeedRate&amp;quot; ,     Milling.MillTool1.FeedRate)&lt;br /&gt;
  RegValue = RegistryWrite:SetBool(&amp;quot;Milling.MillTool1.InMM&amp;quot;,            Milling.MillTool1.InMM)&lt;br /&gt;
  RegValue = RegistryWrite:SetString(&amp;quot;Milling.MillTool1.Name&amp;quot;,          Milling.MillTool1.Name)&lt;br /&gt;
  RegValue = RegistryWrite:SetString(&amp;quot;Milling.MillTool1.BitType&amp;quot;,       Milling.MillTool1.BitType)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool1.PlungeRate&amp;quot; ,   Milling.MillTool1.PlungeRate)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool1.RateUnits&amp;quot;,        Milling.MillTool1.RateUnits)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool1.SpindleSpeed&amp;quot;,     Milling.MillTool1.SpindleSpeed)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool1.Stepdown&amp;quot; ,     Milling.MillTool1.Stepdown)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool1.Stepover&amp;quot; ,     Milling.MillTool1.Stepover)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool1.ToolDia&amp;quot; ,      Milling.MillTool1.ToolDia)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool1.ToolNumber&amp;quot;,       Milling.MillTool1.ToolNumber)&lt;br /&gt;
&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool2.FeedRate&amp;quot; ,     Milling.MillTool2.FeedRate)&lt;br /&gt;
  RegValue = RegistryWrite:SetBool(&amp;quot;Milling.MillTool2.InMM&amp;quot;,            Milling.MillTool2.InMM)&lt;br /&gt;
  RegValue = RegistryWrite:SetString(&amp;quot;Milling.MillTool2.Name&amp;quot;,          Milling.MillTool2.Name)&lt;br /&gt;
  RegValue = RegistryWrite:SetString(&amp;quot;Milling.MillTool2.BitType&amp;quot;,       Milling.MillTool2.BitType)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool2.PlungeRate&amp;quot; ,   Milling.MillTool2.PlungeRate)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool2.RateUnits&amp;quot;,        Milling.MillTool2.RateUnits)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool2.SpindleSpeed&amp;quot;,     Milling.MillTool2.SpindleSpeed)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool2.Stepdown&amp;quot; ,     Milling.MillTool2.Stepdown)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool2.Stepover&amp;quot; ,     Milling.MillTool2.Stepover)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool2.ToolDia&amp;quot; ,      Milling.MillTool2.ToolDia)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool2.ToolNumber&amp;quot;,       Milling.MillTool2.ToolNumber)&lt;br /&gt;
&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool3.FeedRate&amp;quot; ,     Milling.MillTool3.FeedRate)&lt;br /&gt;
  RegValue = RegistryWrite:SetBool(&amp;quot;Milling.MillTool3.InMM&amp;quot;,            Milling.MillTool3.InMM)&lt;br /&gt;
  RegValue = RegistryWrite:SetString(&amp;quot;Milling.MillTool3.Name&amp;quot;,          Milling.MillTool3.Name)&lt;br /&gt;
  RegValue = RegistryWrite:SetString(&amp;quot;Milling.MillTool3.BitType&amp;quot;,       Milling.MillTool3.BitType)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool3.PlungeRate&amp;quot;,    Milling.MillTool3.PlungeRate)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool3.RateUnits&amp;quot;,        Milling.MillTool3.RateUnits)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool3.SpindleSpeed&amp;quot;,     Milling.MillTool3.SpindleSpeed)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool3.Stepdown&amp;quot; ,     Milling.MillTool3.Stepdown)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool3.Stepover&amp;quot; ,     Milling.MillTool3.Stepover)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool3.ToolDia&amp;quot; ,      Milling.MillTool3.ToolDia)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool3.ToolNumber&amp;quot;,       Milling.MillTool3.ToolNumber)&lt;br /&gt;
&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool4.FeedRate&amp;quot; ,     Milling.MillTool4.FeedRate)&lt;br /&gt;
  RegValue = RegistryWrite:SetBool(&amp;quot;Milling.MillTool4.InMM&amp;quot;,            Milling.MillTool4.InMM)&lt;br /&gt;
  RegValue = RegistryWrite:SetString(&amp;quot;Milling.MillTool4.Name&amp;quot;,          Milling.MillTool4.Name)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool4.PlungeRate&amp;quot; ,   Milling.MillTool4.PlungeRate)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool4.RateUnits&amp;quot;,        Milling.MillTool4.RateUnits)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool4.SpindleSpeed&amp;quot;,     Milling.MillTool4.SpindleSpeed)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool4.Stepdown&amp;quot; ,     Milling.MillTool4.Stepdown)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool4.Stepover&amp;quot; ,     Milling.MillTool4.Stepover)&lt;br /&gt;
  RegValue = RegistryWrite:SetDouble(&amp;quot;Milling.MillTool4.ToolDia&amp;quot; ,      Milling.MillTool4.ToolDia)&lt;br /&gt;
  RegValue = RegistryWrite:SetInt(&amp;quot;Milling.MillTool4.ToolNumber&amp;quot;,       Milling.MillTool4.ToolNumber)&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===REG_CheckRegistryBool()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function REG_CheckRegistryBool()               -- Checks Registry for Bool values&lt;br /&gt;
  local RegistryRead = Registry(&amp;quot;RegName&amp;quot;)&lt;br /&gt;
  if RegistryRead:BoolExists(&amp;quot;ProjectQuestion.Runtool&amp;quot;) then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Alert: The Runtool value is saved.&amp;quot;)&lt;br /&gt;
  else&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Alert: The Runtool value is not saved.&amp;quot;)&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===REG_CheckRegistryDouble()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function REG_CheckRegistryDouble()             -- Checks Registry for Double values&lt;br /&gt;
  local RegistryRead = Registry(&amp;quot;RegName&amp;quot;)&lt;br /&gt;
  if RegistryRead:DoubleExists(&amp;quot;ProjectQuestion.ProjectCost&amp;quot;) then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Alert: The project cost is saved.&amp;quot;)&lt;br /&gt;
  else&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Alert: The Project Cost is not saved.&amp;quot;)&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===REG_CheckRegistryInt()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function REG_CheckRegistryInt()                -- Checks Registry for Int values&lt;br /&gt;
  local RegistryRead = Registry(&amp;quot;RegName&amp;quot;)&lt;br /&gt;
  if RegistryRead:IntExists(&amp;quot;ProjectQuestion.ProjectCount&amp;quot;) then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Alert: The Project Count is saved.&amp;quot;)&lt;br /&gt;
  else&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Alert: The Project Count is not saved.&amp;quot;)&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===REG_CheckRegistryString()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function REG_CheckRegistryString()             -- Checks Registry for String values&lt;br /&gt;
  local RegistryRead = Registry(&amp;quot;RegName&amp;quot;)&lt;br /&gt;
  if RegistryRead:StringExists(&amp;quot;ProjectQuestion.ProjectPath&amp;quot;) then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Alert: The Project path is saved.&amp;quot;)&lt;br /&gt;
  else&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Alert: The Project path is not saved.&amp;quot;)&lt;br /&gt;
  end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==String Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===StringToArraySplit===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function StringToArraySplit(s, delimiter)&lt;br /&gt;
--[[&lt;br /&gt;
split_string = StringToArraySplit(&amp;quot;Hello World,Jim,Bill,Tom&amp;quot;, &amp;quot;,&amp;quot;)&lt;br /&gt;
Returns = array&lt;br /&gt;
-- split_string[1] = &amp;quot;Hello World,)&lt;br /&gt;
-- split_string[2] = &amp;quot;Jim&amp;quot;&lt;br /&gt;
]]&lt;br /&gt;
  result = {};&lt;br /&gt;
  for match in (s..delimiter):gmatch(&amp;quot;(.-)&amp;quot;..delimiter) do&lt;br /&gt;
      table.insert(result, match)&lt;br /&gt;
  end&lt;br /&gt;
  return result&lt;br /&gt;
end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===WrapString===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
function WrapString(Str, Wid)                           -- wraps text at the nearest space and puts a return char in the space location&lt;br /&gt;
  --[[  How to use:&lt;br /&gt;
  Call WrapString(string, Number)&lt;br /&gt;
 WrapString(&amp;quot;Jim is a tall man that lives in Texas. He was raised in North East Texas on 1000 acres from 1970 to 1982. This is a man that knows numbers of great people from a round the world.&amp;quot;, 40)&lt;br /&gt;
 returns &amp;quot;Jim is a tall man that lives in Texas.\n&lt;br /&gt;
          He was raised in North East Texas on\n&lt;br /&gt;
          1000 acres from 1970 to 1982. This is a man\n&lt;br /&gt;
          that knows numbers of great people from\n&lt;br /&gt;
          a round the world.&amp;quot;&lt;br /&gt;
 ]]&lt;br /&gt;
  local Wider = Wid&lt;br /&gt;
  local Posx = string.len(Str)&lt;br /&gt;
  local StrLen = string.len(Str)&lt;br /&gt;
  local pt = 0&lt;br /&gt;
  local function FindSpace(MyStr)&lt;br /&gt;
  local Pos = string.len(MyStr)&lt;br /&gt;
  local str = MyStr&lt;br /&gt;
    if string.find(MyStr, &amp;quot; &amp;quot;) ~= nil then&lt;br /&gt;
      while Pos&amp;gt;0 do&lt;br /&gt;
        Pos = Pos - 1&lt;br /&gt;
          if (string.byte(string.sub(str,-1)) == 32) then&lt;br /&gt;
            break&lt;br /&gt;
          else&lt;br /&gt;
            str = string.sub(str, 1, Pos)&lt;br /&gt;
          end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    return Pos&lt;br /&gt;
  end&lt;br /&gt;
  if StrLen &amp;gt; Wider then&lt;br /&gt;
    while Wider &amp;lt; Posx do&lt;br /&gt;
      pt = FindSpace(string.sub(Str,1, Wider))&lt;br /&gt;
      Str = string.sub(Str, 1, pt) .. &amp;quot;\n&amp;quot; ..  string.sub(Str, pt +2)&lt;br /&gt;
      Wider = Wider + Wid&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  return Str&lt;br /&gt;
end -- function end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CleanString===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
function CleanString(inStr)                         -- Check for ascii letters below 127&lt;br /&gt;
  local outStr, str1 = &amp;quot;&amp;quot;&lt;br /&gt;
  local inStrLen = string.len(inStr)&lt;br /&gt;
  for i = 1, inStrLen ,1 do&lt;br /&gt;
    str1 = string.sub(inStr, i, i)&lt;br /&gt;
    if string.byte(str1) &amp;lt;= 127 then&lt;br /&gt;
     outStr=outStr .. str1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  return outStr&lt;br /&gt;
end -- function end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetDiameterAndCentre===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
function CheckString(YourStr)                          -- Check string for specal bite chars for HTML&lt;br /&gt;
  local function FindLetter(TheStr, TestChar)&lt;br /&gt;
    local outStr = false&lt;br /&gt;
    local strChar = &amp;quot;&amp;quot;&lt;br /&gt;
    local TheStrLen = string.len(TheStr)&lt;br /&gt;
    for i = 1, TheStrLen ,1 do&lt;br /&gt;
      strChar = string.sub(TheStr, i, i)&lt;br /&gt;
      if string.byte(strChar) == string.byte(TestChar) then&lt;br /&gt;
        outStr = true&lt;br /&gt;
        break&lt;br /&gt;
      end&lt;br /&gt;
    end&lt;br /&gt;
    return outStr&lt;br /&gt;
  end -- function end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===GetDiameterAndCentre===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
  local StrTest = false&lt;br /&gt;
  StrTest = SwitchLetter(YourStr,  &amp;quot;&amp;amp;&amp;quot;)  -- Non frendly File Name letters&lt;br /&gt;
  StrTest = SwitchLetter(YourStr,  &amp;quot;#&amp;quot;)&lt;br /&gt;
  StrTest = SwitchLetter(YourStr,  &amp;quot;@&amp;quot;)&lt;br /&gt;
  StrTest = SwitchLetter(YourStr,  &amp;quot;^&amp;quot;)&lt;br /&gt;
  StrTest = SwitchLetter(YourStr,  &amp;quot;$&amp;quot;)&lt;br /&gt;
    return outStr&lt;br /&gt;
end -- function end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===MakeHTMLReady()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
function MakeHTMLReady(MyStr)                          -- fix's string with special bite chars for HTML&lt;br /&gt;
  local function SwitchLetter(MyStr, MyChar, NewStr)&lt;br /&gt;
  local outStr, str1 = &amp;quot;&amp;quot;&lt;br /&gt;
  local inStrLen = string.len(MyStr)&lt;br /&gt;
  for i = 1, inStrLen ,1 do&lt;br /&gt;
    str1 = string.sub(MyStr, i, i)&lt;br /&gt;
    if string.byte(str1) == string.byte(MyChar) then&lt;br /&gt;
     outStr=outStr .. NewStr&lt;br /&gt;
     else&lt;br /&gt;
         outStr=outStr .. str1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  return outStr&lt;br /&gt;
end -- function end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===SwitchLetterTest===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function SwitchLetterTest(MyStr)&lt;br /&gt;
  local outStr = &amp;quot;&amp;quot;&lt;br /&gt;
  outStr = SwitchLetter(MyStr, &amp;quot;!&amp;quot;,	&amp;quot;&amp;amp;#33;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;#&amp;quot;,	&amp;quot;&amp;amp;#35;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;$&amp;quot;,	&amp;quot;&amp;amp;#36;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;%&amp;quot;,	&amp;quot;&amp;amp;#37;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;&amp;amp;&amp;quot;,	&amp;quot;&amp;amp;#38;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;'&amp;quot;,	&amp;quot;&amp;amp;#39;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;(&amp;quot;,	&amp;quot;&amp;amp;#40;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;)&amp;quot;,	&amp;quot;&amp;amp;#41;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;*&amp;quot;,	&amp;quot;&amp;amp;#42;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;+&amp;quot;,	&amp;quot;&amp;amp;#43;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;,&amp;quot;,	&amp;quot;&amp;amp;#44;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;-&amp;quot;,	&amp;quot;&amp;amp;#45;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;.&amp;quot;,	&amp;quot;&amp;amp;#46;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;/&amp;quot;,	&amp;quot;&amp;amp;#47;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;:&amp;quot;,	&amp;quot;&amp;amp;#58;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;;&amp;quot;,	&amp;quot;&amp;amp;#59;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;&amp;lt;&amp;quot;,	&amp;quot;&amp;amp;#60;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;=&amp;quot;,	&amp;quot;&amp;amp;#61;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;&amp;gt;&amp;quot;,	&amp;quot;&amp;amp;#62;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;?&amp;quot;,	&amp;quot;&amp;amp;#63;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;@&amp;quot;,	&amp;quot;&amp;amp;#64;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;[&amp;quot;,	&amp;quot;&amp;amp;#91;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;]&amp;quot;,	&amp;quot;&amp;amp;#93;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;^&amp;quot;,	&amp;quot;&amp;amp;#94;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;_&amp;quot;,	&amp;quot;&amp;amp;#95;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;`&amp;quot;,	&amp;quot;&amp;amp;#96;&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;{&amp;quot;,	&amp;quot;&amp;amp;#123&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;|&amp;quot;,	&amp;quot;&amp;amp;#124&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;}&amp;quot;,	&amp;quot;&amp;amp;#125&amp;quot;)&lt;br /&gt;
  outStr = SwitchLetter(outStr, &amp;quot;~&amp;quot;,	&amp;quot;&amp;amp;#126&amp;quot;)&lt;br /&gt;
    return outStr&lt;br /&gt;
end -- function end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===SwitchLetter()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function SwitchLetter(MyStr, MyChar, NewStr)            -- swwap a leter for another letter&lt;br /&gt;
  local outStr, str1 = &amp;quot;&amp;quot;&lt;br /&gt;
  local inStrLen = string.len(MyStr)&lt;br /&gt;
  for i = 1, inStrLen ,1 do&lt;br /&gt;
    str1 = string.sub(MyStr, i, i)&lt;br /&gt;
    if string.byte(str1) == string.byte(MyChar) then&lt;br /&gt;
     outStr=outStr .. NewStr&lt;br /&gt;
     else&lt;br /&gt;
         outStr=outStr .. str1&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
  return outStr&lt;br /&gt;
end -- function end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===PadC===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function PadC(str, lenth)                        -- Adds spaces to front and back to center text in lenth&lt;br /&gt;
-- Local Word = PadC(&amp;quot;K&amp;quot;, 12) -- returns &amp;quot;     K      &amp;quot;&lt;br /&gt;
  if type(str) ~= &amp;quot;string&amp;quot; then&lt;br /&gt;
    str = tostring(str)&lt;br /&gt;
  end&lt;br /&gt;
  if string.len(str) &amp;lt; lenth then&lt;br /&gt;
  local a = math.floor(lenth - string.len(str) * 0.5) - 2&lt;br /&gt;
  local b = math.ceil(lenth - string.len(str) * 0.5) - 2&lt;br /&gt;
  --print (&amp;quot;a = &amp;quot; .. a)&lt;br /&gt;
  for _ = 1, a, 1 do&lt;br /&gt;
    str =  &amp;quot; &amp;quot; .. str&lt;br /&gt;
  end&lt;br /&gt;
  for _ = 1, b, 1 do&lt;br /&gt;
    str =  str .. &amp;quot; &amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  --print (&amp;quot;str len = &amp;quot; .. #str)&lt;br /&gt;
  end&lt;br /&gt;
  return str&lt;br /&gt;
end -- function end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===PadR()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function PadR(str, len)                        -- Adds spaces to Back of string&lt;br /&gt;
-- Local Word = Pad(&amp;quot;KPSDFKSPSK&amp;quot;, 12) -- returns &amp;quot;KPSDFKSPSK  &amp;quot;&lt;br /&gt;
  if type(str) ~= &amp;quot;string&amp;quot; then&lt;br /&gt;
    str = tostring(str)&lt;br /&gt;
  end&lt;br /&gt;
  while string.len(str) &amp;lt; len do&lt;br /&gt;
    str = str .. &amp;quot; &amp;quot;&lt;br /&gt;
  end&lt;br /&gt;
  return str&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===PadL()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function PadL(str, len)              -- Adds spaces to Front of string&lt;br /&gt;
-- Local Word = Pad(&amp;quot;KPSDFKSPSK&amp;quot;, 12) -- returns &amp;quot;  KPSDFKSPSK&amp;quot;&lt;br /&gt;
  if type(str) ~= &amp;quot;string&amp;quot; then&lt;br /&gt;
    str = tostring(str)&lt;br /&gt;
  end&lt;br /&gt;
  while string.len(str) &amp;lt; len do&lt;br /&gt;
    str = &amp;quot; &amp;quot; .. str&lt;br /&gt;
  end&lt;br /&gt;
  return str&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===NumberPad()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function NumberPad(str, front, back) -- Adds spaces to front and zeros to the back of string&lt;br /&gt;
  local mychar&lt;br /&gt;
  local  a,b,c,d = 0,0,0,0&lt;br /&gt;
  local x,y,z = &amp;quot;&amp;quot;,&amp;quot;&amp;quot;,&amp;quot;&amp;quot;&lt;br /&gt;
  if type(str) ~= &amp;quot;string&amp;quot; then&lt;br /&gt;
    str = tostring(str)&lt;br /&gt;
  end&lt;br /&gt;
  c = string.len(str)&lt;br /&gt;
  for i = 1, c, 1 do&lt;br /&gt;
    mychar = string.byte(string.sub(str, i,i))&lt;br /&gt;
    if mychar == 46 then&lt;br /&gt;
      b = i&lt;br /&gt;
    end&lt;br /&gt;
  end&lt;br /&gt;
--  print(&amp;quot;b = &amp;quot; .. b)&lt;br /&gt;
  if b == 0 then&lt;br /&gt;
    str = str .. &amp;quot;.&amp;quot;&lt;br /&gt;
    c = c + 1&lt;br /&gt;
    b = c&lt;br /&gt;
  end -- if loc&lt;br /&gt;
  x = string.sub(str, 1, b-1)&lt;br /&gt;
  y = string.sub(str, b+1)&lt;br /&gt;
  a = c - b&lt;br /&gt;
  a = #x&lt;br /&gt;
  d = #y&lt;br /&gt;
  if a &amp;lt; front then&lt;br /&gt;
    front = front - (a - 1)&lt;br /&gt;
    for _ = 1, front -1 do&lt;br /&gt;
      x = &amp;quot; &amp;quot; .. x&lt;br /&gt;
    end -- end for front&lt;br /&gt;
  end&lt;br /&gt;
  back = back - (c - b)&lt;br /&gt;
  for i = 1, back  do&lt;br /&gt;
    y = y .. &amp;quot;0&amp;quot;&lt;br /&gt;
  end -- end for back&lt;br /&gt;
  str =   x .. &amp;quot;.&amp;quot; .. y&lt;br /&gt;
  return str&lt;br /&gt;
end -- function end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===All_Trim()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function All_Trim(s)                           -- Trims spaces off both ends of a string&lt;br /&gt;
  return s:match( &amp;quot;^%s*(.-)%s*$&amp;quot; )&lt;br /&gt;
end -- function end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===MakeProperCase()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function MakeProperCase(str)&lt;br /&gt;
  local str=string.gsub(string.lower(str),&amp;quot;^(%w)&amp;quot;, string.upper)&lt;br /&gt;
  return string.gsub(str,&amp;quot;([^%w]%w)&amp;quot;, string.upper)&lt;br /&gt;
end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===ifT()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function ifT(x)                                -- Converts Boolean True or False to String &amp;quot;Yes&amp;quot; or &amp;quot;No&amp;quot;&lt;br /&gt;
-- ===ifT(x)===&lt;br /&gt;
  if x then&lt;br /&gt;
    return &amp;quot;Yes&amp;quot;&lt;br /&gt;
  else&lt;br /&gt;
    return &amp;quot;No&amp;quot;&lt;br /&gt;
  end-- if end&lt;br /&gt;
end -- function end&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===ifY()===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function ifY(x)                                -- Converts String &amp;quot;Yes&amp;quot; or &amp;quot;No&amp;quot; to Boolean True or False&lt;br /&gt;
-- ===ifY(x)===&lt;br /&gt;
  if string.upper(x) == &amp;quot;YES&amp;quot; then&lt;br /&gt;
    return true&lt;br /&gt;
  else&lt;br /&gt;
    return false&lt;br /&gt;
  end-- if end&lt;br /&gt;
end -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Seed Documents== &lt;br /&gt;
[https://jimandi.com/SDK/index.php/JimAndi_Toolbox (top)]&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;-- =====================================================]]&lt;br /&gt;
╔═╗╔═╗╔═╗╔╦╗  ╔═╗╦ ╦╔╗╔╔═╗╔╦╗╦╔═╗╔╗╔&lt;br /&gt;
╚═╗║╣ ║╣  ║║  ╠╣ ║ ║║║║║   ║ ║║ ║║║║&lt;br /&gt;
╚═╝╚═╝╚═╝═╩╝  ╚  ╚═╝╝╚╝╚═╝ ╩ ╩╚═╝╝╚╝&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
  -- VECTRIC LUA SCRIPT&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
-- Gadgets are an entirely optional add-in to Vectric's core software products.&lt;br /&gt;
-- They are provided 'as-is', without any express or implied warranty, and you make use of them entirely at your own risk.&lt;br /&gt;
-- In no event will the author(s) or Vectric Ltd. be held liable for any damages arising from their use.&lt;br /&gt;
-- Permission is granted to anyone to use this software for any purpose,&lt;br /&gt;
-- including commercial applications, and to alter it and redistribute it freely,&lt;br /&gt;
-- subject to the following restrictions:&lt;br /&gt;
-- 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.&lt;br /&gt;
-- 2. If you use this software in a product, an acknowledgement in the product documentation would be appreciated but is not required.&lt;br /&gt;
-- 3. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.&lt;br /&gt;
-- 4. This notice may not be removed or altered from any source distribution.&lt;br /&gt;
-- Easy Seed Gadget Master is written by Jim Anderson of Houston Texas 2020&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
-- require(&amp;quot;mobdebug&amp;quot;).start()&lt;br /&gt;
-- require &amp;quot;strict&amp;quot;&lt;br /&gt;
local Tools&lt;br /&gt;
-- Global Variables --&lt;br /&gt;
local Ver = &amp;quot;1.0&amp;quot;  -- Version 7: Aug 2021 - Clean Up and added Ver to Dialog&lt;br /&gt;
&lt;br /&gt;
-- Table Names&lt;br /&gt;
Milling = {}&lt;br /&gt;
Project = {}&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
function main(script_path)&lt;br /&gt;
--[[&lt;br /&gt;
	Gadget Notes: Dec 2019 - My New Gadget&lt;br /&gt;
&lt;br /&gt;
  ]]&lt;br /&gt;
-- Localized Variables --&lt;br /&gt;
&lt;br /&gt;
-- Job Validation --&lt;br /&gt;
  local job = VectricJob()&lt;br /&gt;
  if not job.Exists then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Error: No job loaded&amp;quot;)&lt;br /&gt;
    return false&lt;br /&gt;
  end&lt;br /&gt;
&lt;br /&gt;
  Tools = assert(loadfile(script_path .. &amp;quot;\\EasyGearToolsVer&amp;quot; .. Ver .. &amp;quot;.xlua&amp;quot;)) (Tools) -- Load Tool Function&lt;br /&gt;
-- Get Data --&lt;br /&gt;
&lt;br /&gt;
-- Calculation --&lt;br /&gt;
&lt;br /&gt;
-- Do Something --&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
  return true&lt;br /&gt;
end  -- function end&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Setup Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;-- =====================================================]]&lt;br /&gt;
╔═╗╔═╗╔╦╗╦ ╦╔═╗&lt;br /&gt;
╚═╗║╣  ║ ║ ║╠═╝&lt;br /&gt;
╚═╝╚═╝ ╩ ╚═╝╩&lt;br /&gt;
function SetupAndLetter Seeds()&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
  function LUA_Seed()&lt;br /&gt;
    -- VECTRIC LUA SCRIPT&lt;br /&gt;
    -- ==============================================================================&lt;br /&gt;
    --  Gadgets are an entirely optional add-in to Vectric's core software products.&lt;br /&gt;
    --  They are provided 'as-is', without any express or implied warranty, and you&lt;br /&gt;
    --  make use of them entirely at your own risk.&lt;br /&gt;
    --  In no event will the author(s) or Vectric Ltd. be held liable for any damages&lt;br /&gt;
    --  arising from their use.&lt;br /&gt;
    --  Permission is granted to anyone to use this software for any purpose,&lt;br /&gt;
    --  including commercial applications, and to alter it and redistribute it freely,&lt;br /&gt;
    --  subject to the following restrictions:&lt;br /&gt;
    --  1. The origin of this software must not be misrepresented;&lt;br /&gt;
    --     you must not claim that you wrote the original software.&lt;br /&gt;
    --     If you use this software in a product, an acknowledgement in the product&lt;br /&gt;
    --     documentation would be appreciated but is not required.&lt;br /&gt;
    --  2. Altered source versions must be plainly marked as such, and&lt;br /&gt;
    --     must not be misrepresented as being the original software.&lt;br /&gt;
    --  3. This notice may not be removed or altered from any source distribution.&lt;br /&gt;
    -- ==============================================================================&lt;br /&gt;
    -- &amp;quot;AppName Here&amp;quot; was written by JimAndi Gadgets of Houston Texas&lt;br /&gt;
    -- ==============================================================================&lt;br /&gt;
    -- =====================================================]]&lt;br /&gt;
    -- require(&amp;quot;mobdebug&amp;quot;).start()&lt;br /&gt;
    -- require &amp;quot;strict&amp;quot;&lt;br /&gt;
    -- =====================================================]]&lt;br /&gt;
    -- Global variables&lt;br /&gt;
    -- =====================================================]]&lt;br /&gt;
  end -- lua function&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
  function Install_letter()&lt;br /&gt;
  -- Steps to Install:&lt;br /&gt;
&lt;br /&gt;
  -- 1. Download the gadget x.zip that is attached to this post.&lt;br /&gt;
  -- 2. Rename it from x.zip to x.vgadget&lt;br /&gt;
  -- 3. In Vectric Pro or Aspire click on Gadgets -&amp;gt; Install Gadget and navigate to where you downloaded the file to, select it and click Ok.&lt;br /&gt;
&lt;br /&gt;
  -- It should give you a pop up saying the gadget was installed and you should see x in the Gadgets menu.&lt;br /&gt;
&lt;br /&gt;
  -- Image Here&lt;br /&gt;
&lt;br /&gt;
  -- Steps for Use:&lt;br /&gt;
  -- 1. Select a layer that you want to calculate for&lt;br /&gt;
  -- 2. Enter the cut depth&lt;br /&gt;
  -- 3. Enter the percentage of coverage for the area that will be filled in&lt;br /&gt;
  -- 4. Enter the hardner to resin percentage&lt;br /&gt;
  -- 5. Click the Calculate Button and the results will be displayed below in the Results Pane.&lt;br /&gt;
  end -- install function&lt;br /&gt;
&lt;br /&gt;
end -- Header function&lt;br /&gt;
-- =====================================================]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Toolpathing Tools==&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
This object is a name-value pair that represents a Document Variable within a [[VectricJob]].&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CreateLayerProfileToolpath===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function CreateLayerProfileToolpath(name, layer_name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
    -- clear current selection&lt;br /&gt;
    local selection = job.Selection&lt;br /&gt;
    selection:Clear()&lt;br /&gt;
    -- get layer&lt;br /&gt;
    local layer = job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;No layer found with name = &amp;quot; .. layer_name)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;No closed vectors found on layer &amp;quot; .. layer_name)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua End Mill&amp;quot;, Tool.END_MILL) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * 0.25&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC ...&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local profile_data = ProfileParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    profile_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    profile_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut - ProfileParameterData.&lt;br /&gt;
    -- CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION&lt;br /&gt;
    profile_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- side we machine on - ProfileParameterData.&lt;br /&gt;
    -- PROFILE_OUTSIDE, ProfileParameterData.PROFILE_INSIDE or&lt;br /&gt;
    -- ProfileParameterData.PROFILE_ON&lt;br /&gt;
    profile_data.ProfileSide = ProfileParameterData.PROFILE_OUTSIDE&lt;br /&gt;
    -- Allowance to leave on when machining&lt;br /&gt;
    profile_data.Allowance = 0.0&lt;br /&gt;
    -- true to preserve start point positions, false to reorder start&lt;br /&gt;
    -- points to minimise toolpath length&lt;br /&gt;
    profile_data.KeepStartPoints = false&lt;br /&gt;
    -- true if want to create 'square' external corners on toolpath&lt;br /&gt;
    profile_data.CreateSquareCorners = false&lt;br /&gt;
    -- true to perform corner sharpening on internal corners (only with v-bits)&lt;br /&gt;
    profile_data.CornerSharpen = false&lt;br /&gt;
    -- true to use tabs (position of tabs must already have been defined on vectors)&lt;br /&gt;
    profile_data.UseTabs = false&lt;br /&gt;
    -- length for tabs if being used&lt;br /&gt;
    profile_data.TabLength = 5.0&lt;br /&gt;
    -- Thickness for tabs if being used&lt;br /&gt;
    profile_data.TabThickness = 1.0&lt;br /&gt;
    -- if true then create 3d tabs else 2d tabs&lt;br /&gt;
    profile_data.Use3dTabs = true&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    profile_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object used to control ramping&lt;br /&gt;
    local ramping_data = RampingData()&lt;br /&gt;
    -- if true we do ramping into toolpath&lt;br /&gt;
    ramping_data.DoRamping = false&lt;br /&gt;
    -- type of ramping to perform RampingData.RAMP_LINEAR , RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
    -- or RampingData.RAMP_SPIRAL&lt;br /&gt;
    ramping_data.RampType = RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
    -- how ramp is contrained - either by angle or distance RampingData.CONSTRAIN_DISTANCE&lt;br /&gt;
    -- or RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
    ramping_data.RampConstraint = RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
    -- if we are constraining ramp by distance, distance to ramp over&lt;br /&gt;
    ramping_data.RampDistance = 100.0&lt;br /&gt;
    -- if we are contraining ramp by angle , angle to ramp in at (in degrees)&lt;br /&gt;
    ramping_data.RampAngle = 25.0&lt;br /&gt;
    -- if we are contraining ramp by angle, max distance to travel before 'zig zaging'&lt;br /&gt;
    -- if zig zaging&lt;br /&gt;
    ramping_data.RampMaxAngleDist = 15&lt;br /&gt;
    -- if true we restrict our ramping to lead in section of toolpath&lt;br /&gt;
    ramping_data.RampOnLeadIn = false&lt;br /&gt;
    -- Create object used to control lead in/out&lt;br /&gt;
    local lead_in_out_data = LeadInOutData()&lt;br /&gt;
    -- if true we create lead ins on profiles (not for profile on)&lt;br /&gt;
    lead_in_out_data.DoLeadIn = false&lt;br /&gt;
    -- if true we create lead outs on profiles (not for profile on)&lt;br /&gt;
    lead_in_out_data.DoLeadOut = false&lt;br /&gt;
    -- type of leads to create LeadInOutData.LINEAR_LEAD or LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
    lead_in_out_data.LeadType = LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
    -- length of lead to create&lt;br /&gt;
    lead_in_out_data.LeadLength = 10.0&lt;br /&gt;
    -- Angle for linear leads&lt;br /&gt;
    lead_in_out_data.LinearLeadAngle = 45&lt;br /&gt;
    -- Radius for circular arc leads&lt;br /&gt;
    lead_in_out_data.CirularLeadRadius = 5.0&lt;br /&gt;
    -- distance to 'overcut' (travel past start point) when profiling&lt;br /&gt;
    lead_in_out_data.OvercutDistance = 0.0&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateProfilingToolpath(name, tool, profile_data, ramping_data, lead_in_out_data, pos_data, geometry_selector, create_2d_previews, display_warnings )&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CreateProfileToolpath===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function CreateProfileToolpath(name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua End Mill&amp;quot;, Tool.END_MILL) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * 0.25&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC ...&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local profile_data = ProfileParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    profile_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    profile_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut - ProfileParameterData.&lt;br /&gt;
    -- CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION&lt;br /&gt;
    profile_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- side we machine on - ProfileParameterData.&lt;br /&gt;
    -- PROFILE_OUTSIDE, ProfileParameterData.PROFILE_INSIDE or&lt;br /&gt;
    -- ProfileParameterData.PROFILE_ON&lt;br /&gt;
    profile_data.ProfileSide = ProfileParameterData.PROFILE_OUTSIDE&lt;br /&gt;
    -- Allowance to leave on when machining&lt;br /&gt;
    profile_data.Allowance = 0.0&lt;br /&gt;
    -- true to preserve start point positions, false to reorder start&lt;br /&gt;
    -- points to minimise toolpath length&lt;br /&gt;
    profile_data.KeepStartPoints = false&lt;br /&gt;
    -- true if want to create 'square' external corners on toolpath&lt;br /&gt;
    profile_data.CreateSquareCorners = false&lt;br /&gt;
    -- true to perform corner sharpening on internal corners (only with v-bits)&lt;br /&gt;
    profile_data.CornerSharpen = false&lt;br /&gt;
    -- true to use tabs (position of tabs must already have been defined on vectors)&lt;br /&gt;
    profile_data.UseTabs = false&lt;br /&gt;
    -- length for tabs if being used&lt;br /&gt;
    profile_data.TabLength = 5.0&lt;br /&gt;
    -- Thickness for tabs if being used&lt;br /&gt;
    profile_data.TabThickness = 1.0&lt;br /&gt;
    -- if true then create 3d tabs else 2d tabs&lt;br /&gt;
    profile_data.Use3dTabs = true&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    profile_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object used to control ramping&lt;br /&gt;
    local ramping_data = RampingData()&lt;br /&gt;
    -- if true we do ramping into toolpath&lt;br /&gt;
    ramping_data.DoRamping = false&lt;br /&gt;
    -- type of ramping to perform RampingData.RAMP_LINEAR , RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
    -- or RampingData.RAMP_SPIRAL&lt;br /&gt;
    ramping_data.RampType = RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
    -- how ramp is contrained - either by angle or distance RampingData.CONSTRAIN_DISTANCE&lt;br /&gt;
    -- or RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
    ramping_data.RampConstraint = RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
    -- if we are constraining ramp by distance, distance to ramp over&lt;br /&gt;
    ramping_data.RampDistance = 100.0&lt;br /&gt;
    -- if we are contraining ramp by angle , angle to ramp in at (in degrees)&lt;br /&gt;
    ramping_data.RampAngle = 25.0&lt;br /&gt;
    -- if we are contraining ramp by angle, max distance to travel before 'zig zaging'&lt;br /&gt;
    -- if zig zaging&lt;br /&gt;
    ramping_data.RampMaxAngleDist = 15&lt;br /&gt;
    -- if true we restrict our ramping to lead in section of toolpath&lt;br /&gt;
    ramping_data.RampOnLeadIn = false&lt;br /&gt;
    -- Create object used to control lead in/out&lt;br /&gt;
    local lead_in_out_data = LeadInOutData()&lt;br /&gt;
    -- if true we create lead ins on profiles (not for profile on)&lt;br /&gt;
    lead_in_out_data.DoLeadIn = false&lt;br /&gt;
    -- if true we create lead outs on profiles (not for profile on)&lt;br /&gt;
    lead_in_out_data.DoLeadOut = false&lt;br /&gt;
    -- type of leads to create LeadInOutData.LINEAR_LEAD or LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
    lead_in_out_data.LeadType = LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
    -- length of lead to create&lt;br /&gt;
    lead_in_out_data.LeadLength = 10.0&lt;br /&gt;
    -- Angle for linear leads&lt;br /&gt;
    lead_in_out_data.LinearLeadAngle = 45&lt;br /&gt;
    -- Radius for circular arc leads&lt;br /&gt;
    lead_in_out_data.CirularLeadRadius = 5.0&lt;br /&gt;
    -- distance to 'overcut' (travel past start point) when profiling&lt;br /&gt;
    lead_in_out_data.OvercutDistance = 0.0&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateProfilingToolpath(name, tool, profile_data, ramping_data, lead_in_out_data, pos_data, geometry_selector, create_2d_previews, display_warnings )&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CreatePocketingToolpath===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function CreatePocketingToolpath(name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
  -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua End Mill&amp;quot;,Tool.END_MILL) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * (tool_stepover_percent / 100)&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC,...&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * (tool_stepover_percent / 100) -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass pocketing options&lt;br /&gt;
    local pocket_data = PocketParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    pocket_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    pocket_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION or&lt;br /&gt;
    -- ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
    pocket_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- Allowance to leave on when machining&lt;br /&gt;
    pocket_data.Allowance = 0.0&lt;br /&gt;
    -- if true use raster clearance strategy , else use offset area clearance&lt;br /&gt;
    pocket_data.DoRasterClearance = true&lt;br /&gt;
    -- angle for raster if using raster clearance&lt;br /&gt;
    pocket_data.RasterAngle = 0&lt;br /&gt;
    -- type of profile pass to perform PocketParameterData.PROFILE_NONE ,&lt;br /&gt;
    -- PocketParameterData.PROFILE_FIRST orPocketParameterData.PROFILE_LAST&lt;br /&gt;
    pocket_data.ProfilePassType = PocketParameterData.PROFILE_LAST&lt;br /&gt;
    -- if true we ramp into pockets (always zig-zag)&lt;br /&gt;
    pocket_data.DoRamping = false&lt;br /&gt;
    -- if ramping, distance to ramp over&lt;br /&gt;
    pocket_data.RampDistance = 10.0&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    pocket_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- if we are doing two tool pocketing define tool to use for area clearance&lt;br /&gt;
    local area_clear_tool = nill&lt;br /&gt;
    -- we just create a tool twice as large for testing here&lt;br /&gt;
    area_clear_tool = Tool(&amp;quot;Lua Clearance End Mill&amp;quot;, Tool.END_MILL) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    area_clear_tool.InMM = tool_in_mm&lt;br /&gt;
    area_clear_tool.ToolDia = tool_dia * 2&lt;br /&gt;
    area_clear_tool.Stepdown = tool_stepdown * 2&lt;br /&gt;
    area_clear_tool.Stepover = tool_dia * 2 *(tool_stepover_percent / 100)&lt;br /&gt;
    area_clear_tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC..&lt;br /&gt;
    area_clear_tool.FeedRate = 30&lt;br /&gt;
    area_clear_tool.PlungeRate = 10&lt;br /&gt;
    area_clear_tool.SpindleSpeed = 20000&lt;br /&gt;
    area_clear_tool.ToolNumber = 1&lt;br /&gt;
    area_clear_tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    area_clear_tool.ClearStepover = tool_dia*2*(tool_stepover_percent/100) -- used for vbit&lt;br /&gt;
  -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePocketingToolpath(name,tool,area_clear_tool,pocket_data,pos_data,geometry_selector,create_2d_previews,display_warnings)&lt;br /&gt;
    if toolpath_id == nill then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CreateDrillingToolpath===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function CreateDrillingToolpath(name, start_depth, cut_depth, retract_gap, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
  -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua Drill&amp;quot;, Tool.THROUGH_DRILL) -- BALL_NOSE, END_MILL, VBIT, THROUGH_DRILL&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * 0.25&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local drill_data = DrillParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    drill_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    drill_data.CutDepth = cut_depth&lt;br /&gt;
    -- if true perform peck drilling&lt;br /&gt;
    drill_data.DoPeckDrill = retract_gap &amp;gt; 0.0&lt;br /&gt;
    -- distance to retract above surface when peck drilling&lt;br /&gt;
    drill_data.PeckRetractGap = retract_gap&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    drill_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view,&lt;br /&gt;
    -- if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateDrillingToolpath(name,tool,drill_data,pos_data,geometry_selector,create_2d_previews,display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CreateVCarvingToolpath===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function CreateVCarvingToolpath(name, start_depth, flat_depth, vbit_angle, vbit_dia, vbit_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
    --[[ -------------- CreateVCarvingToolpath --------------&lt;br /&gt;
    |&lt;br /&gt;
    | Create a VCarving toolpath within the program for the currently selected vectors&lt;br /&gt;
    | Parameters:&lt;br /&gt;
    | name, -- Name for toolpath&lt;br /&gt;
    | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
    | flat_depth -- flat depth - if 0.0 assume not doing flat bottom&lt;br /&gt;
    | vbit_angle -- angle of vbit to use&lt;br /&gt;
    | vbit_dia -- diameter of VBit to use&lt;br /&gt;
    | vbit_stepdown -- stepdown for tool&lt;br /&gt;
    | tool_stepover_percent - percentage stepover for tool&lt;br /&gt;
    | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
    |&lt;br /&gt;
    | Return Values:&lt;br /&gt;
    | true if toolpath created OK else false&lt;br /&gt;
    |&lt;br /&gt;
  ]]&lt;br /&gt;
  -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua VBit&amp;quot;,Tool.VBIT )-- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = vbit_dia&lt;br /&gt;
    tool.Stepdown = vbit_stepdown&lt;br /&gt;
    tool.Stepover = vbit_dia * (tool_stepover_percent / 100)&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = vbit_dia * (tool_stepover_percent / 100) * 2 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()    &lt;br /&gt;
    vcarve_data:SetHomePosition(Milling.HomeX, Milling.HomeY, Milling.HomeZGap ) -- vcarve_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    vcarve_data.SafeZGap = Milling.SafeZGap -- vcarve_data.SafeZGap = 0.5&lt;br /&gt;
    local vcarve_data = VCarveParameterData() -- Create object used to pass pocketing options - used for area clearance only&lt;br /&gt;
    vcarve_data.StartDepth = start_depth    -- start depth for toolpath&lt;br /&gt;
    vcarve_data.DoFlatBottom = flat_depth &amp;gt; 0.0    -- flag indicating if we are creating a flat bottomed toolpath&lt;br /&gt;
    vcarve_data.FlatDepth = flat_depth    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    vcarve_data.ProjectToolpath = false    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    vcarve_data.UseAreaClearTool = true    -- set flag indicating we are using flat tool&lt;br /&gt;
    local pocket_data = PocketParameterData()    -- Create object used to pass pocketing options - used for area clearance only&lt;br /&gt;
    pocket_data.StartDepth = start_depth    -- start depth for toolpath&lt;br /&gt;
    pocket_data.CutDepth = flat_depth    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    pocket_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION    -- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
&lt;br /&gt;
    -- if true use raster clearance strategy , else use offset area clearance&lt;br /&gt;
    pocket_data.DoRasterClearance = false&lt;br /&gt;
    -- set flag indicating we are using flat tool&lt;br /&gt;
    pocket_data.UseAreaClearTool = true&lt;br /&gt;
    -- angle for raster if using raster clearance&lt;br /&gt;
    pocket_data.RasterAngle = 0&lt;br /&gt;
    -- type of profile pass to perform PocketParameterData.PROFILE_NONE ,&lt;br /&gt;
    -- PocketParameterData.PROFILE_FIRST orPocketParameterData.PROFILE_LAST&lt;br /&gt;
    pocket_data.ProfilePassType = PocketParameterData.PROFILE_LAST&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- if we are doing two tool pocketing define tool to use for area clearance&lt;br /&gt;
    local area_clear_tool = nil&lt;br /&gt;
    -- we just create a 10mm end mill&lt;br /&gt;
    area_clear_tool = Tool(&amp;quot;Lua Clearance End Mill&amp;quot;,Tool.END_MILL) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    area_clear_tool.InMM = true&lt;br /&gt;
    area_clear_tool.ToolDia = 10&lt;br /&gt;
    area_clear_tool.Stepdown = 3&lt;br /&gt;
    area_clear_tool.Stepover = 3&lt;br /&gt;
    area_clear_tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    area_clear_tool.FeedRate = 30&lt;br /&gt;
    area_clear_tool.PlungeRate = 10&lt;br /&gt;
    area_clear_tool.SpindleSpeed = 20000&lt;br /&gt;
    area_clear_tool.ToolNumber = 2&lt;br /&gt;
    local geometry_selector = GeometrySelector()    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateVCarvingToolpath(name,tool, area_clear_tool,vcarve_data, pocket_data,pos_data,geometry_selector, create_2d_previews,display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CreatePrismToolpath===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function CreatePrismToolpath(name, start_depth, cut_depth, vbit_angle, vbit_dia, vbit_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
  --[[ ------------------- CreatePrismToolpath -------------------&lt;br /&gt;
  |&lt;br /&gt;
  | Create a prism toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
  | VBit_Angle -- angle of vbit to use&lt;br /&gt;
  | vbit_Dia -- diameter of VBit to use&lt;br /&gt;
  | vbit_Stepdown -- stepdown for tool&lt;br /&gt;
  | tool_Stepover_Percent - percentage stepover for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua VBit&amp;quot;, Tool.VBIT ) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = vbit_dia&lt;br /&gt;
    tool.Stepdown = vbit_stepdown&lt;br /&gt;
    tool.Stepover = vbit_dia * (tool_stepover_percent / 100)&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = vbit_dia * (tool_stepover_percent / 100) * 2 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local prism_data = PrismCarveParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    prism_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    prism_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- or ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
    prism_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- calculate the minimum cut depth to fully form the bevel on the current&lt;br /&gt;
    -- selection with the current tool&lt;br /&gt;
    local min_bevel_depth = prism_data:CalculateMinimumBevelDepth(tool, true)&lt;br /&gt;
    if min_bevel_depth &amp;gt; cut_depth then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;A prism will not be fully formed with a depth of &amp;quot; .. cut_depth .. &amp;quot;\r\n&amp;quot; ..&lt;br /&gt;
                        &amp;quot;A depth of &amp;quot; .. min_bevel_depth .. &amp;quot; is required to fully form the prism&amp;quot;)&lt;br /&gt;
    end -- if end&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePrismCarvingToolpath(name, tool, prism_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===CreateFlutingToolpath===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function CreateFlutingToolpath(name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
    --[[ ----------------- CreateFlutingToolpath -----------------&lt;br /&gt;
  | Create a flutting toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for toolpath&lt;br /&gt;
  | tool_dia -- diameter of tool to use&lt;br /&gt;
  | tool_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua Ball Nose&amp;quot;, Tool.BALL_NOSE) -- BALL_NOSE, END_MILL, VBIT, THROUGH_DRILL&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * 0.25&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass fluting options&lt;br /&gt;
    local fluting_data = FlutingParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    fluting_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    fluting_data.CutDepth = cut_depth&lt;br /&gt;
    -- type of fluting FULL_LENGTH, RAMP_START or RAMP_START_END&lt;br /&gt;
    fluting_data.FluteType = FlutingParameterData.RAMP_START_END&lt;br /&gt;
    -- type of ramping RAMP_LINEAR, RAMP_SMOOTH&lt;br /&gt;
    fluting_data.RampType = FlutingParameterData.RAMP_LINEAR&lt;br /&gt;
    -- if true use ratio field for controling ramp length else absolute length value&lt;br /&gt;
    fluting_data.UseRampRatio = false&lt;br /&gt;
    -- length of ramp as ratio of flute length(range 0 - 1.0)&lt;br /&gt;
    -- (for start and end - ratio is of half length)&lt;br /&gt;
    fluting_data.RampRatio = 0.2&lt;br /&gt;
    -- length to ramp over - if UseRampRatio == false&lt;br /&gt;
    fluting_data.RampLength = 15&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    fluting_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateFlutingToolpath(name, tool, fluting_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    else&lt;br /&gt;
      return true&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    end -- end function&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
===SelectVectorsOnLayer===&lt;br /&gt;
[[File:TopOfPage.png|right|50px|link=JimAndi Toolbox]]&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;function SelectVectorsOnLayer(layer, selection, select_closed, select_open, select_groups)&lt;br /&gt;
    -- Please Note: SelectVectorsOnLayer is provided by Vectric and can be found in the SDK and Sample Gadget files.&lt;br /&gt;
    --[[  ---------------- SelectVectorsOnLayer ----------------&lt;br /&gt;
    -- |   SelectVectorsOnLayer(&amp;quot;Stringer Profile&amp;quot;, selection, true, falus, falus)&lt;br /&gt;
    -- |   Add all the vectors on the layer to the selection&lt;br /&gt;
    -- |     layer,            -- layer we are selecting vectors on&lt;br /&gt;
    -- |     selection         -- selection object&lt;br /&gt;
    -- |     select_closed     -- if true  select closed objects&lt;br /&gt;
    -- |     select_open       -- if true  select open objects&lt;br /&gt;
    -- |     select_groups     -- if true select grouped vectors (irrespective of open / closed state of member objects)&lt;br /&gt;
    -- |  Return Values:&lt;br /&gt;
    -- |     true if selected one or more vectors|&lt;br /&gt;
    --]]&lt;br /&gt;
    local objects_selected = false&lt;br /&gt;
    local warning_displayed = false&lt;br /&gt;
    local pos = layer:GetHeadPosition()&lt;br /&gt;
    while pos ~= nil do&lt;br /&gt;
      local object&lt;br /&gt;
      object, pos = layer:GetNext(pos)&lt;br /&gt;
      local contour = object:GetContour()&lt;br /&gt;
      if contour == nil then&lt;br /&gt;
        if (object.ClassName == &amp;quot;vcCadObjectGroup&amp;quot;) and select_groups then&lt;br /&gt;
          selection:Add(object, true, true)&lt;br /&gt;
          objects_selected = true&lt;br /&gt;
        else&lt;br /&gt;
          if not warning_displayed then&lt;br /&gt;
            local message = &amp;quot;Object(s) without contour information found on layer - ignoring&amp;quot;&lt;br /&gt;
            if not select_groups then&lt;br /&gt;
              message = message ..  &amp;quot;\r\n\r\n&amp;quot; ..&lt;br /&gt;
              &amp;quot;If layer contains grouped vectors these must be ungrouped for this script&amp;quot;&lt;br /&gt;
            end -- if end&lt;br /&gt;
            DisplayMessageBox(message)&lt;br /&gt;
            warning_displayed = true&lt;br /&gt;
          end -- if end&lt;br /&gt;
        end -- if end&lt;br /&gt;
      else  -- contour was NOT nil, test if Open or Closed&lt;br /&gt;
        if contour.IsOpen and select_open then&lt;br /&gt;
          selection:Add(object, true, true)&lt;br /&gt;
          objects_selected = true&lt;br /&gt;
        elseif select_closed then&lt;br /&gt;
          selection:Add(object, true, true)&lt;br /&gt;
          objects_selected = true&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- if end&lt;br /&gt;
    end -- while end&lt;br /&gt;
    -- to avoid excessive redrawing etc we added vectors to the selection in 'batch' mode&lt;br /&gt;
    -- tell selection we have now finished updating&lt;br /&gt;
    if objects_selected then&lt;br /&gt;
      selection:GroupSelectionFinished()&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return objects_selected&lt;br /&gt;
  end -- function end&lt;br /&gt;
&amp;lt;/nowiki&amp;gt; &lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 10.0, published August 21, 2019. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=ExternalToolpathOptions&amp;diff=1095</id>
		<title>ExternalToolpathOptions</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=ExternalToolpathOptions&amp;diff=1095"/>
		<updated>2024-11-16T17:17:32Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: /* Example Code: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
This object is used to hold the settings for an external toolpath.&lt;br /&gt;
&lt;br /&gt;
==Constructor==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===ExternalToolpathOptions()===&lt;br /&gt;
Create a new object ready to have its parameters set&lt;br /&gt;
&lt;br /&gt;
==Properties==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.CreatePreview===&lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (bool) if true, create preview in 2d view for this toolpath&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.StartDepth===&lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (double) Start depth for toolpath below material surface&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Example Code:====&lt;br /&gt;
 function CreateToolpath(name, vectors, start_depth)&lt;br /&gt;
  -- Create tool we will use to machine vectors&lt;br /&gt;
 local tool = Tool(&amp;quot;Lua End Mill&amp;quot;,&lt;br /&gt;
 Tool.END_MILL -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
 )&lt;br /&gt;
 tool.InMM = true&lt;br /&gt;
 tool.ToolDia = 3.0&lt;br /&gt;
 tool.Stepdown = 2.0&lt;br /&gt;
 tool.Stepover = 1.0&lt;br /&gt;
 tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
 tool.FeedRate = 30&lt;br /&gt;
 tool.PlungeRate = 10&lt;br /&gt;
 tool.SpindleSpeed = 20000&lt;br /&gt;
 tool.ToolNumber = 1&lt;br /&gt;
 tool.VBit_Angle = 90.0    -- used for vbit only&lt;br /&gt;
 tool.ClearStepover = 1.0 -- used for vbit only&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
  -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
 local pos_data = ToolpathPosData()&lt;br /&gt;
 pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
 pos_data.SafeZGap = 5.0&lt;br /&gt;
 &lt;br /&gt;
  -- object used to pass data on toolpath settings&lt;br /&gt;
 toolpath_options = ExternalToolpathOptions()&lt;br /&gt;
 toolpath_options.StartDepth = start_depth&lt;br /&gt;
 toolpath_options.CreatePreview = true&lt;br /&gt;
 &lt;br /&gt;
  -- Create our toolpath&lt;br /&gt;
 local toolpath = ExternalToolpath(name,tool, pos_data, toolpath_options, vectors) &lt;br /&gt;
 &lt;br /&gt;
  if toolpath:Error() then&lt;br /&gt;
     DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
     return&lt;br /&gt;
  end&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  success = toolpath_manager:AddExternalToolpath(toolpath)&lt;br /&gt;
  return success&lt;br /&gt;
 end     &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Example_Toolpath_Code&amp;diff=1094</id>
		<title>Example Toolpath Code</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Example_Toolpath_Code&amp;diff=1094"/>
		<updated>2024-11-16T17:15:39Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: /* Profile Toolpaths */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
These are Code Examples for toolpaths.&lt;br /&gt;
&lt;br /&gt;
==Selection by Layer Name==&lt;br /&gt;
&lt;br /&gt;
===SelectVectorsOnLayer===&lt;br /&gt;
Create a selection set by layer name and object type, retunes the selection set.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function SelectVectorsOnLayer(layer, selection, select_closed, select_open, select_groups)&lt;br /&gt;
  --[[ Please Note: SelectVectorsOnLayer is provided by Vectric and can be found in the SDK and Sample Gadget files.&lt;br /&gt;
  -- | ---------------- SelectVectorsOnLayer ----------------&lt;br /&gt;
  -- |   SelectVectorsOnLayer(&amp;quot;Stringer Profile&amp;quot;, selection, true, false, false)&lt;br /&gt;
  -- |   Add all the vectors on the layer to the selection&lt;br /&gt;
  -- |     layer,            -- layer we are selecting vectors on&lt;br /&gt;
  -- |     selection         -- selection object&lt;br /&gt;
  -- |     select_closed     -- if true  select closed objects&lt;br /&gt;
  -- |     select_open       -- if true  select open objects&lt;br /&gt;
  -- |     select_groups     -- if true select grouped vectors (irrespective of open / closed state of member objects)&lt;br /&gt;
  -- |  Return Values:  true if selected one or more vectors&lt;br /&gt;
  -- |&lt;br /&gt;
  -- ====================================================]]&lt;br /&gt;
  local objects_selected = false&lt;br /&gt;
  local warning_displayed = false&lt;br /&gt;
  local pos = layer:GetHeadPosition()&lt;br /&gt;
  while pos ~= nil do&lt;br /&gt;
    local object&lt;br /&gt;
    object, pos = layer:GetNext(pos)&lt;br /&gt;
    local contour = object:GetContour()&lt;br /&gt;
    if contour == nil then&lt;br /&gt;
      if (object.ClassName == &amp;quot;vcCadObjectGroup&amp;quot;) and select_groups then&lt;br /&gt;
        selection:Add(object, true, true)&lt;br /&gt;
        objects_selected = true&lt;br /&gt;
      else&lt;br /&gt;
        if not warning_displayed then&lt;br /&gt;
          local message = &amp;quot;Object(s) without contour information found on layer - ignoring&amp;quot;&lt;br /&gt;
          if not select_groups then&lt;br /&gt;
            message = message ..  &amp;quot;\r\n\r\n&amp;quot; ..&lt;br /&gt;
            &amp;quot;If layer contains grouped vectors these must be un-grouped for this script&amp;quot;&lt;br /&gt;
          end -- if end&lt;br /&gt;
          StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Select Vectors&amp;quot;, message, &amp;quot;(7200)&amp;quot;)&lt;br /&gt;
          warning_displayed = true&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- if end&lt;br /&gt;
    else  -- contour was NOT nil, test if Open or Closed&lt;br /&gt;
      if contour.IsOpen and select_open then&lt;br /&gt;
        selection:Add(object, true, true)&lt;br /&gt;
        objects_selected = true&lt;br /&gt;
      elseif select_closed then&lt;br /&gt;
        selection:Add(object, true, true)&lt;br /&gt;
        objects_selected = true&lt;br /&gt;
      end -- if end&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- while end&lt;br /&gt;
  -- to avoid excessive redrawing etc. we added vectors to the selection in 'batch' mode&lt;br /&gt;
  -- tell selection we have now finished updating&lt;br /&gt;
  if objects_selected then&lt;br /&gt;
    selection:GroupSelectionFinished()&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return objects_selected&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Pocketing Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreatePocketingToolpath by Selection===&lt;br /&gt;
Create a Pocketing toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreatePocketingToolpath(name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
--[[ ------------ CreatePocketingToolpath ------------&lt;br /&gt;
|| =====================================================&lt;br /&gt;
| Create a Pocketing toolpath within the program for the currently selected vectors&lt;br /&gt;
| Parameters:&lt;br /&gt;
| name, -- Name for toolpath&lt;br /&gt;
| start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
| cut_depth -- cut depth for pocket toolpath&lt;br /&gt;
| tool_dia -- diameter of end mill to use&lt;br /&gt;
| tool_stepdown -- stepdown for tool&lt;br /&gt;
| tool_stepover_percent -- percentage stepover for tool&lt;br /&gt;
| tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
|| =====================================================]]&lt;br /&gt;
-- Return Values:&lt;br /&gt;
-- true if toolpath created OK else false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&amp;quot;Lua End Mill&amp;quot;,Tool.END_MILL -- BALL_NOSE, END_MILL, VBIT)&lt;br /&gt;
  tool.InMM = tool_in_mm&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * (tool_stepover_percent / 100)&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC,...&lt;br /&gt;
  tool.FeedRate = 30&lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBitAngle = 90.0 -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * (tool_stepover_percent / 100) -- used for vbit only&lt;br /&gt;
-- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
  pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
  pos_data.SafeZGap = 5.0&lt;br /&gt;
-- Create object used to pass pocketing options&lt;br /&gt;
  local pocket_data = PocketParameterData()&lt;br /&gt;
-- start depth for toolpath&lt;br /&gt;
  pocket_data.StartDepth = start_depth&lt;br /&gt;
-- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  pocket_data.CutDepth = cut_depth&lt;br /&gt;
-- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION or&lt;br /&gt;
-- ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
  pocket_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
-- Allowance to leave on when machining&lt;br /&gt;
  pocket_data.Allowance = 0.0&lt;br /&gt;
-- if true use raster clearance strategy , else use offset area clearance&lt;br /&gt;
  pocket_data.DoRasterClearance = true&lt;br /&gt;
-- angle for raster if using raster clearance&lt;br /&gt;
  pocket_data.RasterAngle = 0&lt;br /&gt;
-- type of profile pass to perform PocketParameterData.PROFILE_NONE ,&lt;br /&gt;
-- PocketParameterData.PROFILE_FIRST orPocketParameterData.PROFILE_LAST&lt;br /&gt;
  pocket_data.ProfilePassType = PocketParameterData.PROFILE_LAST&lt;br /&gt;
-- if true we ramp into pockets (always zig-zag)&lt;br /&gt;
  pocket_data.DoRamping = false&lt;br /&gt;
-- if ramping, distance to ramp over&lt;br /&gt;
  pocket_data.RampDistance = 10.0&lt;br /&gt;
-- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  pocket_data.ProjectToolpath = false&lt;br /&gt;
-- Create object which can be used to automatically select geometry&lt;br /&gt;
  local geometry_selector = GeometrySelector()&lt;br /&gt;
-- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
-- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
-- if we are doing two tool pocketing define tool to use for area clearance&lt;br /&gt;
  local area_clear_tool = nill&lt;br /&gt;
-- we just create a tool twice as large for testing here&lt;br /&gt;
  area_clear_tool = Tool(&amp;quot;Lua Clearance End Mill&amp;quot;,Tool.END_MILL) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
  area_clear_tool.InMM = tool_in_mm&lt;br /&gt;
  area_clear_tool.ToolDia = tool_dia * 2&lt;br /&gt;
  area_clear_tool.Stepdown = tool_stepdown * 2&lt;br /&gt;
  area_clear_tool.Stepover = tool_dia * 2 *(tool_stepover_percent / 100)&lt;br /&gt;
  area_clear_tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC..&lt;br /&gt;
  area_clear_tool.FeedRate = 30&lt;br /&gt;
  area_clear_tool.PlungeRate = 10&lt;br /&gt;
  area_clear_tool.SpindleSpeed = 20000&lt;br /&gt;
  area_clear_tool.ToolNumber = 1&lt;br /&gt;
  area_clear_tool.VBitAngle = 90.0 -- used for vbit only&lt;br /&gt;
  area_clear_tool.ClearStepover = tool_dia*2*(tool_stepover_percent/100) -- used for vbit&lt;br /&gt;
-- Create our toolpath&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreatePocketingToolpath(name, tool, area_clear_tool, pocket_data, pos_data, &lt;br /&gt;
                                                               geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
  if toolpath_id == nill then&lt;br /&gt;
     DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
     return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===CreatePocketingToolpath by Named Layer===&lt;br /&gt;
Create a Pocketing toolpath within the program for the named layer.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreateLayerPocketingToolpath(layer_name, name, start_depth, cut_depth)&lt;br /&gt;
  local caller = &amp;quot; - &amp;quot; .. name&lt;br /&gt;
  if Milling.Pocket then&lt;br /&gt;
    local selection = Milling.job.Selection  -- clear current selection&lt;br /&gt;
          selection:Clear()&lt;br /&gt;
  -- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot;   .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
   -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(MillTool2.Name, Tool.END_MILL)    -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
          tool.InMM = MillTool2.InMM            -- tool_in_mm&lt;br /&gt;
          tool.ToolDia = MillTool2.ToolDia         -- tool_dia&lt;br /&gt;
          tool.Stepdown = MillTool2.Stepdown        -- tool_stepdown&lt;br /&gt;
          tool.Stepover = MillTool2.Stepover        -- tool_dia * (tool_stepover_percent / 100)&lt;br /&gt;
          tool.RateUnits = MillTool2.RateUnits       -- Tool.MM_SEC     -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
          tool.FeedRate = MillTool2.FeedRate        -- 30&lt;br /&gt;
          tool.PlungeRate = MillTool2.PlungeRate      -- 10&lt;br /&gt;
          tool.SpindleSpeed = MillTool2.SpindleSpeed    -- 20000&lt;br /&gt;
          tool.ToolNumber = MillTool2.ToolNumber      -- 1&lt;br /&gt;
      --  tool.VBit_Angle = MillTool.VBit_Angle        -- 90.0            -- used for vbit only&lt;br /&gt;
      --  tool.ClearStepover = MillTool.ClearStepover   --  tool_dia * (tool_stepover_percent / 100)  -- used for vbit only&lt;br /&gt;
   -- we will set home position and safe z relative to material block size&lt;br /&gt;
    local mtl_block = MaterialBlock()&lt;br /&gt;
    local mtl_box = mtl_block.MaterialBox&lt;br /&gt;
    local mtl_box_blc = mtl_box.BLC&lt;br /&gt;
   -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
          pos_data:SetHomePosition(mtl_box_blc.x, mtl_box_blc.y, mtl_box.TRC.z + (mtl_block.Thickness * 0.2) )&lt;br /&gt;
          pos_data.SafeZGap = mtl_block.Thickness * 0.1&lt;br /&gt;
   -- Create  object used to pass pocketing options&lt;br /&gt;
    local pocket_data = PocketParameterData()&lt;br /&gt;
          -- start depth for toolpath&lt;br /&gt;
          pocket_data.StartDepth = start_depth&lt;br /&gt;
          -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
          pocket_data.CutDepth = cut_depth&lt;br /&gt;
          -- direction of cut for offset clearance - ProfileParameterData.CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION &lt;br /&gt;
          -- NOTE: enum from ProfileParameterData&lt;br /&gt;
          pocket_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
          -- Allowance to leave on when machining&lt;br /&gt;
          pocket_data.Allowance = 0.0&lt;br /&gt;
          -- if true use raster clearance strategy , else use offset area clearance&lt;br /&gt;
          pocket_data.DoRasterClearance = false --true&lt;br /&gt;
          -- angle for raster if using raster clearance&lt;br /&gt;
          pocket_data.RasterAngle = 0&lt;br /&gt;
          -- type of profile pass to perform  PocketParameterData.PROFILE_NONE , PocketParameterData.PROFILE_FIRST orPocketParameterData.PROFILE_LAST&lt;br /&gt;
          pocket_data.ProfilePassType = PocketParameterData.PROFILE_LAST&lt;br /&gt;
          -- if true we ramp into pockets (always zig-zag)&lt;br /&gt;
          pocket_data.DoRamping = false&lt;br /&gt;
          --  if ramping, distance to ramp over&lt;br /&gt;
          pocket_data.RampDistance = 1.0&lt;br /&gt;
          -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
          pocket_data.ProjectToolpath = false&lt;br /&gt;
   -- Create object which can used to automatically select geometry on layers etc.&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
   -- if this is true we create 2d toolpaths previews in 2d view, if false we don't&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
   -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings =  true -- false --&lt;br /&gt;
   -- if we are doing two tool pocketing define tool to use for area clearance&lt;br /&gt;
    local area_clear_tool = nil&lt;br /&gt;
    if Milling.Clearning then&lt;br /&gt;
   -- we just create a tool twice as large for testing here&lt;br /&gt;
     area_clear_tool = Tool(MillTool3.Name, Tool.END_MILL)  -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
     area_clear_tool.InMM = MillTool3.InMM       -- tool_in_mm&lt;br /&gt;
     area_clear_tool.ToolDia = MillTool3.ToolDia    -- tool_dia * 2&lt;br /&gt;
     area_clear_tool.Stepdown = MillTool3.Stepdown   -- tool_stepdown * 2&lt;br /&gt;
     area_clear_tool.Stepover = MillTool3.Stepover   -- tool_dia * 2 *(tool_stepover_percent / 100)&lt;br /&gt;
     area_clear_tool.RateUnits = MillTool3.RateUnits  -- Tool.MM_SEC  -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
     area_clear_tool.FeedRate = MillTool3.FeedRate      -- 30&lt;br /&gt;
     area_clear_tool.PlungeRate = MillTool3.PlungeRate    -- 10&lt;br /&gt;
     area_clear_tool.SpindleSpeed = MillTool3.SpindleSpeed  -- 20000&lt;br /&gt;
     area_clear_tool.ToolNumber = MillTool3.ToolNumber    -- 1&lt;br /&gt;
    end -- if end&lt;br /&gt;
     -- area_clear_tool.VBit_Angle = Carrier.MillTool3.VBit_Angle      -- 90.0 -- used for vbit only&lt;br /&gt;
     -- area_clear_tool.ClearStepover = Carrier.MillTool3.ClearStepover  -- tool_dia * 2 * (tool_stepover_percent / 100)  -- used for vbit only&lt;br /&gt;
   -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePocketingToolpath(&lt;br /&gt;
                                              name,&lt;br /&gt;
                                              tool,&lt;br /&gt;
                                              area_clear_tool,&lt;br /&gt;
                                              pocket_data,&lt;br /&gt;
                                              pos_data,&lt;br /&gt;
                                              geometry_selector,&lt;br /&gt;
                                              create_2d_previews,&lt;br /&gt;
                                              display_warnings&lt;br /&gt;
                                              )&lt;br /&gt;
    if toolpath_id  == nil  then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Milling Settings&amp;quot;, &amp;quot;Unable to create toolpath.&amp;quot;, &amp;quot;(4603)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
  end -- if end &lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Drilling Toolpath== &lt;br /&gt;
===Drilling Toolpath by Selection===&lt;br /&gt;
&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreateDrillingToolpath(name, start_depth, cut_depth, retract_gap, &lt;br /&gt;
                                          tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
--[[ ------- CreateDrillingToolpath --------------------------------------------------&lt;br /&gt;
||&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors&lt;br /&gt;
| Parameters:&lt;br /&gt;
| name, -- Name for toolpath&lt;br /&gt;
| start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
| cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
| retract_gap -- distance to retract above surface for pecks&lt;br /&gt;
| tool_dia -- diameter of drill to use&lt;br /&gt;
| tool_stepdown -- stepdown for tool&lt;br /&gt;
| tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
||&lt;br /&gt;
  Return Values:&lt;br /&gt;
|   true if toolpath created OK else false&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
-- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&amp;quot;Lua Drill&amp;quot;, Tool.THROUGH_DRILL) -- BALL_NOSE, END_MILL, VBIT, THROUGH_DRILL&lt;br /&gt;
  tool.InMM = tool_in_mm&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * 0.25&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
  tool.FeedRate = 30&lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBitAngle = 90.0 -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
-- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
        pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
        pos_data.SafeZGap = 5.0&lt;br /&gt;
-- Create object used to pass profile options&lt;br /&gt;
  local drill_data = DrillParameterData()&lt;br /&gt;
-- start depth for toolpath&lt;br /&gt;
  drill_data.StartDepth = start_depth&lt;br /&gt;
-- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  drill_data.CutDepth = cut_depth&lt;br /&gt;
-- if true perform peck drilling&lt;br /&gt;
  drill_data.DoPeckDrill = retract_gap &amp;gt; 0.0&lt;br /&gt;
-- distance to retract above surface when peck drilling&lt;br /&gt;
  drill_data.PeckRetractGap = retract_gap&lt;br /&gt;
-- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  drill_data.ProjectToolpath = false&lt;br /&gt;
-- Create object which can be used to automatically select geometry&lt;br /&gt;
  local geometry_selector = GeometrySelector()&lt;br /&gt;
-- if this is true we create 2d toolpaths previews in 2d view,&lt;br /&gt;
-- if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
-- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
-- Create our toolpath&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreateDrillingToolpath(name, tool, drill_data, pos_data, geometry_selector, &lt;br /&gt;
                                                            create_2d_previews, display_warnings)&lt;br /&gt;
  if toolpath_id == nil then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
    return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Drilling Toolpath by Named Layer===&lt;br /&gt;
&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreateDrillingToolpath(layer_name, name, start_depth, cut_depth, retract_gap, &lt;br /&gt;
                                          tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
--[[ ------- CreateDrillingToolpath --------------------------------------------------&lt;br /&gt;
||&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors&lt;br /&gt;
| Parameters:&lt;br /&gt;
| name, -- Name for toolpath&lt;br /&gt;
| start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
| cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
| retract_gap -- distance to retract above surface for pecks&lt;br /&gt;
| tool_dia -- diameter of drill to use&lt;br /&gt;
| tool_stepdown -- stepdown for tool&lt;br /&gt;
| tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
||&lt;br /&gt;
  Return Values:&lt;br /&gt;
|   true if toolpath created OK else false&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
-- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot;   .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
-- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&amp;quot;Lua Drill&amp;quot;, Tool.THROUGH_DRILL) -- BALL_NOSE, END_MILL, VBIT, THROUGH_DRILL&lt;br /&gt;
  tool.InMM = tool_in_mm&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * 0.25&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
  tool.FeedRate = 30&lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBitAngle = 90.0 -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
-- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
        pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
        pos_data.SafeZGap = 5.0&lt;br /&gt;
-- Create object used to pass profile options&lt;br /&gt;
  local drill_data = DrillParameterData()&lt;br /&gt;
-- start depth for toolpath&lt;br /&gt;
  drill_data.StartDepth = start_depth&lt;br /&gt;
-- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  drill_data.CutDepth = cut_depth&lt;br /&gt;
-- if true perform peck drilling&lt;br /&gt;
  drill_data.DoPeckDrill = retract_gap &amp;gt; 0.0&lt;br /&gt;
-- distance to retract above surface when peck drilling&lt;br /&gt;
  drill_data.PeckRetractGap = retract_gap&lt;br /&gt;
-- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  drill_data.ProjectToolpath = false&lt;br /&gt;
-- Create object which can be used to automatically select geometry&lt;br /&gt;
  local geometry_selector = GeometrySelector()&lt;br /&gt;
-- if this is true we create 2d toolpaths previews in 2d view,&lt;br /&gt;
-- if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
-- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
-- Create our toolpath&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreateDrillingToolpath(name, tool, drill_data, pos_data, geometry_selector, &lt;br /&gt;
                                                            create_2d_previews, display_warnings)&lt;br /&gt;
  if toolpath_id == nil then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
    return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==V-Carve Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreateVCarveToolpath by Selection===&lt;br /&gt;
Create a V-Carve toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===CreateVCarveToolpath by Layer Name===&lt;br /&gt;
Create a V-Carve toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Fluting Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreateFlutingToolpath by Selection===&lt;br /&gt;
Create a Fluting toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;  function CreateFlutingToolpath(name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
    --[[ ----------------- CreateFlutingToolpath -----------------&lt;br /&gt;
  | Create a flutting toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for toolpath&lt;br /&gt;
  | tool_dia -- diameter of tool to use&lt;br /&gt;
  | tool_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua Ball Nose&amp;quot;, Tool.BALL_NOSE) -- BALL_NOSE, END_MILL, VBit_Angle, THROUGH_DRILL&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * 0.25&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass fluting options&lt;br /&gt;
    local fluting_data = FlutingParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    fluting_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    fluting_data.CutDepth = cut_depth&lt;br /&gt;
    -- type of fluting FULL_LENGTH, RAMP_START or RAMP_START_END&lt;br /&gt;
    fluting_data.FluteType = FlutingParameterData.RAMP_START_END&lt;br /&gt;
    -- type of ramping RAMP_LINEAR, RAMP_SMOOTH&lt;br /&gt;
    fluting_data.RampType = FlutingParameterData.RAMP_LINEAR&lt;br /&gt;
    -- if true use ratio field for controling ramp length else absolute length value&lt;br /&gt;
    fluting_data.UseRampRatio = false&lt;br /&gt;
    -- length of ramp as ratio of flute length(range 0 - 1.0)&lt;br /&gt;
    -- (for start and end - ratio is of half length)&lt;br /&gt;
    fluting_data.RampRatio = 0.2&lt;br /&gt;
    -- length to ramp over - if UseRampRatio == false&lt;br /&gt;
    fluting_data.RampLength = 15&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    fluting_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateFlutingToolpath(name, tool, fluting_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    else&lt;br /&gt;
      return true&lt;br /&gt;
    end -- if end &lt;br /&gt;
&lt;br /&gt;
    end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===CreateFlutingToolpath by Layer Name===&lt;br /&gt;
Create a Fluting toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Profile Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreateProfileToolpath by Selection===&lt;br /&gt;
Create a Profile toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===CreateProfileToolpath by Layer Name===&lt;br /&gt;
Create a Profile toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function CreateProfileToolpath(layer_name, name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
   -- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot;   .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua End Mill&amp;quot;, Tool.END_MILL) -- BALL_NOSE, END_MILL, VBit&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * 0.25&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC ...&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local profile_data = ProfileParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    profile_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    profile_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut - ProfileParameterData.&lt;br /&gt;
    -- CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION&lt;br /&gt;
    profile_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- side we machine on - ProfileParameterData.&lt;br /&gt;
    -- PROFILE_OUTSIDE, ProfileParameterData.PROFILE_INSIDE or&lt;br /&gt;
    -- ProfileParameterData.PROFILE_ON&lt;br /&gt;
    profile_data.ProfileSide = ProfileParameterData.PROFILE_OUTSIDE&lt;br /&gt;
    -- Allowance to leave on when machining&lt;br /&gt;
    profile_data.Allowance = 0.0&lt;br /&gt;
    -- true to preserve start point positions, false to reorder start&lt;br /&gt;
    -- points to minimise toolpath length&lt;br /&gt;
    profile_data.KeepStartPoints = false&lt;br /&gt;
    -- true if want to create 'square' external corners on toolpath&lt;br /&gt;
    profile_data.CreateSquareCorners = false&lt;br /&gt;
    -- true to perform corner sharpening on internal corners (only with v-bits)&lt;br /&gt;
    profile_data.CornerSharpen = false&lt;br /&gt;
    -- true to use tabs (position of tabs must already have been defined on vectors)&lt;br /&gt;
    profile_data.UseTabs = false&lt;br /&gt;
    -- length for tabs if being used&lt;br /&gt;
    profile_data.TabLength = 5.0&lt;br /&gt;
    -- Thickness for tabs if being used&lt;br /&gt;
    profile_data.TabThickness = 1.0&lt;br /&gt;
    -- if true then create 3d tabs else 2d tabs&lt;br /&gt;
    profile_data.Use3dTabs = true&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    profile_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object used to control ramping&lt;br /&gt;
    local ramping_data = RampingData()&lt;br /&gt;
    -- if true we do ramping into toolpath&lt;br /&gt;
    ramping_data.DoRamping = false&lt;br /&gt;
    -- type of ramping to perform RampingData.RAMP_LINEAR , RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
    -- or RampingData.RAMP_SPIRAL&lt;br /&gt;
    ramping_data.RampType = RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
    -- how ramp is contrained - either by angle or distance RampingData.CONSTRAIN_DISTANCE&lt;br /&gt;
    -- or RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
    ramping_data.RampConstraint = RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
    -- if we are constraining ramp by distance, distance to ramp over&lt;br /&gt;
    ramping_data.RampDistance = 100.0&lt;br /&gt;
    -- if we are contraining ramp by angle , angle to ramp in at (in degrees)&lt;br /&gt;
    ramping_data.RampAngle = 25.0&lt;br /&gt;
    -- if we are contraining ramp by angle, max distance to travel before 'zig zaging'&lt;br /&gt;
    -- if zig zaging&lt;br /&gt;
    ramping_data.RampMaxAngleDist = 15&lt;br /&gt;
    -- if true we restrict our ramping to lead in section of toolpath&lt;br /&gt;
    ramping_data.RampOnLeadIn = false&lt;br /&gt;
    -- Create object used to control lead in/out&lt;br /&gt;
    local lead_in_out_data = LeadInOutData()&lt;br /&gt;
    -- if true we create lead ins on profiles (not for profile on)&lt;br /&gt;
    lead_in_out_data.DoLeadIn = false&lt;br /&gt;
    -- if true we create lead outs on profiles (not for profile on)&lt;br /&gt;
    lead_in_out_data.DoLeadOut = false&lt;br /&gt;
    -- type of leads to create LeadInOutData.LINEAR_LEAD or LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
    lead_in_out_data.LeadType = LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
    -- length of lead to create&lt;br /&gt;
    lead_in_out_data.LeadLength = 10.0&lt;br /&gt;
    -- Angle for linear leads&lt;br /&gt;
    lead_in_out_data.LinearLeadAngle = 45&lt;br /&gt;
    -- Radius for circular arc leads&lt;br /&gt;
    lead_in_out_data.CirularLeadRadius = 5.0&lt;br /&gt;
    -- distance to 'overcut' (travel past start point) when profiling&lt;br /&gt;
    lead_in_out_data.OvercutDistance = 0.0&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateProfilingToolpath(name, tool, profile_data, ramping_data, lead_in_out_data, pos_data, geometry_selector, create_2d_previews, display_warnings )&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Prism Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreatePrismToolpath by Selection===&lt;br /&gt;
Create a Prism toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;  function CreatePrismToolpath(name, start_depth, cut_depth, vbit_angle, vbit_dia, vbit_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
  --[[ ------------------- CreatePrismToolpath -------------------&lt;br /&gt;
  |&lt;br /&gt;
  | Create a prism toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
  | vbit_angle -- angle of vbit to use&lt;br /&gt;
  | vbit_dia -- diameter of VBit to use&lt;br /&gt;
  | vbit_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_stepover_percent - percentage stepover for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua VBit&amp;quot;, Tool.VBIT ) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = vbit_dia&lt;br /&gt;
    tool.Stepdown = vbit_stepdown&lt;br /&gt;
    tool.Stepover = vbit_dia * (tool_stepover_percent / 100)&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = vbit_dia * (tool_stepover_percent / 100) * 2 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local prism_data = PrismCarveParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    prism_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    prism_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- or ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
    prism_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- calculate the minimum cut depth to fully form the bevel on the current&lt;br /&gt;
    -- selection with the current tool&lt;br /&gt;
    local min_bevel_depth = prism_data:CalculateMinimumBevelDepth(tool, true)&lt;br /&gt;
    if min_bevel_depth &amp;gt; cut_depth then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;A prism will not be fully formed with a depth of &amp;quot; .. cut_depth .. &amp;quot;\r\n&amp;quot; ..&lt;br /&gt;
                        &amp;quot;A depth of &amp;quot; .. min_bevel_depth .. &amp;quot; is required to fully form the prism&amp;quot;&lt;br /&gt;
                        )&lt;br /&gt;
    end -- if end&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePrismCarvingToolpath(name, tool, prism_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===CreatePrismToolpath by Layer Name===&lt;br /&gt;
Create a Prism toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function CreatePrismToolpath(layer_name, name, start_depth, cut_depth, vbit_angle, vbit_dia, vbit_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
  --[[ ------------------- CreatePrismToolpath -------------------&lt;br /&gt;
  |&lt;br /&gt;
  | Create a prism toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
  | vbit_angle -- angle of vbit to use&lt;br /&gt;
  | vbit_dia -- diameter of VBit to use&lt;br /&gt;
  | vbit_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_stepover_percent - percentage stepover for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
   -- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot; .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua VBit&amp;quot;, Tool.VBIT ) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = vbit_dia&lt;br /&gt;
    tool.Stepdown = vbit_stepdown&lt;br /&gt;
    tool.Stepover = vbit_dia * (tool_stepover_percent / 100)&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = vbit_dia * (tool_stepover_percent / 100) * 2 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local prism_data = PrismCarveParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    prism_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    prism_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
    prism_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- calculate the minimum cut depth to fully form the bevel on the current&lt;br /&gt;
    -- selection with the current tool&lt;br /&gt;
    local min_bevel_depth = prism_data:CalculateMinimumBevelDepth(tool, true)&lt;br /&gt;
    if min_bevel_depth &amp;gt; cut_depth then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;A prism will not be fully formed with a depth of &amp;quot; .. cut_depth .. &amp;quot;\r\n&amp;quot; ..&lt;br /&gt;
                        &amp;quot;A depth of &amp;quot; .. min_bevel_depth .. &amp;quot; is required to fully form the prism&amp;quot;)&lt;br /&gt;
    end -- if end&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePrismCarvingToolpath(name, tool, prism_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Example_Toolpath_Code&amp;diff=1093</id>
		<title>Example Toolpath Code</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Example_Toolpath_Code&amp;diff=1093"/>
		<updated>2024-11-16T17:14:57Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: /* CreateProfileToolpath by Layer Name */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
These are Code Examples for toolpaths.&lt;br /&gt;
&lt;br /&gt;
==Selection by Layer Name==&lt;br /&gt;
&lt;br /&gt;
===SelectVectorsOnLayer===&lt;br /&gt;
Create a selection set by layer name and object type, retunes the selection set.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function SelectVectorsOnLayer(layer, selection, select_closed, select_open, select_groups)&lt;br /&gt;
  --[[ Please Note: SelectVectorsOnLayer is provided by Vectric and can be found in the SDK and Sample Gadget files.&lt;br /&gt;
  -- | ---------------- SelectVectorsOnLayer ----------------&lt;br /&gt;
  -- |   SelectVectorsOnLayer(&amp;quot;Stringer Profile&amp;quot;, selection, true, false, false)&lt;br /&gt;
  -- |   Add all the vectors on the layer to the selection&lt;br /&gt;
  -- |     layer,            -- layer we are selecting vectors on&lt;br /&gt;
  -- |     selection         -- selection object&lt;br /&gt;
  -- |     select_closed     -- if true  select closed objects&lt;br /&gt;
  -- |     select_open       -- if true  select open objects&lt;br /&gt;
  -- |     select_groups     -- if true select grouped vectors (irrespective of open / closed state of member objects)&lt;br /&gt;
  -- |  Return Values:  true if selected one or more vectors&lt;br /&gt;
  -- |&lt;br /&gt;
  -- ====================================================]]&lt;br /&gt;
  local objects_selected = false&lt;br /&gt;
  local warning_displayed = false&lt;br /&gt;
  local pos = layer:GetHeadPosition()&lt;br /&gt;
  while pos ~= nil do&lt;br /&gt;
    local object&lt;br /&gt;
    object, pos = layer:GetNext(pos)&lt;br /&gt;
    local contour = object:GetContour()&lt;br /&gt;
    if contour == nil then&lt;br /&gt;
      if (object.ClassName == &amp;quot;vcCadObjectGroup&amp;quot;) and select_groups then&lt;br /&gt;
        selection:Add(object, true, true)&lt;br /&gt;
        objects_selected = true&lt;br /&gt;
      else&lt;br /&gt;
        if not warning_displayed then&lt;br /&gt;
          local message = &amp;quot;Object(s) without contour information found on layer - ignoring&amp;quot;&lt;br /&gt;
          if not select_groups then&lt;br /&gt;
            message = message ..  &amp;quot;\r\n\r\n&amp;quot; ..&lt;br /&gt;
            &amp;quot;If layer contains grouped vectors these must be un-grouped for this script&amp;quot;&lt;br /&gt;
          end -- if end&lt;br /&gt;
          StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Select Vectors&amp;quot;, message, &amp;quot;(7200)&amp;quot;)&lt;br /&gt;
          warning_displayed = true&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- if end&lt;br /&gt;
    else  -- contour was NOT nil, test if Open or Closed&lt;br /&gt;
      if contour.IsOpen and select_open then&lt;br /&gt;
        selection:Add(object, true, true)&lt;br /&gt;
        objects_selected = true&lt;br /&gt;
      elseif select_closed then&lt;br /&gt;
        selection:Add(object, true, true)&lt;br /&gt;
        objects_selected = true&lt;br /&gt;
      end -- if end&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- while end&lt;br /&gt;
  -- to avoid excessive redrawing etc. we added vectors to the selection in 'batch' mode&lt;br /&gt;
  -- tell selection we have now finished updating&lt;br /&gt;
  if objects_selected then&lt;br /&gt;
    selection:GroupSelectionFinished()&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return objects_selected&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Pocketing Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreatePocketingToolpath by Selection===&lt;br /&gt;
Create a Pocketing toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreatePocketingToolpath(name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
--[[ ------------ CreatePocketingToolpath ------------&lt;br /&gt;
|| =====================================================&lt;br /&gt;
| Create a Pocketing toolpath within the program for the currently selected vectors&lt;br /&gt;
| Parameters:&lt;br /&gt;
| name, -- Name for toolpath&lt;br /&gt;
| start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
| cut_depth -- cut depth for pocket toolpath&lt;br /&gt;
| tool_dia -- diameter of end mill to use&lt;br /&gt;
| tool_stepdown -- stepdown for tool&lt;br /&gt;
| tool_stepover_percent -- percentage stepover for tool&lt;br /&gt;
| tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
|| =====================================================]]&lt;br /&gt;
-- Return Values:&lt;br /&gt;
-- true if toolpath created OK else false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&amp;quot;Lua End Mill&amp;quot;,Tool.END_MILL -- BALL_NOSE, END_MILL, VBIT)&lt;br /&gt;
  tool.InMM = tool_in_mm&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * (tool_stepover_percent / 100)&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC,...&lt;br /&gt;
  tool.FeedRate = 30&lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBitAngle = 90.0 -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * (tool_stepover_percent / 100) -- used for vbit only&lt;br /&gt;
-- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
  pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
  pos_data.SafeZGap = 5.0&lt;br /&gt;
-- Create object used to pass pocketing options&lt;br /&gt;
  local pocket_data = PocketParameterData()&lt;br /&gt;
-- start depth for toolpath&lt;br /&gt;
  pocket_data.StartDepth = start_depth&lt;br /&gt;
-- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  pocket_data.CutDepth = cut_depth&lt;br /&gt;
-- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION or&lt;br /&gt;
-- ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
  pocket_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
-- Allowance to leave on when machining&lt;br /&gt;
  pocket_data.Allowance = 0.0&lt;br /&gt;
-- if true use raster clearance strategy , else use offset area clearance&lt;br /&gt;
  pocket_data.DoRasterClearance = true&lt;br /&gt;
-- angle for raster if using raster clearance&lt;br /&gt;
  pocket_data.RasterAngle = 0&lt;br /&gt;
-- type of profile pass to perform PocketParameterData.PROFILE_NONE ,&lt;br /&gt;
-- PocketParameterData.PROFILE_FIRST orPocketParameterData.PROFILE_LAST&lt;br /&gt;
  pocket_data.ProfilePassType = PocketParameterData.PROFILE_LAST&lt;br /&gt;
-- if true we ramp into pockets (always zig-zag)&lt;br /&gt;
  pocket_data.DoRamping = false&lt;br /&gt;
-- if ramping, distance to ramp over&lt;br /&gt;
  pocket_data.RampDistance = 10.0&lt;br /&gt;
-- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  pocket_data.ProjectToolpath = false&lt;br /&gt;
-- Create object which can be used to automatically select geometry&lt;br /&gt;
  local geometry_selector = GeometrySelector()&lt;br /&gt;
-- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
-- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
-- if we are doing two tool pocketing define tool to use for area clearance&lt;br /&gt;
  local area_clear_tool = nill&lt;br /&gt;
-- we just create a tool twice as large for testing here&lt;br /&gt;
  area_clear_tool = Tool(&amp;quot;Lua Clearance End Mill&amp;quot;,Tool.END_MILL) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
  area_clear_tool.InMM = tool_in_mm&lt;br /&gt;
  area_clear_tool.ToolDia = tool_dia * 2&lt;br /&gt;
  area_clear_tool.Stepdown = tool_stepdown * 2&lt;br /&gt;
  area_clear_tool.Stepover = tool_dia * 2 *(tool_stepover_percent / 100)&lt;br /&gt;
  area_clear_tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC..&lt;br /&gt;
  area_clear_tool.FeedRate = 30&lt;br /&gt;
  area_clear_tool.PlungeRate = 10&lt;br /&gt;
  area_clear_tool.SpindleSpeed = 20000&lt;br /&gt;
  area_clear_tool.ToolNumber = 1&lt;br /&gt;
  area_clear_tool.VBitAngle = 90.0 -- used for vbit only&lt;br /&gt;
  area_clear_tool.ClearStepover = tool_dia*2*(tool_stepover_percent/100) -- used for vbit&lt;br /&gt;
-- Create our toolpath&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreatePocketingToolpath(name, tool, area_clear_tool, pocket_data, pos_data, &lt;br /&gt;
                                                               geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
  if toolpath_id == nill then&lt;br /&gt;
     DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
     return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===CreatePocketingToolpath by Named Layer===&lt;br /&gt;
Create a Pocketing toolpath within the program for the named layer.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreateLayerPocketingToolpath(layer_name, name, start_depth, cut_depth)&lt;br /&gt;
  local caller = &amp;quot; - &amp;quot; .. name&lt;br /&gt;
  if Milling.Pocket then&lt;br /&gt;
    local selection = Milling.job.Selection  -- clear current selection&lt;br /&gt;
          selection:Clear()&lt;br /&gt;
  -- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot;   .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
   -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(MillTool2.Name, Tool.END_MILL)    -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
          tool.InMM = MillTool2.InMM            -- tool_in_mm&lt;br /&gt;
          tool.ToolDia = MillTool2.ToolDia         -- tool_dia&lt;br /&gt;
          tool.Stepdown = MillTool2.Stepdown        -- tool_stepdown&lt;br /&gt;
          tool.Stepover = MillTool2.Stepover        -- tool_dia * (tool_stepover_percent / 100)&lt;br /&gt;
          tool.RateUnits = MillTool2.RateUnits       -- Tool.MM_SEC     -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
          tool.FeedRate = MillTool2.FeedRate        -- 30&lt;br /&gt;
          tool.PlungeRate = MillTool2.PlungeRate      -- 10&lt;br /&gt;
          tool.SpindleSpeed = MillTool2.SpindleSpeed    -- 20000&lt;br /&gt;
          tool.ToolNumber = MillTool2.ToolNumber      -- 1&lt;br /&gt;
      --  tool.VBit_Angle = MillTool.VBit_Angle        -- 90.0            -- used for vbit only&lt;br /&gt;
      --  tool.ClearStepover = MillTool.ClearStepover   --  tool_dia * (tool_stepover_percent / 100)  -- used for vbit only&lt;br /&gt;
   -- we will set home position and safe z relative to material block size&lt;br /&gt;
    local mtl_block = MaterialBlock()&lt;br /&gt;
    local mtl_box = mtl_block.MaterialBox&lt;br /&gt;
    local mtl_box_blc = mtl_box.BLC&lt;br /&gt;
   -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
          pos_data:SetHomePosition(mtl_box_blc.x, mtl_box_blc.y, mtl_box.TRC.z + (mtl_block.Thickness * 0.2) )&lt;br /&gt;
          pos_data.SafeZGap = mtl_block.Thickness * 0.1&lt;br /&gt;
   -- Create  object used to pass pocketing options&lt;br /&gt;
    local pocket_data = PocketParameterData()&lt;br /&gt;
          -- start depth for toolpath&lt;br /&gt;
          pocket_data.StartDepth = start_depth&lt;br /&gt;
          -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
          pocket_data.CutDepth = cut_depth&lt;br /&gt;
          -- direction of cut for offset clearance - ProfileParameterData.CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION &lt;br /&gt;
          -- NOTE: enum from ProfileParameterData&lt;br /&gt;
          pocket_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
          -- Allowance to leave on when machining&lt;br /&gt;
          pocket_data.Allowance = 0.0&lt;br /&gt;
          -- if true use raster clearance strategy , else use offset area clearance&lt;br /&gt;
          pocket_data.DoRasterClearance = false --true&lt;br /&gt;
          -- angle for raster if using raster clearance&lt;br /&gt;
          pocket_data.RasterAngle = 0&lt;br /&gt;
          -- type of profile pass to perform  PocketParameterData.PROFILE_NONE , PocketParameterData.PROFILE_FIRST orPocketParameterData.PROFILE_LAST&lt;br /&gt;
          pocket_data.ProfilePassType = PocketParameterData.PROFILE_LAST&lt;br /&gt;
          -- if true we ramp into pockets (always zig-zag)&lt;br /&gt;
          pocket_data.DoRamping = false&lt;br /&gt;
          --  if ramping, distance to ramp over&lt;br /&gt;
          pocket_data.RampDistance = 1.0&lt;br /&gt;
          -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
          pocket_data.ProjectToolpath = false&lt;br /&gt;
   -- Create object which can used to automatically select geometry on layers etc.&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
   -- if this is true we create 2d toolpaths previews in 2d view, if false we don't&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
   -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings =  true -- false --&lt;br /&gt;
   -- if we are doing two tool pocketing define tool to use for area clearance&lt;br /&gt;
    local area_clear_tool = nil&lt;br /&gt;
    if Milling.Clearning then&lt;br /&gt;
   -- we just create a tool twice as large for testing here&lt;br /&gt;
     area_clear_tool = Tool(MillTool3.Name, Tool.END_MILL)  -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
     area_clear_tool.InMM = MillTool3.InMM       -- tool_in_mm&lt;br /&gt;
     area_clear_tool.ToolDia = MillTool3.ToolDia    -- tool_dia * 2&lt;br /&gt;
     area_clear_tool.Stepdown = MillTool3.Stepdown   -- tool_stepdown * 2&lt;br /&gt;
     area_clear_tool.Stepover = MillTool3.Stepover   -- tool_dia * 2 *(tool_stepover_percent / 100)&lt;br /&gt;
     area_clear_tool.RateUnits = MillTool3.RateUnits  -- Tool.MM_SEC  -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
     area_clear_tool.FeedRate = MillTool3.FeedRate      -- 30&lt;br /&gt;
     area_clear_tool.PlungeRate = MillTool3.PlungeRate    -- 10&lt;br /&gt;
     area_clear_tool.SpindleSpeed = MillTool3.SpindleSpeed  -- 20000&lt;br /&gt;
     area_clear_tool.ToolNumber = MillTool3.ToolNumber    -- 1&lt;br /&gt;
    end -- if end&lt;br /&gt;
     -- area_clear_tool.VBit_Angle = Carrier.MillTool3.VBit_Angle      -- 90.0 -- used for vbit only&lt;br /&gt;
     -- area_clear_tool.ClearStepover = Carrier.MillTool3.ClearStepover  -- tool_dia * 2 * (tool_stepover_percent / 100)  -- used for vbit only&lt;br /&gt;
   -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePocketingToolpath(&lt;br /&gt;
                                              name,&lt;br /&gt;
                                              tool,&lt;br /&gt;
                                              area_clear_tool,&lt;br /&gt;
                                              pocket_data,&lt;br /&gt;
                                              pos_data,&lt;br /&gt;
                                              geometry_selector,&lt;br /&gt;
                                              create_2d_previews,&lt;br /&gt;
                                              display_warnings&lt;br /&gt;
                                              )&lt;br /&gt;
    if toolpath_id  == nil  then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Milling Settings&amp;quot;, &amp;quot;Unable to create toolpath.&amp;quot;, &amp;quot;(4603)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
  end -- if end &lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Drilling Toolpath== &lt;br /&gt;
===Drilling Toolpath by Selection===&lt;br /&gt;
&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreateDrillingToolpath(name, start_depth, cut_depth, retract_gap, &lt;br /&gt;
                                          tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
--[[ ------- CreateDrillingToolpath --------------------------------------------------&lt;br /&gt;
||&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors&lt;br /&gt;
| Parameters:&lt;br /&gt;
| name, -- Name for toolpath&lt;br /&gt;
| start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
| cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
| retract_gap -- distance to retract above surface for pecks&lt;br /&gt;
| tool_dia -- diameter of drill to use&lt;br /&gt;
| tool_stepdown -- stepdown for tool&lt;br /&gt;
| tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
||&lt;br /&gt;
  Return Values:&lt;br /&gt;
|   true if toolpath created OK else false&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
-- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&amp;quot;Lua Drill&amp;quot;, Tool.THROUGH_DRILL) -- BALL_NOSE, END_MILL, VBIT, THROUGH_DRILL&lt;br /&gt;
  tool.InMM = tool_in_mm&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * 0.25&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
  tool.FeedRate = 30&lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBitAngle = 90.0 -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
-- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
        pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
        pos_data.SafeZGap = 5.0&lt;br /&gt;
-- Create object used to pass profile options&lt;br /&gt;
  local drill_data = DrillParameterData()&lt;br /&gt;
-- start depth for toolpath&lt;br /&gt;
  drill_data.StartDepth = start_depth&lt;br /&gt;
-- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  drill_data.CutDepth = cut_depth&lt;br /&gt;
-- if true perform peck drilling&lt;br /&gt;
  drill_data.DoPeckDrill = retract_gap &amp;gt; 0.0&lt;br /&gt;
-- distance to retract above surface when peck drilling&lt;br /&gt;
  drill_data.PeckRetractGap = retract_gap&lt;br /&gt;
-- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  drill_data.ProjectToolpath = false&lt;br /&gt;
-- Create object which can be used to automatically select geometry&lt;br /&gt;
  local geometry_selector = GeometrySelector()&lt;br /&gt;
-- if this is true we create 2d toolpaths previews in 2d view,&lt;br /&gt;
-- if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
-- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
-- Create our toolpath&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreateDrillingToolpath(name, tool, drill_data, pos_data, geometry_selector, &lt;br /&gt;
                                                            create_2d_previews, display_warnings)&lt;br /&gt;
  if toolpath_id == nil then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
    return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Drilling Toolpath by Named Layer===&lt;br /&gt;
&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreateDrillingToolpath(layer_name, name, start_depth, cut_depth, retract_gap, &lt;br /&gt;
                                          tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
--[[ ------- CreateDrillingToolpath --------------------------------------------------&lt;br /&gt;
||&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors&lt;br /&gt;
| Parameters:&lt;br /&gt;
| name, -- Name for toolpath&lt;br /&gt;
| start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
| cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
| retract_gap -- distance to retract above surface for pecks&lt;br /&gt;
| tool_dia -- diameter of drill to use&lt;br /&gt;
| tool_stepdown -- stepdown for tool&lt;br /&gt;
| tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
||&lt;br /&gt;
  Return Values:&lt;br /&gt;
|   true if toolpath created OK else false&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
-- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot;   .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
-- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&amp;quot;Lua Drill&amp;quot;, Tool.THROUGH_DRILL) -- BALL_NOSE, END_MILL, VBIT, THROUGH_DRILL&lt;br /&gt;
  tool.InMM = tool_in_mm&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * 0.25&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
  tool.FeedRate = 30&lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBitAngle = 90.0 -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
-- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
        pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
        pos_data.SafeZGap = 5.0&lt;br /&gt;
-- Create object used to pass profile options&lt;br /&gt;
  local drill_data = DrillParameterData()&lt;br /&gt;
-- start depth for toolpath&lt;br /&gt;
  drill_data.StartDepth = start_depth&lt;br /&gt;
-- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  drill_data.CutDepth = cut_depth&lt;br /&gt;
-- if true perform peck drilling&lt;br /&gt;
  drill_data.DoPeckDrill = retract_gap &amp;gt; 0.0&lt;br /&gt;
-- distance to retract above surface when peck drilling&lt;br /&gt;
  drill_data.PeckRetractGap = retract_gap&lt;br /&gt;
-- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  drill_data.ProjectToolpath = false&lt;br /&gt;
-- Create object which can be used to automatically select geometry&lt;br /&gt;
  local geometry_selector = GeometrySelector()&lt;br /&gt;
-- if this is true we create 2d toolpaths previews in 2d view,&lt;br /&gt;
-- if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
-- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
-- Create our toolpath&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreateDrillingToolpath(name, tool, drill_data, pos_data, geometry_selector, &lt;br /&gt;
                                                            create_2d_previews, display_warnings)&lt;br /&gt;
  if toolpath_id == nil then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
    return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==V-Carve Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreateVCarveToolpath by Selection===&lt;br /&gt;
Create a V-Carve toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===CreateVCarveToolpath by Layer Name===&lt;br /&gt;
Create a V-Carve toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Fluting Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreateFlutingToolpath by Selection===&lt;br /&gt;
Create a Fluting toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;  function CreateFlutingToolpath(name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
    --[[ ----------------- CreateFlutingToolpath -----------------&lt;br /&gt;
  | Create a flutting toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for toolpath&lt;br /&gt;
  | tool_dia -- diameter of tool to use&lt;br /&gt;
  | tool_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua Ball Nose&amp;quot;, Tool.BALL_NOSE) -- BALL_NOSE, END_MILL, VBit_Angle, THROUGH_DRILL&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * 0.25&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass fluting options&lt;br /&gt;
    local fluting_data = FlutingParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    fluting_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    fluting_data.CutDepth = cut_depth&lt;br /&gt;
    -- type of fluting FULL_LENGTH, RAMP_START or RAMP_START_END&lt;br /&gt;
    fluting_data.FluteType = FlutingParameterData.RAMP_START_END&lt;br /&gt;
    -- type of ramping RAMP_LINEAR, RAMP_SMOOTH&lt;br /&gt;
    fluting_data.RampType = FlutingParameterData.RAMP_LINEAR&lt;br /&gt;
    -- if true use ratio field for controling ramp length else absolute length value&lt;br /&gt;
    fluting_data.UseRampRatio = false&lt;br /&gt;
    -- length of ramp as ratio of flute length(range 0 - 1.0)&lt;br /&gt;
    -- (for start and end - ratio is of half length)&lt;br /&gt;
    fluting_data.RampRatio = 0.2&lt;br /&gt;
    -- length to ramp over - if UseRampRatio == false&lt;br /&gt;
    fluting_data.RampLength = 15&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    fluting_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateFlutingToolpath(name, tool, fluting_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    else&lt;br /&gt;
      return true&lt;br /&gt;
    end -- if end &lt;br /&gt;
&lt;br /&gt;
    end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===CreateFlutingToolpath by Layer Name===&lt;br /&gt;
Create a Fluting toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Profile Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreateProfileToolpath by Selection===&lt;br /&gt;
Create a Profile toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===CreateProfileToolpath by Layer Name===&lt;br /&gt;
Create a Profile toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function CreateProfileToolpath(layer_name, name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
   -- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot;   .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua End Mill&amp;quot;, Tool.END_MILL) -- BALL_NOSE, END_MILL, VBit_Angle&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * 0.25&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC ...&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local profile_data = ProfileParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    profile_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    profile_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut - ProfileParameterData.&lt;br /&gt;
    -- CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION&lt;br /&gt;
    profile_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- side we machine on - ProfileParameterData.&lt;br /&gt;
    -- PROFILE_OUTSIDE, ProfileParameterData.PROFILE_INSIDE or&lt;br /&gt;
    -- ProfileParameterData.PROFILE_ON&lt;br /&gt;
    profile_data.ProfileSide = ProfileParameterData.PROFILE_OUTSIDE&lt;br /&gt;
    -- Allowance to leave on when machining&lt;br /&gt;
    profile_data.Allowance = 0.0&lt;br /&gt;
    -- true to preserve start point positions, false to reorder start&lt;br /&gt;
    -- points to minimise toolpath length&lt;br /&gt;
    profile_data.KeepStartPoints = false&lt;br /&gt;
    -- true if want to create 'square' external corners on toolpath&lt;br /&gt;
    profile_data.CreateSquareCorners = false&lt;br /&gt;
    -- true to perform corner sharpening on internal corners (only with v-bits)&lt;br /&gt;
    profile_data.CornerSharpen = false&lt;br /&gt;
    -- true to use tabs (position of tabs must already have been defined on vectors)&lt;br /&gt;
    profile_data.UseTabs = false&lt;br /&gt;
    -- length for tabs if being used&lt;br /&gt;
    profile_data.TabLength = 5.0&lt;br /&gt;
    -- Thickness for tabs if being used&lt;br /&gt;
    profile_data.TabThickness = 1.0&lt;br /&gt;
    -- if true then create 3d tabs else 2d tabs&lt;br /&gt;
    profile_data.Use3dTabs = true&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    profile_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object used to control ramping&lt;br /&gt;
    local ramping_data = RampingData()&lt;br /&gt;
    -- if true we do ramping into toolpath&lt;br /&gt;
    ramping_data.DoRamping = false&lt;br /&gt;
    -- type of ramping to perform RampingData.RAMP_LINEAR , RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
    -- or RampingData.RAMP_SPIRAL&lt;br /&gt;
    ramping_data.RampType = RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
    -- how ramp is contrained - either by angle or distance RampingData.CONSTRAIN_DISTANCE&lt;br /&gt;
    -- or RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
    ramping_data.RampConstraint = RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
    -- if we are constraining ramp by distance, distance to ramp over&lt;br /&gt;
    ramping_data.RampDistance = 100.0&lt;br /&gt;
    -- if we are contraining ramp by angle , angle to ramp in at (in degrees)&lt;br /&gt;
    ramping_data.RampAngle = 25.0&lt;br /&gt;
    -- if we are contraining ramp by angle, max distance to travel before 'zig zaging'&lt;br /&gt;
    -- if zig zaging&lt;br /&gt;
    ramping_data.RampMaxAngleDist = 15&lt;br /&gt;
    -- if true we restrict our ramping to lead in section of toolpath&lt;br /&gt;
    ramping_data.RampOnLeadIn = false&lt;br /&gt;
    -- Create object used to control lead in/out&lt;br /&gt;
    local lead_in_out_data = LeadInOutData()&lt;br /&gt;
    -- if true we create lead ins on profiles (not for profile on)&lt;br /&gt;
    lead_in_out_data.DoLeadIn = false&lt;br /&gt;
    -- if true we create lead outs on profiles (not for profile on)&lt;br /&gt;
    lead_in_out_data.DoLeadOut = false&lt;br /&gt;
    -- type of leads to create LeadInOutData.LINEAR_LEAD or LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
    lead_in_out_data.LeadType = LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
    -- length of lead to create&lt;br /&gt;
    lead_in_out_data.LeadLength = 10.0&lt;br /&gt;
    -- Angle for linear leads&lt;br /&gt;
    lead_in_out_data.LinearLeadAngle = 45&lt;br /&gt;
    -- Radius for circular arc leads&lt;br /&gt;
    lead_in_out_data.CirularLeadRadius = 5.0&lt;br /&gt;
    -- distance to 'overcut' (travel past start point) when profiling&lt;br /&gt;
    lead_in_out_data.OvercutDistance = 0.0&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateProfilingToolpath(name, tool, profile_data, ramping_data, lead_in_out_data, pos_data, geometry_selector, create_2d_previews, display_warnings )&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Prism Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreatePrismToolpath by Selection===&lt;br /&gt;
Create a Prism toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;  function CreatePrismToolpath(name, start_depth, cut_depth, vbit_angle, vbit_dia, vbit_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
  --[[ ------------------- CreatePrismToolpath -------------------&lt;br /&gt;
  |&lt;br /&gt;
  | Create a prism toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
  | vbit_angle -- angle of vbit to use&lt;br /&gt;
  | vbit_dia -- diameter of VBit to use&lt;br /&gt;
  | vbit_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_stepover_percent - percentage stepover for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua VBit&amp;quot;, Tool.VBIT ) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = vbit_dia&lt;br /&gt;
    tool.Stepdown = vbit_stepdown&lt;br /&gt;
    tool.Stepover = vbit_dia * (tool_stepover_percent / 100)&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = vbit_dia * (tool_stepover_percent / 100) * 2 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local prism_data = PrismCarveParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    prism_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    prism_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- or ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
    prism_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- calculate the minimum cut depth to fully form the bevel on the current&lt;br /&gt;
    -- selection with the current tool&lt;br /&gt;
    local min_bevel_depth = prism_data:CalculateMinimumBevelDepth(tool, true)&lt;br /&gt;
    if min_bevel_depth &amp;gt; cut_depth then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;A prism will not be fully formed with a depth of &amp;quot; .. cut_depth .. &amp;quot;\r\n&amp;quot; ..&lt;br /&gt;
                        &amp;quot;A depth of &amp;quot; .. min_bevel_depth .. &amp;quot; is required to fully form the prism&amp;quot;&lt;br /&gt;
                        )&lt;br /&gt;
    end -- if end&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePrismCarvingToolpath(name, tool, prism_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===CreatePrismToolpath by Layer Name===&lt;br /&gt;
Create a Prism toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function CreatePrismToolpath(layer_name, name, start_depth, cut_depth, vbit_angle, vbit_dia, vbit_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
  --[[ ------------------- CreatePrismToolpath -------------------&lt;br /&gt;
  |&lt;br /&gt;
  | Create a prism toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
  | vbit_angle -- angle of vbit to use&lt;br /&gt;
  | vbit_dia -- diameter of VBit to use&lt;br /&gt;
  | vbit_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_stepover_percent - percentage stepover for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
   -- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot; .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua VBit&amp;quot;, Tool.VBIT ) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = vbit_dia&lt;br /&gt;
    tool.Stepdown = vbit_stepdown&lt;br /&gt;
    tool.Stepover = vbit_dia * (tool_stepover_percent / 100)&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = vbit_dia * (tool_stepover_percent / 100) * 2 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local prism_data = PrismCarveParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    prism_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    prism_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
    prism_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- calculate the minimum cut depth to fully form the bevel on the current&lt;br /&gt;
    -- selection with the current tool&lt;br /&gt;
    local min_bevel_depth = prism_data:CalculateMinimumBevelDepth(tool, true)&lt;br /&gt;
    if min_bevel_depth &amp;gt; cut_depth then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;A prism will not be fully formed with a depth of &amp;quot; .. cut_depth .. &amp;quot;\r\n&amp;quot; ..&lt;br /&gt;
                        &amp;quot;A depth of &amp;quot; .. min_bevel_depth .. &amp;quot; is required to fully form the prism&amp;quot;)&lt;br /&gt;
    end -- if end&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePrismCarvingToolpath(name, tool, prism_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Example_Toolpath_Code&amp;diff=1092</id>
		<title>Example Toolpath Code</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Example_Toolpath_Code&amp;diff=1092"/>
		<updated>2024-11-16T17:14:43Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: /* Fluting Toolpaths */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
These are Code Examples for toolpaths.&lt;br /&gt;
&lt;br /&gt;
==Selection by Layer Name==&lt;br /&gt;
&lt;br /&gt;
===SelectVectorsOnLayer===&lt;br /&gt;
Create a selection set by layer name and object type, retunes the selection set.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function SelectVectorsOnLayer(layer, selection, select_closed, select_open, select_groups)&lt;br /&gt;
  --[[ Please Note: SelectVectorsOnLayer is provided by Vectric and can be found in the SDK and Sample Gadget files.&lt;br /&gt;
  -- | ---------------- SelectVectorsOnLayer ----------------&lt;br /&gt;
  -- |   SelectVectorsOnLayer(&amp;quot;Stringer Profile&amp;quot;, selection, true, false, false)&lt;br /&gt;
  -- |   Add all the vectors on the layer to the selection&lt;br /&gt;
  -- |     layer,            -- layer we are selecting vectors on&lt;br /&gt;
  -- |     selection         -- selection object&lt;br /&gt;
  -- |     select_closed     -- if true  select closed objects&lt;br /&gt;
  -- |     select_open       -- if true  select open objects&lt;br /&gt;
  -- |     select_groups     -- if true select grouped vectors (irrespective of open / closed state of member objects)&lt;br /&gt;
  -- |  Return Values:  true if selected one or more vectors&lt;br /&gt;
  -- |&lt;br /&gt;
  -- ====================================================]]&lt;br /&gt;
  local objects_selected = false&lt;br /&gt;
  local warning_displayed = false&lt;br /&gt;
  local pos = layer:GetHeadPosition()&lt;br /&gt;
  while pos ~= nil do&lt;br /&gt;
    local object&lt;br /&gt;
    object, pos = layer:GetNext(pos)&lt;br /&gt;
    local contour = object:GetContour()&lt;br /&gt;
    if contour == nil then&lt;br /&gt;
      if (object.ClassName == &amp;quot;vcCadObjectGroup&amp;quot;) and select_groups then&lt;br /&gt;
        selection:Add(object, true, true)&lt;br /&gt;
        objects_selected = true&lt;br /&gt;
      else&lt;br /&gt;
        if not warning_displayed then&lt;br /&gt;
          local message = &amp;quot;Object(s) without contour information found on layer - ignoring&amp;quot;&lt;br /&gt;
          if not select_groups then&lt;br /&gt;
            message = message ..  &amp;quot;\r\n\r\n&amp;quot; ..&lt;br /&gt;
            &amp;quot;If layer contains grouped vectors these must be un-grouped for this script&amp;quot;&lt;br /&gt;
          end -- if end&lt;br /&gt;
          StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Select Vectors&amp;quot;, message, &amp;quot;(7200)&amp;quot;)&lt;br /&gt;
          warning_displayed = true&lt;br /&gt;
        end -- if end&lt;br /&gt;
      end -- if end&lt;br /&gt;
    else  -- contour was NOT nil, test if Open or Closed&lt;br /&gt;
      if contour.IsOpen and select_open then&lt;br /&gt;
        selection:Add(object, true, true)&lt;br /&gt;
        objects_selected = true&lt;br /&gt;
      elseif select_closed then&lt;br /&gt;
        selection:Add(object, true, true)&lt;br /&gt;
        objects_selected = true&lt;br /&gt;
      end -- if end&lt;br /&gt;
    end -- if end&lt;br /&gt;
  end -- while end&lt;br /&gt;
  -- to avoid excessive redrawing etc. we added vectors to the selection in 'batch' mode&lt;br /&gt;
  -- tell selection we have now finished updating&lt;br /&gt;
  if objects_selected then&lt;br /&gt;
    selection:GroupSelectionFinished()&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return objects_selected&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Pocketing Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreatePocketingToolpath by Selection===&lt;br /&gt;
Create a Pocketing toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreatePocketingToolpath(name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
--[[ ------------ CreatePocketingToolpath ------------&lt;br /&gt;
|| =====================================================&lt;br /&gt;
| Create a Pocketing toolpath within the program for the currently selected vectors&lt;br /&gt;
| Parameters:&lt;br /&gt;
| name, -- Name for toolpath&lt;br /&gt;
| start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
| cut_depth -- cut depth for pocket toolpath&lt;br /&gt;
| tool_dia -- diameter of end mill to use&lt;br /&gt;
| tool_stepdown -- stepdown for tool&lt;br /&gt;
| tool_stepover_percent -- percentage stepover for tool&lt;br /&gt;
| tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
|| =====================================================]]&lt;br /&gt;
-- Return Values:&lt;br /&gt;
-- true if toolpath created OK else false&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
-- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&amp;quot;Lua End Mill&amp;quot;,Tool.END_MILL -- BALL_NOSE, END_MILL, VBIT)&lt;br /&gt;
  tool.InMM = tool_in_mm&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * (tool_stepover_percent / 100)&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC,...&lt;br /&gt;
  tool.FeedRate = 30&lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBitAngle = 90.0 -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * (tool_stepover_percent / 100) -- used for vbit only&lt;br /&gt;
-- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
  pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
  pos_data.SafeZGap = 5.0&lt;br /&gt;
-- Create object used to pass pocketing options&lt;br /&gt;
  local pocket_data = PocketParameterData()&lt;br /&gt;
-- start depth for toolpath&lt;br /&gt;
  pocket_data.StartDepth = start_depth&lt;br /&gt;
-- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  pocket_data.CutDepth = cut_depth&lt;br /&gt;
-- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION or&lt;br /&gt;
-- ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
  pocket_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
-- Allowance to leave on when machining&lt;br /&gt;
  pocket_data.Allowance = 0.0&lt;br /&gt;
-- if true use raster clearance strategy , else use offset area clearance&lt;br /&gt;
  pocket_data.DoRasterClearance = true&lt;br /&gt;
-- angle for raster if using raster clearance&lt;br /&gt;
  pocket_data.RasterAngle = 0&lt;br /&gt;
-- type of profile pass to perform PocketParameterData.PROFILE_NONE ,&lt;br /&gt;
-- PocketParameterData.PROFILE_FIRST orPocketParameterData.PROFILE_LAST&lt;br /&gt;
  pocket_data.ProfilePassType = PocketParameterData.PROFILE_LAST&lt;br /&gt;
-- if true we ramp into pockets (always zig-zag)&lt;br /&gt;
  pocket_data.DoRamping = false&lt;br /&gt;
-- if ramping, distance to ramp over&lt;br /&gt;
  pocket_data.RampDistance = 10.0&lt;br /&gt;
-- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  pocket_data.ProjectToolpath = false&lt;br /&gt;
-- Create object which can be used to automatically select geometry&lt;br /&gt;
  local geometry_selector = GeometrySelector()&lt;br /&gt;
-- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
-- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
-- if we are doing two tool pocketing define tool to use for area clearance&lt;br /&gt;
  local area_clear_tool = nill&lt;br /&gt;
-- we just create a tool twice as large for testing here&lt;br /&gt;
  area_clear_tool = Tool(&amp;quot;Lua Clearance End Mill&amp;quot;,Tool.END_MILL) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
  area_clear_tool.InMM = tool_in_mm&lt;br /&gt;
  area_clear_tool.ToolDia = tool_dia * 2&lt;br /&gt;
  area_clear_tool.Stepdown = tool_stepdown * 2&lt;br /&gt;
  area_clear_tool.Stepover = tool_dia * 2 *(tool_stepover_percent / 100)&lt;br /&gt;
  area_clear_tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC..&lt;br /&gt;
  area_clear_tool.FeedRate = 30&lt;br /&gt;
  area_clear_tool.PlungeRate = 10&lt;br /&gt;
  area_clear_tool.SpindleSpeed = 20000&lt;br /&gt;
  area_clear_tool.ToolNumber = 1&lt;br /&gt;
  area_clear_tool.VBitAngle = 90.0 -- used for vbit only&lt;br /&gt;
  area_clear_tool.ClearStepover = tool_dia*2*(tool_stepover_percent/100) -- used for vbit&lt;br /&gt;
-- Create our toolpath&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreatePocketingToolpath(name, tool, area_clear_tool, pocket_data, pos_data, &lt;br /&gt;
                                                               geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
  if toolpath_id == nill then&lt;br /&gt;
     DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
     return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===CreatePocketingToolpath by Named Layer===&lt;br /&gt;
Create a Pocketing toolpath within the program for the named layer.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreateLayerPocketingToolpath(layer_name, name, start_depth, cut_depth)&lt;br /&gt;
  local caller = &amp;quot; - &amp;quot; .. name&lt;br /&gt;
  if Milling.Pocket then&lt;br /&gt;
    local selection = Milling.job.Selection  -- clear current selection&lt;br /&gt;
          selection:Clear()&lt;br /&gt;
  -- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot;   .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
   -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(MillTool2.Name, Tool.END_MILL)    -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
          tool.InMM = MillTool2.InMM            -- tool_in_mm&lt;br /&gt;
          tool.ToolDia = MillTool2.ToolDia         -- tool_dia&lt;br /&gt;
          tool.Stepdown = MillTool2.Stepdown        -- tool_stepdown&lt;br /&gt;
          tool.Stepover = MillTool2.Stepover        -- tool_dia * (tool_stepover_percent / 100)&lt;br /&gt;
          tool.RateUnits = MillTool2.RateUnits       -- Tool.MM_SEC     -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
          tool.FeedRate = MillTool2.FeedRate        -- 30&lt;br /&gt;
          tool.PlungeRate = MillTool2.PlungeRate      -- 10&lt;br /&gt;
          tool.SpindleSpeed = MillTool2.SpindleSpeed    -- 20000&lt;br /&gt;
          tool.ToolNumber = MillTool2.ToolNumber      -- 1&lt;br /&gt;
      --  tool.VBit_Angle = MillTool.VBit_Angle        -- 90.0            -- used for vbit only&lt;br /&gt;
      --  tool.ClearStepover = MillTool.ClearStepover   --  tool_dia * (tool_stepover_percent / 100)  -- used for vbit only&lt;br /&gt;
   -- we will set home position and safe z relative to material block size&lt;br /&gt;
    local mtl_block = MaterialBlock()&lt;br /&gt;
    local mtl_box = mtl_block.MaterialBox&lt;br /&gt;
    local mtl_box_blc = mtl_box.BLC&lt;br /&gt;
   -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
          pos_data:SetHomePosition(mtl_box_blc.x, mtl_box_blc.y, mtl_box.TRC.z + (mtl_block.Thickness * 0.2) )&lt;br /&gt;
          pos_data.SafeZGap = mtl_block.Thickness * 0.1&lt;br /&gt;
   -- Create  object used to pass pocketing options&lt;br /&gt;
    local pocket_data = PocketParameterData()&lt;br /&gt;
          -- start depth for toolpath&lt;br /&gt;
          pocket_data.StartDepth = start_depth&lt;br /&gt;
          -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
          pocket_data.CutDepth = cut_depth&lt;br /&gt;
          -- direction of cut for offset clearance - ProfileParameterData.CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION &lt;br /&gt;
          -- NOTE: enum from ProfileParameterData&lt;br /&gt;
          pocket_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
          -- Allowance to leave on when machining&lt;br /&gt;
          pocket_data.Allowance = 0.0&lt;br /&gt;
          -- if true use raster clearance strategy , else use offset area clearance&lt;br /&gt;
          pocket_data.DoRasterClearance = false --true&lt;br /&gt;
          -- angle for raster if using raster clearance&lt;br /&gt;
          pocket_data.RasterAngle = 0&lt;br /&gt;
          -- type of profile pass to perform  PocketParameterData.PROFILE_NONE , PocketParameterData.PROFILE_FIRST orPocketParameterData.PROFILE_LAST&lt;br /&gt;
          pocket_data.ProfilePassType = PocketParameterData.PROFILE_LAST&lt;br /&gt;
          -- if true we ramp into pockets (always zig-zag)&lt;br /&gt;
          pocket_data.DoRamping = false&lt;br /&gt;
          --  if ramping, distance to ramp over&lt;br /&gt;
          pocket_data.RampDistance = 1.0&lt;br /&gt;
          -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
          pocket_data.ProjectToolpath = false&lt;br /&gt;
   -- Create object which can used to automatically select geometry on layers etc.&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
   -- if this is true we create 2d toolpaths previews in 2d view, if false we don't&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
   -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings =  true -- false --&lt;br /&gt;
   -- if we are doing two tool pocketing define tool to use for area clearance&lt;br /&gt;
    local area_clear_tool = nil&lt;br /&gt;
    if Milling.Clearning then&lt;br /&gt;
   -- we just create a tool twice as large for testing here&lt;br /&gt;
     area_clear_tool = Tool(MillTool3.Name, Tool.END_MILL)  -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
     area_clear_tool.InMM = MillTool3.InMM       -- tool_in_mm&lt;br /&gt;
     area_clear_tool.ToolDia = MillTool3.ToolDia    -- tool_dia * 2&lt;br /&gt;
     area_clear_tool.Stepdown = MillTool3.Stepdown   -- tool_stepdown * 2&lt;br /&gt;
     area_clear_tool.Stepover = MillTool3.Stepover   -- tool_dia * 2 *(tool_stepover_percent / 100)&lt;br /&gt;
     area_clear_tool.RateUnits = MillTool3.RateUnits  -- Tool.MM_SEC  -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
     area_clear_tool.FeedRate = MillTool3.FeedRate      -- 30&lt;br /&gt;
     area_clear_tool.PlungeRate = MillTool3.PlungeRate    -- 10&lt;br /&gt;
     area_clear_tool.SpindleSpeed = MillTool3.SpindleSpeed  -- 20000&lt;br /&gt;
     area_clear_tool.ToolNumber = MillTool3.ToolNumber    -- 1&lt;br /&gt;
    end -- if end&lt;br /&gt;
     -- area_clear_tool.VBit_Angle = Carrier.MillTool3.VBit_Angle      -- 90.0 -- used for vbit only&lt;br /&gt;
     -- area_clear_tool.ClearStepover = Carrier.MillTool3.ClearStepover  -- tool_dia * 2 * (tool_stepover_percent / 100)  -- used for vbit only&lt;br /&gt;
   -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePocketingToolpath(&lt;br /&gt;
                                              name,&lt;br /&gt;
                                              tool,&lt;br /&gt;
                                              area_clear_tool,&lt;br /&gt;
                                              pocket_data,&lt;br /&gt;
                                              pos_data,&lt;br /&gt;
                                              geometry_selector,&lt;br /&gt;
                                              create_2d_previews,&lt;br /&gt;
                                              display_warnings&lt;br /&gt;
                                              )&lt;br /&gt;
    if toolpath_id  == nil  then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Milling Settings&amp;quot;, &amp;quot;Unable to create toolpath.&amp;quot;, &amp;quot;(4603)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
  end -- if end &lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Drilling Toolpath== &lt;br /&gt;
===Drilling Toolpath by Selection===&lt;br /&gt;
&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreateDrillingToolpath(name, start_depth, cut_depth, retract_gap, &lt;br /&gt;
                                          tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
--[[ ------- CreateDrillingToolpath --------------------------------------------------&lt;br /&gt;
||&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors&lt;br /&gt;
| Parameters:&lt;br /&gt;
| name, -- Name for toolpath&lt;br /&gt;
| start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
| cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
| retract_gap -- distance to retract above surface for pecks&lt;br /&gt;
| tool_dia -- diameter of drill to use&lt;br /&gt;
| tool_stepdown -- stepdown for tool&lt;br /&gt;
| tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
||&lt;br /&gt;
  Return Values:&lt;br /&gt;
|   true if toolpath created OK else false&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
-- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&amp;quot;Lua Drill&amp;quot;, Tool.THROUGH_DRILL) -- BALL_NOSE, END_MILL, VBIT, THROUGH_DRILL&lt;br /&gt;
  tool.InMM = tool_in_mm&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * 0.25&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
  tool.FeedRate = 30&lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBitAngle = 90.0 -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
-- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
        pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
        pos_data.SafeZGap = 5.0&lt;br /&gt;
-- Create object used to pass profile options&lt;br /&gt;
  local drill_data = DrillParameterData()&lt;br /&gt;
-- start depth for toolpath&lt;br /&gt;
  drill_data.StartDepth = start_depth&lt;br /&gt;
-- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  drill_data.CutDepth = cut_depth&lt;br /&gt;
-- if true perform peck drilling&lt;br /&gt;
  drill_data.DoPeckDrill = retract_gap &amp;gt; 0.0&lt;br /&gt;
-- distance to retract above surface when peck drilling&lt;br /&gt;
  drill_data.PeckRetractGap = retract_gap&lt;br /&gt;
-- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  drill_data.ProjectToolpath = false&lt;br /&gt;
-- Create object which can be used to automatically select geometry&lt;br /&gt;
  local geometry_selector = GeometrySelector()&lt;br /&gt;
-- if this is true we create 2d toolpaths previews in 2d view,&lt;br /&gt;
-- if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
-- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
-- Create our toolpath&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreateDrillingToolpath(name, tool, drill_data, pos_data, geometry_selector, &lt;br /&gt;
                                                            create_2d_previews, display_warnings)&lt;br /&gt;
  if toolpath_id == nil then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
    return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Drilling Toolpath by Named Layer===&lt;br /&gt;
&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;function CreateDrillingToolpath(layer_name, name, start_depth, cut_depth, retract_gap, &lt;br /&gt;
                                          tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
--[[ ------- CreateDrillingToolpath --------------------------------------------------&lt;br /&gt;
||&lt;br /&gt;
Create a drilling toolpath within the program for the currently selected vectors&lt;br /&gt;
| Parameters:&lt;br /&gt;
| name, -- Name for toolpath&lt;br /&gt;
| start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
| cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
| retract_gap -- distance to retract above surface for pecks&lt;br /&gt;
| tool_dia -- diameter of drill to use&lt;br /&gt;
| tool_stepdown -- stepdown for tool&lt;br /&gt;
| tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
||&lt;br /&gt;
  Return Values:&lt;br /&gt;
|   true if toolpath created OK else false&lt;br /&gt;
|&lt;br /&gt;
]]&lt;br /&gt;
-- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot;   .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
-- Create tool we will use to machine vectors&lt;br /&gt;
  local tool = Tool(&amp;quot;Lua Drill&amp;quot;, Tool.THROUGH_DRILL) -- BALL_NOSE, END_MILL, VBIT, THROUGH_DRILL&lt;br /&gt;
  tool.InMM = tool_in_mm&lt;br /&gt;
  tool.ToolDia = tool_dia&lt;br /&gt;
  tool.Stepdown = tool_stepdown&lt;br /&gt;
  tool.Stepover = tool_dia * 0.25&lt;br /&gt;
  tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
  tool.FeedRate = 30&lt;br /&gt;
  tool.PlungeRate = 10&lt;br /&gt;
  tool.SpindleSpeed = 20000&lt;br /&gt;
  tool.ToolNumber = 1&lt;br /&gt;
  tool.VBitAngle = 90.0 -- used for vbit only&lt;br /&gt;
  tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
-- Create object used to set home position and safez gap above material surface&lt;br /&gt;
  local pos_data = ToolpathPosData()&lt;br /&gt;
        pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
        pos_data.SafeZGap = 5.0&lt;br /&gt;
-- Create object used to pass profile options&lt;br /&gt;
  local drill_data = DrillParameterData()&lt;br /&gt;
-- start depth for toolpath&lt;br /&gt;
  drill_data.StartDepth = start_depth&lt;br /&gt;
-- cut depth for toolpath this is depth below start depth&lt;br /&gt;
  drill_data.CutDepth = cut_depth&lt;br /&gt;
-- if true perform peck drilling&lt;br /&gt;
  drill_data.DoPeckDrill = retract_gap &amp;gt; 0.0&lt;br /&gt;
-- distance to retract above surface when peck drilling&lt;br /&gt;
  drill_data.PeckRetractGap = retract_gap&lt;br /&gt;
-- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
  drill_data.ProjectToolpath = false&lt;br /&gt;
-- Create object which can be used to automatically select geometry&lt;br /&gt;
  local geometry_selector = GeometrySelector()&lt;br /&gt;
-- if this is true we create 2d toolpaths previews in 2d view,&lt;br /&gt;
-- if false we dont&lt;br /&gt;
  local create_2d_previews = true&lt;br /&gt;
-- if this is true we will display errors and warning to the user&lt;br /&gt;
  local display_warnings = true&lt;br /&gt;
-- Create our toolpath&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  local toolpath_id = toolpath_manager:CreateDrillingToolpath(name, tool, drill_data, pos_data, geometry_selector, &lt;br /&gt;
                                                            create_2d_previews, display_warnings)&lt;br /&gt;
  if toolpath_id == nil then&lt;br /&gt;
    DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
    return false&lt;br /&gt;
  end -- if end&lt;br /&gt;
  return true&lt;br /&gt;
end -- function end&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==V-Carve Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreateVCarveToolpath by Selection===&lt;br /&gt;
Create a V-Carve toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===CreateVCarveToolpath by Layer Name===&lt;br /&gt;
Create a V-Carve toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Fluting Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreateFlutingToolpath by Selection===&lt;br /&gt;
Create a Fluting toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;  function CreateFlutingToolpath(name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
    --[[ ----------------- CreateFlutingToolpath -----------------&lt;br /&gt;
  | Create a flutting toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for toolpath&lt;br /&gt;
  | tool_dia -- diameter of tool to use&lt;br /&gt;
  | tool_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua Ball Nose&amp;quot;, Tool.BALL_NOSE) -- BALL_NOSE, END_MILL, VBit_Angle, THROUGH_DRILL&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * 0.25&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass fluting options&lt;br /&gt;
    local fluting_data = FlutingParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    fluting_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    fluting_data.CutDepth = cut_depth&lt;br /&gt;
    -- type of fluting FULL_LENGTH, RAMP_START or RAMP_START_END&lt;br /&gt;
    fluting_data.FluteType = FlutingParameterData.RAMP_START_END&lt;br /&gt;
    -- type of ramping RAMP_LINEAR, RAMP_SMOOTH&lt;br /&gt;
    fluting_data.RampType = FlutingParameterData.RAMP_LINEAR&lt;br /&gt;
    -- if true use ratio field for controling ramp length else absolute length value&lt;br /&gt;
    fluting_data.UseRampRatio = false&lt;br /&gt;
    -- length of ramp as ratio of flute length(range 0 - 1.0)&lt;br /&gt;
    -- (for start and end - ratio is of half length)&lt;br /&gt;
    fluting_data.RampRatio = 0.2&lt;br /&gt;
    -- length to ramp over - if UseRampRatio == false&lt;br /&gt;
    fluting_data.RampLength = 15&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    fluting_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateFlutingToolpath(name, tool, fluting_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    else&lt;br /&gt;
      return true&lt;br /&gt;
    end -- if end &lt;br /&gt;
&lt;br /&gt;
    end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===CreateFlutingToolpath by Layer Name===&lt;br /&gt;
Create a Fluting toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Profile Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreateProfileToolpath by Selection===&lt;br /&gt;
Create a Profile toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===CreateProfileToolpath by Layer Name===&lt;br /&gt;
Create a Profile toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function CreateProfileToolpath(layer_name, name, start_depth, cut_depth, tool_dia, tool_stepdown, tool_in_mm)&lt;br /&gt;
   -- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot;   .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua End Mill&amp;quot;, Tool.END_MILL) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = tool_dia&lt;br /&gt;
    tool.Stepdown = tool_stepdown&lt;br /&gt;
    tool.Stepover = tool_dia * 0.25&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC ...&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = tool_dia * 0.5 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local profile_data = ProfileParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    profile_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    profile_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut - ProfileParameterData.&lt;br /&gt;
    -- CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION&lt;br /&gt;
    profile_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- side we machine on - ProfileParameterData.&lt;br /&gt;
    -- PROFILE_OUTSIDE, ProfileParameterData.PROFILE_INSIDE or&lt;br /&gt;
    -- ProfileParameterData.PROFILE_ON&lt;br /&gt;
    profile_data.ProfileSide = ProfileParameterData.PROFILE_OUTSIDE&lt;br /&gt;
    -- Allowance to leave on when machining&lt;br /&gt;
    profile_data.Allowance = 0.0&lt;br /&gt;
    -- true to preserve start point positions, false to reorder start&lt;br /&gt;
    -- points to minimise toolpath length&lt;br /&gt;
    profile_data.KeepStartPoints = false&lt;br /&gt;
    -- true if want to create 'square' external corners on toolpath&lt;br /&gt;
    profile_data.CreateSquareCorners = false&lt;br /&gt;
    -- true to perform corner sharpening on internal corners (only with v-bits)&lt;br /&gt;
    profile_data.CornerSharpen = false&lt;br /&gt;
    -- true to use tabs (position of tabs must already have been defined on vectors)&lt;br /&gt;
    profile_data.UseTabs = false&lt;br /&gt;
    -- length for tabs if being used&lt;br /&gt;
    profile_data.TabLength = 5.0&lt;br /&gt;
    -- Thickness for tabs if being used&lt;br /&gt;
    profile_data.TabThickness = 1.0&lt;br /&gt;
    -- if true then create 3d tabs else 2d tabs&lt;br /&gt;
    profile_data.Use3dTabs = true&lt;br /&gt;
    -- if true in Aspire, project toolpath onto composite model&lt;br /&gt;
    profile_data.ProjectToolpath = false&lt;br /&gt;
    -- Create object used to control ramping&lt;br /&gt;
    local ramping_data = RampingData()&lt;br /&gt;
    -- if true we do ramping into toolpath&lt;br /&gt;
    ramping_data.DoRamping = false&lt;br /&gt;
    -- type of ramping to perform RampingData.RAMP_LINEAR , RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
    -- or RampingData.RAMP_SPIRAL&lt;br /&gt;
    ramping_data.RampType = RampingData.RAMP_ZIG_ZAG&lt;br /&gt;
    -- how ramp is contrained - either by angle or distance RampingData.CONSTRAIN_DISTANCE&lt;br /&gt;
    -- or RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
    ramping_data.RampConstraint = RampingData.CONSTRAIN_ANGLE&lt;br /&gt;
    -- if we are constraining ramp by distance, distance to ramp over&lt;br /&gt;
    ramping_data.RampDistance = 100.0&lt;br /&gt;
    -- if we are contraining ramp by angle , angle to ramp in at (in degrees)&lt;br /&gt;
    ramping_data.RampAngle = 25.0&lt;br /&gt;
    -- if we are contraining ramp by angle, max distance to travel before 'zig zaging'&lt;br /&gt;
    -- if zig zaging&lt;br /&gt;
    ramping_data.RampMaxAngleDist = 15&lt;br /&gt;
    -- if true we restrict our ramping to lead in section of toolpath&lt;br /&gt;
    ramping_data.RampOnLeadIn = false&lt;br /&gt;
    -- Create object used to control lead in/out&lt;br /&gt;
    local lead_in_out_data = LeadInOutData()&lt;br /&gt;
    -- if true we create lead ins on profiles (not for profile on)&lt;br /&gt;
    lead_in_out_data.DoLeadIn = false&lt;br /&gt;
    -- if true we create lead outs on profiles (not for profile on)&lt;br /&gt;
    lead_in_out_data.DoLeadOut = false&lt;br /&gt;
    -- type of leads to create LeadInOutData.LINEAR_LEAD or LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
    lead_in_out_data.LeadType = LeadInOutData.CIRCULAR_LEAD&lt;br /&gt;
    -- length of lead to create&lt;br /&gt;
    lead_in_out_data.LeadLength = 10.0&lt;br /&gt;
    -- Angle for linear leads&lt;br /&gt;
    lead_in_out_data.LinearLeadAngle = 45&lt;br /&gt;
    -- Radius for circular arc leads&lt;br /&gt;
    lead_in_out_data.CirularLeadRadius = 5.0&lt;br /&gt;
    -- distance to 'overcut' (travel past start point) when profiling&lt;br /&gt;
    lead_in_out_data.OvercutDistance = 0.0&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreateProfilingToolpath(name, tool, profile_data, ramping_data, lead_in_out_data, pos_data, geometry_selector, create_2d_previews, display_warnings )&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end &lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Prism Toolpaths==&lt;br /&gt;
&lt;br /&gt;
===CreatePrismToolpath by Selection===&lt;br /&gt;
Create a Prism toolpath within the program for the currently selected vectors.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;  function CreatePrismToolpath(name, start_depth, cut_depth, vbit_angle, vbit_dia, vbit_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
  --[[ ------------------- CreatePrismToolpath -------------------&lt;br /&gt;
  |&lt;br /&gt;
  | Create a prism toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
  | vbit_angle -- angle of vbit to use&lt;br /&gt;
  | vbit_dia -- diameter of VBit to use&lt;br /&gt;
  | vbit_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_stepover_percent - percentage stepover for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua VBit&amp;quot;, Tool.VBIT ) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = vbit_dia&lt;br /&gt;
    tool.Stepdown = vbit_stepdown&lt;br /&gt;
    tool.Stepover = vbit_dia * (tool_stepover_percent / 100)&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = vbit_dia * (tool_stepover_percent / 100) * 2 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local prism_data = PrismCarveParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    prism_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    prism_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- or ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
    prism_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- calculate the minimum cut depth to fully form the bevel on the current&lt;br /&gt;
    -- selection with the current tool&lt;br /&gt;
    local min_bevel_depth = prism_data:CalculateMinimumBevelDepth(tool, true)&lt;br /&gt;
    if min_bevel_depth &amp;gt; cut_depth then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;A prism will not be fully formed with a depth of &amp;quot; .. cut_depth .. &amp;quot;\r\n&amp;quot; ..&lt;br /&gt;
                        &amp;quot;A depth of &amp;quot; .. min_bevel_depth .. &amp;quot; is required to fully form the prism&amp;quot;&lt;br /&gt;
                        )&lt;br /&gt;
    end -- if end&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePrismCarvingToolpath(name, tool, prism_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===CreatePrismToolpath by Layer Name===&lt;br /&gt;
Create a Prism toolpath within the program by Layer Name.&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt; function CreatePrismToolpath(layer_name, name, start_depth, cut_depth, vbit_angle, vbit_dia, vbit_stepdown, tool_stepover_percent, tool_in_mm)&lt;br /&gt;
  --[[ ------------------- CreatePrismToolpath -------------------&lt;br /&gt;
  |&lt;br /&gt;
  | Create a prism toolpath within the program for the currently selected vectors&lt;br /&gt;
  | Parameters:&lt;br /&gt;
  | name, -- Name for toolpath&lt;br /&gt;
  | start_depth -- Start depth for toolpath below surface of material&lt;br /&gt;
  | cut_depth -- cut depth for drilling toolpath&lt;br /&gt;
  | vbit_angle -- angle of vbit to use&lt;br /&gt;
  | vbit_dia -- diameter of VBit to use&lt;br /&gt;
  | vbit_stepdown -- stepdown for tool&lt;br /&gt;
  | tool_stepover_percent - percentage stepover for tool&lt;br /&gt;
  | tool_in_mm -- true if tool size and stepdown are in mm&lt;br /&gt;
  |&lt;br /&gt;
  | Return Values:&lt;br /&gt;
  | true if toolpath created OK else false&lt;br /&gt;
  |&lt;br /&gt;
  ]]&lt;br /&gt;
   -- get layer&lt;br /&gt;
    local layer = Milling.job.LayerManager:FindLayerWithName(layer_name)&lt;br /&gt;
    if layer == nil then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No layer found with name = &amp;quot; .. layer_name, &amp;quot; (4601)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
  -- select all closed vectors on the layer&lt;br /&gt;
    if not SelectVectorsOnLayer(layer, selection, true, false, true) then&lt;br /&gt;
      StatusMessage(&amp;quot;Error&amp;quot;, &amp;quot;Pocketing Toolpath&amp;quot;, &amp;quot;No closed vectors found on layer &amp;quot; .. layer_name , &amp;quot;(4602)&amp;quot; .. caller, 165)&lt;br /&gt;
      return false&lt;br /&gt;
    end&lt;br /&gt;
    -- Create tool we will use to machine vectors&lt;br /&gt;
    local tool = Tool(&amp;quot;Lua VBit&amp;quot;, Tool.VBIT ) -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
    tool.InMM = tool_in_mm&lt;br /&gt;
    tool.ToolDia = vbit_dia&lt;br /&gt;
    tool.Stepdown = vbit_stepdown&lt;br /&gt;
    tool.Stepover = vbit_dia * (tool_stepover_percent / 100)&lt;br /&gt;
    tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
    tool.FeedRate = 30&lt;br /&gt;
    tool.PlungeRate = 10&lt;br /&gt;
    tool.SpindleSpeed = 20000&lt;br /&gt;
    tool.ToolNumber = 1&lt;br /&gt;
    tool.VBit_Angle = 90.0 -- used for vbit only&lt;br /&gt;
    tool.ClearStepover = vbit_dia * (tool_stepover_percent / 100) * 2 -- used for vbit only&lt;br /&gt;
    -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
    local pos_data = ToolpathPosData()&lt;br /&gt;
    pos_data:SetHomePosition(0, 0, 1.0)&lt;br /&gt;
    pos_data.SafeZGap = 5.0&lt;br /&gt;
    -- Create object used to pass profile options&lt;br /&gt;
    local prism_data = PrismCarveParameterData()&lt;br /&gt;
    -- start depth for toolpath&lt;br /&gt;
    prism_data.StartDepth = start_depth&lt;br /&gt;
    -- cut depth for toolpath this is depth below start depth&lt;br /&gt;
    prism_data.CutDepth = cut_depth&lt;br /&gt;
    -- direction of cut for offet clearance - ProfileParameterData.CLIMB_DIRECTION or ProfileParameterData.CONVENTIONAL_DIRECTION - NOTE: enum from ProfileParameterData&lt;br /&gt;
    prism_data.CutDirection = ProfileParameterData.CLIMB_DIRECTION&lt;br /&gt;
    -- calculate the minimum cut depth to fully form the bevel on the current&lt;br /&gt;
    -- selection with the current tool&lt;br /&gt;
    local min_bevel_depth = prism_data:CalculateMinimumBevelDepth(tool, true)&lt;br /&gt;
    if min_bevel_depth &amp;gt; cut_depth then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;A prism will not be fully formed with a depth of &amp;quot; .. cut_depth .. &amp;quot;\r\n&amp;quot; ..&lt;br /&gt;
                        &amp;quot;A depth of &amp;quot; .. min_bevel_depth .. &amp;quot; is required to fully form the prism&amp;quot;)&lt;br /&gt;
    end -- if end&lt;br /&gt;
    -- Create object which can be used to automatically select geometry&lt;br /&gt;
    local geometry_selector = GeometrySelector()&lt;br /&gt;
    -- if this is true we create 2d toolpaths previews in 2d view, if false we dont&lt;br /&gt;
    local create_2d_previews = true&lt;br /&gt;
    -- if this is true we will display errors and warning to the user&lt;br /&gt;
    local display_warnings = true&lt;br /&gt;
    -- Create our toolpath&lt;br /&gt;
    local toolpath_manager = ToolpathManager()&lt;br /&gt;
    local toolpath_id = toolpath_manager:CreatePrismCarvingToolpath(name, tool, prism_data, pos_data, geometry_selector, create_2d_previews, display_warnings)&lt;br /&gt;
    if toolpath_id == nil then&lt;br /&gt;
      DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
      return false&lt;br /&gt;
    end -- if end&lt;br /&gt;
    return true&lt;br /&gt;
end -- end function&lt;br /&gt;
-- =====================================================]]&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=ExternalToolpathOptions&amp;diff=1091</id>
		<title>ExternalToolpathOptions</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=ExternalToolpathOptions&amp;diff=1091"/>
		<updated>2024-11-16T17:13:49Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: /* Example Code: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
This object is used to hold the settings for an external toolpath.&lt;br /&gt;
&lt;br /&gt;
==Constructor==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===ExternalToolpathOptions()===&lt;br /&gt;
Create a new object ready to have its parameters set&lt;br /&gt;
&lt;br /&gt;
==Properties==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.CreatePreview===&lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (bool) if true, create preview in 2d view for this toolpath&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.StartDepth===&lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (double) Start depth for toolpath below material surface&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Example Code:====&lt;br /&gt;
 function CreateToolpath(name, vectors, start_depth)&lt;br /&gt;
  -- Create tool we will use to machine vectors&lt;br /&gt;
 local tool = Tool(&amp;quot;Lua End Mill&amp;quot;,&lt;br /&gt;
 Tool.END_MILL -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
 )&lt;br /&gt;
 tool.InMM = true&lt;br /&gt;
 tool.ToolDia = 3.0&lt;br /&gt;
 tool.Stepdown = 2.0&lt;br /&gt;
 tool.Stepover = 1.0&lt;br /&gt;
 tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, -- INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
 tool.FeedRate = 30&lt;br /&gt;
 tool.PlungeRate = 10&lt;br /&gt;
 tool.SpindleSpeed = 20000&lt;br /&gt;
 tool.ToolNumber = 1&lt;br /&gt;
 tool.VBit_Angle = 90.0    -- used for vbit only&lt;br /&gt;
 tool.ClearStepover = 1.0 -- used for vbit only&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
  -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
 local pos_data = ToolpathPosData()&lt;br /&gt;
 pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
 pos_data.SafeZGap = 5.0&lt;br /&gt;
 &lt;br /&gt;
  -- object used to pass data on toolpath settings&lt;br /&gt;
 toolpath_options = ExternalToolpathOptions()&lt;br /&gt;
 toolpath_options.StartDepth = start_depth&lt;br /&gt;
 toolpath_options.CreatePreview = true&lt;br /&gt;
 &lt;br /&gt;
  -- Create our toolpath&lt;br /&gt;
 local toolpath = ExternalToolpath(name,tool, pos_data, toolpath_options, vectors) &lt;br /&gt;
 &lt;br /&gt;
  if toolpath:Error() then&lt;br /&gt;
     DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
     return&lt;br /&gt;
  end&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  success = toolpath_manager:AddExternalToolpath(toolpath)&lt;br /&gt;
  return success&lt;br /&gt;
 end     &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Tool&amp;diff=1090</id>
		<title>Tool</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Tool&amp;diff=1090"/>
		<updated>2024-11-16T17:12:51Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: /* .ToolType */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
The Tool object represents a tool within the program. All the methods for creating toolpaths take one or more Tool objects as arguments. Any of the supported tool types can be accessed from the ToolDatabase as shown in the section describing the ToolDatabase:SelectTool() method. In addition, the most common tool types (BallNose, EndMill, VBit and Drill) can be created programmatically from Lua.&lt;br /&gt;
&lt;br /&gt;
==Constructor==&lt;br /&gt;
&lt;br /&gt;
===Tool( string name, ToolType tool_type)===&lt;br /&gt;
Create a new tool. Only a limited number of tool types are supported for creation from script. To access the full range of tools use the ToolDatabase:SelectTool() method to allow users to select tools from the tool database. Name (string) Name for the too to be created tool_type (integer)Type of tool to create. &lt;br /&gt;
&lt;br /&gt;
::'''''Valid values are:'''''&lt;br /&gt;
:::''Tool.BALL_NOSE''&lt;br /&gt;
:::''Tool.END_MILL''&lt;br /&gt;
:::''Tool.VBit_angle''&lt;br /&gt;
:::''Tool.THROUGH_DRILL''&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' ''If you change ANY parameters or properties on a tool retrieved from an EXISTING toolpath, you MUST call UpdateParameters() after you have finished editing tool properties to flush the changes through to the toolpath.''&lt;br /&gt;
&lt;br /&gt;
==Properties==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.ClearStepover=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:'''(double) Clearance pass stepover for tool (VBits only)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.InMM=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:'''(bool) flag indicating if tool is in mm or inches&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.FeedRate=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:'''(double) Feedrate for tool (see RateUnits for the units)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.Name=== &lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (string) name of tool&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.Notes=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (string) Notes field for tool . (Aspire 4.015 or VCP 7.015 onwards only)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.PlungeRate=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
 &lt;br /&gt;
 '''Returns:''' (double) Feed rate for tool&lt;br /&gt;
&lt;br /&gt;
Note: see RateUnits for the units&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.RateUnits=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (integer) Feed rate units for tool.&lt;br /&gt;
&lt;br /&gt;
::'''''Valid values are:'''''&lt;br /&gt;
:::''Tool.MM_SEC''&lt;br /&gt;
:::''Tool.MM_MIN''&lt;br /&gt;
:::''Tool.METRES_MIN''&lt;br /&gt;
:::''Tool.INCHES_SEC''&lt;br /&gt;
:::''Tool.INCHES_MIN''&lt;br /&gt;
:::''Tool.FEET_MIN''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.RateUnitsText=== &lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
&lt;br /&gt;
'''Returns:''' (string) Feed rate units for tool as a string for display&lt;br /&gt;
'''For Example:'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;quot;mm or sec&amp;quot; or &amp;quot;inch or sec&amp;quot; &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.SpindleSpeed=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
 &lt;br /&gt;
 '''Returns:'''(integer) Spindle speed for tool&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.Stepdown=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:'''(double) Stepdown for tool&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.Stepover=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:'''(double) Stepover for tool&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.ToolDB_Location=== &lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (string) path to tool in tool database&lt;br /&gt;
Note: not including tool name&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.ToolType=== &lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (integer) an integer indicating the type of the tool values are:&lt;br /&gt;
:::''Tool.BALL_NOSE''&lt;br /&gt;
:::''Tool.END_MILL''&lt;br /&gt;
:::''Tool.RADIUSED_END_MILL''&lt;br /&gt;
:::''Tool.VBit_Angle''&lt;br /&gt;
:::''Tool.ENGRAVING''&lt;br /&gt;
:::''Tool.RADIUSED_ENGRAVING''&lt;br /&gt;
:::''Tool.THROUGH_DRILL''&lt;br /&gt;
:::''Tool.FORM_TOOL''&lt;br /&gt;
:::''Tool.DIAMOND_DRAG''&lt;br /&gt;
:::''Tool.RADIUSED_FLAT_ENGRAVING''&lt;br /&gt;
&lt;br /&gt;
===.ToolTypeText=== &lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (string) a string indicating the type of the tool&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.ToolDia=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (double) Diameter of tool&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.ToolNumber=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (integer) Tool number for tool&lt;br /&gt;
&lt;br /&gt;
===.ToolDBId ===&lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (integer) ToolDBId – The Id describing the location in the tool database&lt;br /&gt;
&lt;br /&gt;
===.VBit_Angle=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (double) Included angle for VBit tools&lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
===:ConvertRateUnitsTo( integer new_units)===&lt;br /&gt;
Convert the feed and plunge rates for the tool into the passed units.&lt;br /&gt;
new_units (integer)new units for feed and plunge rate.&lt;br /&gt;
&lt;br /&gt;
::''Valid values are the same as for .RateUnits''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:IsCompatibleFeedRates( Tool tool_to_check)===&lt;br /&gt;
 '''Returns:''' (bool) true if this tool has same feed, plunge and spindles speeds as passed tool. Does not check geometry or cut depths (see: IsCompatibleTool and :IsCompatibleCutDepthss)&lt;br /&gt;
&lt;br /&gt;
::''tool_to_check (Tool) tool we check for compatibility''&lt;br /&gt;
&lt;br /&gt;
===:IsCompatibleTool( Tool tool_to_check)===&lt;br /&gt;
 '''Returns:''' (bool) true if this tool is compatible (same type and geometry) as passed tool. Does not check cut depths or feed rates (see :IsCompatibleCutDepths and :IsCompatibleFeedRates for this data)&lt;br /&gt;
&lt;br /&gt;
::''tool_to_check (Tool) tool we check for compatibility''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:IsCompatibleCutDepths( Tool tool_to_check)===&lt;br /&gt;
 '''Returns:''' (bool) true if this tool is has same cut depths as passed tool. Does not check geometry or feed rates&lt;br /&gt;
(see: IsCompatibleTool and:IsCompatibleFeedRates)&lt;br /&gt;
&lt;br /&gt;
::''Tool_to_check (Tool) tool we check for compatibility''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:FlatRadius( bool in_mm)===&lt;br /&gt;
Retrieve the flat radius for tools flat tools otherwise returns zero.&lt;br /&gt;
&lt;br /&gt;
::''in_mm (bool) If true, return the tip radius in millimeters''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:GetBool( string parameter_name, bool default_value)===&lt;br /&gt;
Retrieve a Boolean flag (true or false) with the passed name, if no value with passed name returns the passed default value. (Aspire 4.015 or VCP 7.015 onwards only)&lt;br /&gt;
&lt;br /&gt;
::''parameter_name (string) the name of the parameter ''&lt;br /&gt;
::''default_value(bool) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:GetDouble( string parameter_name, double default_value,)===&lt;br /&gt;
Retrieve a double with the passed name, if no value with passed name returns passed default value. (Aspire 4.015 or VCP 7.015 onwards only)&lt;br /&gt;
&lt;br /&gt;
::''parameter_name (string) the name of the parameter''&lt;br /&gt;
::''default_value(double) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
===:GetInt( string parameter_name, integer default_value)===&lt;br /&gt;
Retrieve an integer with the passed name, if no value with passed name returns the passed default value. (Aspire 4.015 or VCP 7.015 onwards only)&lt;br /&gt;
&lt;br /&gt;
::''parameter_name (string) the name of the parameter &lt;br /&gt;
::''value (integer) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:ParameterExists( string parameter_name, utParameterType type)===&lt;br /&gt;
 '''Returns:''' (bool) true if there is an existing parameter with passed name and type. (Aspire 4.015 or VCP 7.015 onwards only)&lt;br /&gt;
&lt;br /&gt;
::''parameter_name (string) the name of the parameter ''&lt;br /&gt;
::''type (utParameterType) the type of parameter''&lt;br /&gt;
&lt;br /&gt;
===:SetBool(string parameter_name, bool value)===&lt;br /&gt;
Store a Boolean flag (true or false) with the passed name and value. (Aspire 4.015 or VCP 7.015 onwards only)&lt;br /&gt;
&lt;br /&gt;
::''parameter_name (string) the name which will be used to store and retrieve the value''&lt;br /&gt;
::''value (bool) the value which will be stored in the parameter list''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:SetDouble(string parameter_name, double value)===&lt;br /&gt;
Store a double with the passed name and value. (Aspire 4.015 or VCP 7.015 onwards only)&lt;br /&gt;
&lt;br /&gt;
::''parameter_name (string) the name which will be used to store and retrieve the value''&lt;br /&gt;
::''value(double) the value which will be stored in the parameter list''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:SetInt(string parameter_name, integer value)===&lt;br /&gt;
Store an integer with the passed name and value. (Aspire 4.015 or VCP 7.015 onwards only)&lt;br /&gt;
&lt;br /&gt;
::''parameter_name (string) the name which will be used to store and retrieve the value''&lt;br /&gt;
::''value (integer) the value which will be stored in the parameter list''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:SetString(string parameter_name, string value)===&lt;br /&gt;
Store a string with the passed name and value. (Aspire 4.015 or VCP 7.015 onwards only)&lt;br /&gt;
&lt;br /&gt;
::''parameter_name (string) the name which will be used to store and retrieve the value''&lt;br /&gt;
::''value (string) the value which will be stored in the parameter list''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:TipRadius( bool in_mm)===&lt;br /&gt;
Retrieve the tip radius for tools of type Tool.RADIUSED_END_MILL or Tool.RADIUSED_ENGRAVING otherwise return zero.&lt;br /&gt;
&lt;br /&gt;
::''in_mm (bool) If true, return the tip radius in millimeters''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:UpdateParameters()===&lt;br /&gt;
If editing a tool on an existing toolpath update feed rates and other parameters set on the tool to new values.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' ''You '''MUST''' call this method if you have edited any parameters on an existing tool, otherwise your changes will be ignored!''&lt;br /&gt;
&lt;br /&gt;
'''For Example:'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; -- Create tool we will use to machine vectors&lt;br /&gt;
   local tool = Tool(&lt;br /&gt;
                     &amp;quot;Lua End Mill&amp;quot;,&lt;br /&gt;
                      Tool.END_MILL      -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
                    )&lt;br /&gt;
   tool.InMM = tool_in_mm&lt;br /&gt;
   tool.ToolDia = tool_dia&lt;br /&gt;
   tool.Stepdown = tool_stepdown&lt;br /&gt;
   tool.Stepover = tool_dia * 0.25&lt;br /&gt;
   tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN,&lt;br /&gt;
                                -- INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
   tool.FeedRate = 30&lt;br /&gt;
   tool.PlungeRate = 10&lt;br /&gt;
   tool.SpindleSpeed = 20000&lt;br /&gt;
   tool.ToolNumber = 1&lt;br /&gt;
   tool.VBitAngle = 90.0                    -- used for vbit only&lt;br /&gt;
   tool.ClearStepover = tool_dia * 0.5      -- used for vbit only&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 10.0, published August 21, 2019. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Tool&amp;diff=1089</id>
		<title>Tool</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Tool&amp;diff=1089"/>
		<updated>2024-11-16T16:57:17Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
The Tool object represents a tool within the program. All the methods for creating toolpaths take one or more Tool objects as arguments. Any of the supported tool types can be accessed from the ToolDatabase as shown in the section describing the ToolDatabase:SelectTool() method. In addition, the most common tool types (BallNose, EndMill, VBit and Drill) can be created programmatically from Lua.&lt;br /&gt;
&lt;br /&gt;
==Constructor==&lt;br /&gt;
&lt;br /&gt;
===Tool( string name, ToolType tool_type)===&lt;br /&gt;
Create a new tool. Only a limited number of tool types are supported for creation from script. To access the full range of tools use the ToolDatabase:SelectTool() method to allow users to select tools from the tool database. Name (string) Name for the too to be created tool_type (integer)Type of tool to create. &lt;br /&gt;
&lt;br /&gt;
::'''''Valid values are:'''''&lt;br /&gt;
:::''Tool.BALL_NOSE''&lt;br /&gt;
:::''Tool.END_MILL''&lt;br /&gt;
:::''Tool.VBit_angle''&lt;br /&gt;
:::''Tool.THROUGH_DRILL''&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' ''If you change ANY parameters or properties on a tool retrieved from an EXISTING toolpath, you MUST call UpdateParameters() after you have finished editing tool properties to flush the changes through to the toolpath.''&lt;br /&gt;
&lt;br /&gt;
==Properties==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.ClearStepover=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:'''(double) Clearance pass stepover for tool (VBits only)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.InMM=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:'''(bool) flag indicating if tool is in mm or inches&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.FeedRate=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:'''(double) Feedrate for tool (see RateUnits for the units)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.Name=== &lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (string) name of tool&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.Notes=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (string) Notes field for tool . (Aspire 4.015 or VCP 7.015 onwards only)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.PlungeRate=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
 &lt;br /&gt;
 '''Returns:''' (double) Feed rate for tool&lt;br /&gt;
&lt;br /&gt;
Note: see RateUnits for the units&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.RateUnits=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (integer) Feed rate units for tool.&lt;br /&gt;
&lt;br /&gt;
::'''''Valid values are:'''''&lt;br /&gt;
:::''Tool.MM_SEC''&lt;br /&gt;
:::''Tool.MM_MIN''&lt;br /&gt;
:::''Tool.METRES_MIN''&lt;br /&gt;
:::''Tool.INCHES_SEC''&lt;br /&gt;
:::''Tool.INCHES_MIN''&lt;br /&gt;
:::''Tool.FEET_MIN''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.RateUnitsText=== &lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
&lt;br /&gt;
'''Returns:''' (string) Feed rate units for tool as a string for display&lt;br /&gt;
'''For Example:'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&amp;quot;mm or sec&amp;quot; or &amp;quot;inch or sec&amp;quot; &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.SpindleSpeed=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
 &lt;br /&gt;
 '''Returns:'''(integer) Spindle speed for tool&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.Stepdown=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:'''(double) Stepdown for tool&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.Stepover=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:'''(double) Stepover for tool&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.ToolDB_Location=== &lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (string) path to tool in tool database&lt;br /&gt;
Note: not including tool name&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.ToolType=== &lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (integer) an integer indicating the type of the tool values are:&lt;br /&gt;
:::''Tool.BALL_NOSE''&lt;br /&gt;
:::''Tool.END_MILL''&lt;br /&gt;
:::''Tool.RADIUSED_END_MILL''&lt;br /&gt;
:::''Tool.VBIT''&lt;br /&gt;
:::''Tool.ENGRAVING''&lt;br /&gt;
:::''Tool.RADIUSED_ENGRAVING''&lt;br /&gt;
:::''Tool.THROUGH_DRILL''&lt;br /&gt;
:::''Tool.FORM_TOOL''&lt;br /&gt;
:::''Tool.DIAMOND_DRAG''&lt;br /&gt;
:::''Tool.RADIUSED_FLAT_ENGRAVING''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.ToolTypeText=== &lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (string) a string indicating the type of the tool&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.ToolDia=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (double) Diameter of tool&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.ToolNumber=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (integer) Tool number for tool&lt;br /&gt;
&lt;br /&gt;
===.ToolDBId ===&lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (integer) ToolDBId – The Id describing the location in the tool database&lt;br /&gt;
&lt;br /&gt;
===.VBit_Angle=== &lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (double) Included angle for VBit tools&lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
===:ConvertRateUnitsTo( integer new_units)===&lt;br /&gt;
Convert the feed and plunge rates for the tool into the passed units.&lt;br /&gt;
new_units (integer)new units for feed and plunge rate.&lt;br /&gt;
&lt;br /&gt;
::''Valid values are the same as for .RateUnits''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:IsCompatibleFeedRates( Tool tool_to_check)===&lt;br /&gt;
 '''Returns:''' (bool) true if this tool has same feed, plunge and spindles speeds as passed tool. Does not check geometry or cut depths (see: IsCompatibleTool and :IsCompatibleCutDepthss)&lt;br /&gt;
&lt;br /&gt;
::''tool_to_check (Tool) tool we check for compatibility''&lt;br /&gt;
&lt;br /&gt;
===:IsCompatibleTool( Tool tool_to_check)===&lt;br /&gt;
 '''Returns:''' (bool) true if this tool is compatible (same type and geometry) as passed tool. Does not check cut depths or feed rates (see :IsCompatibleCutDepths and :IsCompatibleFeedRates for this data)&lt;br /&gt;
&lt;br /&gt;
::''tool_to_check (Tool) tool we check for compatibility''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:IsCompatibleCutDepths( Tool tool_to_check)===&lt;br /&gt;
 '''Returns:''' (bool) true if this tool is has same cut depths as passed tool. Does not check geometry or feed rates&lt;br /&gt;
(see: IsCompatibleTool and:IsCompatibleFeedRates)&lt;br /&gt;
&lt;br /&gt;
::''Tool_to_check (Tool) tool we check for compatibility''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:FlatRadius( bool in_mm)===&lt;br /&gt;
Retrieve the flat radius for tools flat tools otherwise returns zero.&lt;br /&gt;
&lt;br /&gt;
::''in_mm (bool) If true, return the tip radius in millimeters''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:GetBool( string parameter_name, bool default_value)===&lt;br /&gt;
Retrieve a Boolean flag (true or false) with the passed name, if no value with passed name returns the passed default value. (Aspire 4.015 or VCP 7.015 onwards only)&lt;br /&gt;
&lt;br /&gt;
::''parameter_name (string) the name of the parameter ''&lt;br /&gt;
::''default_value(bool) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:GetDouble( string parameter_name, double default_value,)===&lt;br /&gt;
Retrieve a double with the passed name, if no value with passed name returns passed default value. (Aspire 4.015 or VCP 7.015 onwards only)&lt;br /&gt;
&lt;br /&gt;
::''parameter_name (string) the name of the parameter''&lt;br /&gt;
::''default_value(double) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
===:GetInt( string parameter_name, integer default_value)===&lt;br /&gt;
Retrieve an integer with the passed name, if no value with passed name returns the passed default value. (Aspire 4.015 or VCP 7.015 onwards only)&lt;br /&gt;
&lt;br /&gt;
::''parameter_name (string) the name of the parameter &lt;br /&gt;
::''value (integer) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:ParameterExists( string parameter_name, utParameterType type)===&lt;br /&gt;
 '''Returns:''' (bool) true if there is an existing parameter with passed name and type. (Aspire 4.015 or VCP 7.015 onwards only)&lt;br /&gt;
&lt;br /&gt;
::''parameter_name (string) the name of the parameter ''&lt;br /&gt;
::''type (utParameterType) the type of parameter''&lt;br /&gt;
&lt;br /&gt;
===:SetBool(string parameter_name, bool value)===&lt;br /&gt;
Store a Boolean flag (true or false) with the passed name and value. (Aspire 4.015 or VCP 7.015 onwards only)&lt;br /&gt;
&lt;br /&gt;
::''parameter_name (string) the name which will be used to store and retrieve the value''&lt;br /&gt;
::''value (bool) the value which will be stored in the parameter list''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:SetDouble(string parameter_name, double value)===&lt;br /&gt;
Store a double with the passed name and value. (Aspire 4.015 or VCP 7.015 onwards only)&lt;br /&gt;
&lt;br /&gt;
::''parameter_name (string) the name which will be used to store and retrieve the value''&lt;br /&gt;
::''value(double) the value which will be stored in the parameter list''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:SetInt(string parameter_name, integer value)===&lt;br /&gt;
Store an integer with the passed name and value. (Aspire 4.015 or VCP 7.015 onwards only)&lt;br /&gt;
&lt;br /&gt;
::''parameter_name (string) the name which will be used to store and retrieve the value''&lt;br /&gt;
::''value (integer) the value which will be stored in the parameter list''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:SetString(string parameter_name, string value)===&lt;br /&gt;
Store a string with the passed name and value. (Aspire 4.015 or VCP 7.015 onwards only)&lt;br /&gt;
&lt;br /&gt;
::''parameter_name (string) the name which will be used to store and retrieve the value''&lt;br /&gt;
::''value (string) the value which will be stored in the parameter list''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:TipRadius( bool in_mm)===&lt;br /&gt;
Retrieve the tip radius for tools of type Tool.RADIUSED_END_MILL or Tool.RADIUSED_ENGRAVING otherwise return zero.&lt;br /&gt;
&lt;br /&gt;
::''in_mm (bool) If true, return the tip radius in millimeters''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:UpdateParameters()===&lt;br /&gt;
If editing a tool on an existing toolpath update feed rates and other parameters set on the tool to new values.&lt;br /&gt;
&lt;br /&gt;
'''NOTE:''' ''You '''MUST''' call this method if you have edited any parameters on an existing tool, otherwise your changes will be ignored!''&lt;br /&gt;
&lt;br /&gt;
'''For Example:'''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; -- Create tool we will use to machine vectors&lt;br /&gt;
   local tool = Tool(&lt;br /&gt;
                     &amp;quot;Lua End Mill&amp;quot;,&lt;br /&gt;
                      Tool.END_MILL      -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
                    )&lt;br /&gt;
   tool.InMM = tool_in_mm&lt;br /&gt;
   tool.ToolDia = tool_dia&lt;br /&gt;
   tool.Stepdown = tool_stepdown&lt;br /&gt;
   tool.Stepover = tool_dia * 0.25&lt;br /&gt;
   tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN,&lt;br /&gt;
                                -- INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
   tool.FeedRate = 30&lt;br /&gt;
   tool.PlungeRate = 10&lt;br /&gt;
   tool.SpindleSpeed = 20000&lt;br /&gt;
   tool.ToolNumber = 1&lt;br /&gt;
   tool.VBitAngle = 90.0                    -- used for vbit only&lt;br /&gt;
   tool.ClearStepover = tool_dia * 0.5      -- used for vbit only&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 10.0, published August 21, 2019. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=ExternalToolpathOptions&amp;diff=1088</id>
		<title>ExternalToolpathOptions</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=ExternalToolpathOptions&amp;diff=1088"/>
		<updated>2024-11-16T16:55:23Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: /* Example Code: */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
This object is used to hold the settings for an external toolpath.&lt;br /&gt;
&lt;br /&gt;
==Constructor==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===ExternalToolpathOptions()===&lt;br /&gt;
Create a new object ready to have its parameters set&lt;br /&gt;
&lt;br /&gt;
==Properties==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.CreatePreview===&lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (bool) if true, create preview in 2d view for this toolpath&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===.StartDepth===&lt;br /&gt;
'''Interaction:''' Read and Write&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (double) Start depth for toolpath below material surface&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Example Code:====&lt;br /&gt;
 function CreateToolpath(name, vectors, start_depth)&lt;br /&gt;
  -- Create tool we will use to machine vectors&lt;br /&gt;
 local tool = Tool(&amp;quot;Lua End Mill&amp;quot;,&lt;br /&gt;
 Tool.END_MILL -- BALL_NOSE, END_MILL, VBIT&lt;br /&gt;
 )&lt;br /&gt;
 tool.InMM = true&lt;br /&gt;
 tool.ToolDia = 3.0&lt;br /&gt;
 tool.Stepdown = 2.0&lt;br /&gt;
 tool.Stepover = 1.0&lt;br /&gt;
 tool.RateUnits = Tool.MM_SEC -- MM_SEC, MM_MIN, METRES_MIN, -- INCHES_SEC, INCHES_MIN, FEET_MIN&lt;br /&gt;
 tool.FeedRate = 30&lt;br /&gt;
 tool.PlungeRate = 10&lt;br /&gt;
 tool.SpindleSpeed = 20000&lt;br /&gt;
 tool.ToolNumber = 1&lt;br /&gt;
 tool.VBit_angle = 90.0    -- used for vbit only&lt;br /&gt;
 tool.ClearStepover = 1.0 -- used for vbit only&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
  -- Create object used to set home position and safez gap above material surface&lt;br /&gt;
 local pos_data = ToolpathPosData()&lt;br /&gt;
 pos_data:SetHomePosition(0, 0, 5.0)&lt;br /&gt;
 pos_data.SafeZGap = 5.0&lt;br /&gt;
 &lt;br /&gt;
  -- object used to pass data on toolpath settings&lt;br /&gt;
 toolpath_options = ExternalToolpathOptions()&lt;br /&gt;
 toolpath_options.StartDepth = start_depth&lt;br /&gt;
 toolpath_options.CreatePreview = true&lt;br /&gt;
 &lt;br /&gt;
  -- Create our toolpath&lt;br /&gt;
 local toolpath = ExternalToolpath(name,tool, pos_data, toolpath_options, vectors) &lt;br /&gt;
 &lt;br /&gt;
  if toolpath:Error() then&lt;br /&gt;
     DisplayMessageBox(&amp;quot;Error creating toolpath&amp;quot;)&lt;br /&gt;
     return&lt;br /&gt;
  end&lt;br /&gt;
  local toolpath_manager = ToolpathManager()&lt;br /&gt;
  success = toolpath_manager:AddExternalToolpath(toolpath)&lt;br /&gt;
  return success&lt;br /&gt;
 end     &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Toolpaths]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Registry&amp;diff=1087</id>
		<title>Registry</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Registry&amp;diff=1087"/>
		<updated>2024-10-11T21:49:51Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: /* :SetInt(string parameter_name, integer value) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=User Interface]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
This object is used to save and load values from the registry. This allows gadgets to persist settings across different runs of the gadget. All the values are stored under a single &amp;lt;q&amp;gt;section&amp;lt;/q&amp;gt; in the registry, so it is important that each gadget uses a unique name for its section. The sections are unique to each product, so the same gadget run under both Aspire and VCarve Pro will store their settings in different areas.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Constructor==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Registry(string section_name)===&lt;br /&gt;
Create a new object used for reading and writing values&lt;br /&gt;
Section_name (string) Name of section in registry to store all values under&lt;br /&gt;
::''local dir_reader = DirectoryReader(&amp;quot;MyGadget&amp;quot;)''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:BoolExists(string parameter_name)===&lt;br /&gt;
 '''Returns:''' (bool) true if there is an existing bool parameter with passed name&lt;br /&gt;
&lt;br /&gt;
===:GetBool(string parameter_name, bool default_value)===&lt;br /&gt;
Retrieve a bool with the passed name, if no value with passed name returns the passed default value&lt;br /&gt;
::''parameter_name (string) the name of the parameter ''&lt;br /&gt;
::''value (integer) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
===:SetBool(string parameter_name, bool default_value)===&lt;br /&gt;
Retrieve a Boolean flag (true or false) with the passed name, if no value with passed name returns the passed default value&lt;br /&gt;
::''parameter_name (string) the name of the parameter''&lt;br /&gt;
::''default_value(bool) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:DoubleExists(string parameter_name)===&lt;br /&gt;
 '''Returns:''' (bool) true if there is an existing double parameter with passed name&lt;br /&gt;
&lt;br /&gt;
===:GetDouble(string parameter_name, double default_value)===&lt;br /&gt;
Retrieve a double with the passed name, if no value with passed name returns the passed default value&lt;br /&gt;
::''parameter_name (string) the name of the parameter default_value(double) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
===:SetDouble(string parameter_name, double value)===&lt;br /&gt;
Store a double with the passed name and value&lt;br /&gt;
::''parameter_name (string) the name which will be used to store and retrieve the value''&lt;br /&gt;
::''value(double) the value which will be stored in the parameter list''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:IntExists(string parameter_name)===&lt;br /&gt;
 '''Returns:''' (bool) true if there is an existing int parameter with passed name&lt;br /&gt;
&lt;br /&gt;
===:GetInt(string parameter_name, integer default_value)===&lt;br /&gt;
Retrieve an integer with the passed name, if no value with passed name returns the passed default value&lt;br /&gt;
::''parameter_name (string) the name of the parameter''&lt;br /&gt;
::''value (integer) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
'''''Sample Code:'''''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; &lt;br /&gt;
  JimAndI.Count = RegistryRead:GetInt(&amp;quot;JimAndI.Count&amp;quot;, 2)&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===:SetInt(string parameter_name, integer value)===&lt;br /&gt;
Store an integer with the passed name and value&lt;br /&gt;
::''parameter_name (string) the name which will be used to store and retrieve the value''&lt;br /&gt;
::''value (integer) the value which will be stored in the parameter list''&lt;br /&gt;
&lt;br /&gt;
'''''Sample Code:'''''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; &lt;br /&gt;
  RegistryWrite:SetInt(&amp;quot;JimAndI.Count&amp;quot;, JimAndI.Count)&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===:StringExists(string parameter_name)===&lt;br /&gt;
 '''Returns:''' (bool) true if there is an existing string parameter with passed name&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:GetString(string parameter_name, string value)===&lt;br /&gt;
Retrieve a string with the passed name , if no value with passed name returns the  passed default value&lt;br /&gt;
::''parameter_name (string) the name of the parameter''&lt;br /&gt;
::''value (string) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:SetString(string parameter_name, string value)===&lt;br /&gt;
Store a string with the passed name and value&lt;br /&gt;
::''parameter_name (string) the name which will be used to store and retrieve the value''&lt;br /&gt;
::''value (string) the value which will be stored in the parameter list''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''Sample Code:'''''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function ReadRegistry()  -- Read from Registry values&lt;br /&gt;
  local RegistryRead = Registry(&amp;quot;MyProgram&amp;quot;)&lt;br /&gt;
  if not(RegistryRead:StringExists(&amp;quot;CodeBy&amp;quot;)) then&lt;br /&gt;
      LoadRegistry()&lt;br /&gt;
  end&lt;br /&gt;
  CodeBy = RegistryRead:GetString(&amp;quot;CodeBy&amp;quot;, &amp;quot;James Anderson&amp;quot;)&lt;br /&gt;
  ProgramName = RegistryRead:GetString(&amp;quot;ProgramName&amp;quot;, &amp;quot;Easy Dovetail Maker&amp;quot;)&lt;br /&gt;
  ProgramVersion = RegistryRead:GetString(&amp;quot;ProgramVersion&amp;quot;, Dovetail.ProgramVersion)&lt;br /&gt;
  ProgramYear = RegistryRead:GetString(&amp;quot;ProgramYear&amp;quot;, &amp;quot;2020&amp;quot;)&lt;br /&gt;
 end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=User Interface]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 10.0, published August 21, 2019. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Registry&amp;diff=1086</id>
		<title>Registry</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Registry&amp;diff=1086"/>
		<updated>2024-10-11T21:48:38Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: /* :GetInt(string parameter_name, integer default_value) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=User Interface]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
This object is used to save and load values from the registry. This allows gadgets to persist settings across different runs of the gadget. All the values are stored under a single &amp;lt;q&amp;gt;section&amp;lt;/q&amp;gt; in the registry, so it is important that each gadget uses a unique name for its section. The sections are unique to each product, so the same gadget run under both Aspire and VCarve Pro will store their settings in different areas.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Constructor==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Registry(string section_name)===&lt;br /&gt;
Create a new object used for reading and writing values&lt;br /&gt;
Section_name (string) Name of section in registry to store all values under&lt;br /&gt;
::''local dir_reader = DirectoryReader(&amp;quot;MyGadget&amp;quot;)''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:BoolExists(string parameter_name)===&lt;br /&gt;
 '''Returns:''' (bool) true if there is an existing bool parameter with passed name&lt;br /&gt;
&lt;br /&gt;
===:GetBool(string parameter_name, bool default_value)===&lt;br /&gt;
Retrieve a bool with the passed name, if no value with passed name returns the passed default value&lt;br /&gt;
::''parameter_name (string) the name of the parameter ''&lt;br /&gt;
::''value (integer) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
===:SetBool(string parameter_name, bool default_value)===&lt;br /&gt;
Retrieve a Boolean flag (true or false) with the passed name, if no value with passed name returns the passed default value&lt;br /&gt;
::''parameter_name (string) the name of the parameter''&lt;br /&gt;
::''default_value(bool) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:DoubleExists(string parameter_name)===&lt;br /&gt;
 '''Returns:''' (bool) true if there is an existing double parameter with passed name&lt;br /&gt;
&lt;br /&gt;
===:GetDouble(string parameter_name, double default_value)===&lt;br /&gt;
Retrieve a double with the passed name, if no value with passed name returns the passed default value&lt;br /&gt;
::''parameter_name (string) the name of the parameter default_value(double) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
===:SetDouble(string parameter_name, double value)===&lt;br /&gt;
Store a double with the passed name and value&lt;br /&gt;
::''parameter_name (string) the name which will be used to store and retrieve the value''&lt;br /&gt;
::''value(double) the value which will be stored in the parameter list''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:IntExists(string parameter_name)===&lt;br /&gt;
 '''Returns:''' (bool) true if there is an existing int parameter with passed name&lt;br /&gt;
&lt;br /&gt;
===:GetInt(string parameter_name, integer default_value)===&lt;br /&gt;
Retrieve an integer with the passed name, if no value with passed name returns the passed default value&lt;br /&gt;
::''parameter_name (string) the name of the parameter''&lt;br /&gt;
::''value (integer) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
'''''Sample Code:'''''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; &lt;br /&gt;
  JimAndI.Count = RegistryRead:GetInt(&amp;quot;JimAndI.Count&amp;quot;, 2)&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===:SetInt(string parameter_name, integer value)===&lt;br /&gt;
Store an integer with the passed name and value&lt;br /&gt;
::''parameter_name (string) the name which will be used to store and retrieve the value''&lt;br /&gt;
::''value (integer) the value which will be stored in the parameter list''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:StringExists(string parameter_name)===&lt;br /&gt;
 '''Returns:''' (bool) true if there is an existing string parameter with passed name&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:GetString(string parameter_name, string value)===&lt;br /&gt;
Retrieve a string with the passed name , if no value with passed name returns the  passed default value&lt;br /&gt;
::''parameter_name (string) the name of the parameter''&lt;br /&gt;
::''value (string) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:SetString(string parameter_name, string value)===&lt;br /&gt;
Store a string with the passed name and value&lt;br /&gt;
::''parameter_name (string) the name which will be used to store and retrieve the value''&lt;br /&gt;
::''value (string) the value which will be stored in the parameter list''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''Sample Code:'''''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function ReadRegistry()  -- Read from Registry values&lt;br /&gt;
  local RegistryRead = Registry(&amp;quot;MyProgram&amp;quot;)&lt;br /&gt;
  if not(RegistryRead:StringExists(&amp;quot;CodeBy&amp;quot;)) then&lt;br /&gt;
      LoadRegistry()&lt;br /&gt;
  end&lt;br /&gt;
  CodeBy = RegistryRead:GetString(&amp;quot;CodeBy&amp;quot;, &amp;quot;James Anderson&amp;quot;)&lt;br /&gt;
  ProgramName = RegistryRead:GetString(&amp;quot;ProgramName&amp;quot;, &amp;quot;Easy Dovetail Maker&amp;quot;)&lt;br /&gt;
  ProgramVersion = RegistryRead:GetString(&amp;quot;ProgramVersion&amp;quot;, Dovetail.ProgramVersion)&lt;br /&gt;
  ProgramYear = RegistryRead:GetString(&amp;quot;ProgramYear&amp;quot;, &amp;quot;2020&amp;quot;)&lt;br /&gt;
 end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=User Interface]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 10.0, published August 21, 2019. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Registry&amp;diff=1085</id>
		<title>Registry</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Registry&amp;diff=1085"/>
		<updated>2024-10-11T21:48:09Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: /* :GetInt(string parameter_name, integer default_value) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=User Interface]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
This object is used to save and load values from the registry. This allows gadgets to persist settings across different runs of the gadget. All the values are stored under a single &amp;lt;q&amp;gt;section&amp;lt;/q&amp;gt; in the registry, so it is important that each gadget uses a unique name for its section. The sections are unique to each product, so the same gadget run under both Aspire and VCarve Pro will store their settings in different areas.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Constructor==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Registry(string section_name)===&lt;br /&gt;
Create a new object used for reading and writing values&lt;br /&gt;
Section_name (string) Name of section in registry to store all values under&lt;br /&gt;
::''local dir_reader = DirectoryReader(&amp;quot;MyGadget&amp;quot;)''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:BoolExists(string parameter_name)===&lt;br /&gt;
 '''Returns:''' (bool) true if there is an existing bool parameter with passed name&lt;br /&gt;
&lt;br /&gt;
===:GetBool(string parameter_name, bool default_value)===&lt;br /&gt;
Retrieve a bool with the passed name, if no value with passed name returns the passed default value&lt;br /&gt;
::''parameter_name (string) the name of the parameter ''&lt;br /&gt;
::''value (integer) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
===:SetBool(string parameter_name, bool default_value)===&lt;br /&gt;
Retrieve a Boolean flag (true or false) with the passed name, if no value with passed name returns the passed default value&lt;br /&gt;
::''parameter_name (string) the name of the parameter''&lt;br /&gt;
::''default_value(bool) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:DoubleExists(string parameter_name)===&lt;br /&gt;
 '''Returns:''' (bool) true if there is an existing double parameter with passed name&lt;br /&gt;
&lt;br /&gt;
===:GetDouble(string parameter_name, double default_value)===&lt;br /&gt;
Retrieve a double with the passed name, if no value with passed name returns the passed default value&lt;br /&gt;
::''parameter_name (string) the name of the parameter default_value(double) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
===:SetDouble(string parameter_name, double value)===&lt;br /&gt;
Store a double with the passed name and value&lt;br /&gt;
::''parameter_name (string) the name which will be used to store and retrieve the value''&lt;br /&gt;
::''value(double) the value which will be stored in the parameter list''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:IntExists(string parameter_name)===&lt;br /&gt;
 '''Returns:''' (bool) true if there is an existing int parameter with passed name&lt;br /&gt;
&lt;br /&gt;
===:GetInt(string parameter_name, integer default_value)===&lt;br /&gt;
Retrieve an integer with the passed name, if no value with passed name returns the passed default value&lt;br /&gt;
::''parameter_name (string) the name of the parameter''&lt;br /&gt;
::''value (integer) the value which will be returned if there is no existing value stored''&lt;br /&gt;
 '''''Sample Code:'''''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; &lt;br /&gt;
  JimAndI.Count = RegistryRead:GetInt(&amp;quot;JimAndI.Count&amp;quot;, 2)&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===:SetInt(string parameter_name, integer value)===&lt;br /&gt;
Store an integer with the passed name and value&lt;br /&gt;
::''parameter_name (string) the name which will be used to store and retrieve the value''&lt;br /&gt;
::''value (integer) the value which will be stored in the parameter list''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:StringExists(string parameter_name)===&lt;br /&gt;
 '''Returns:''' (bool) true if there is an existing string parameter with passed name&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:GetString(string parameter_name, string value)===&lt;br /&gt;
Retrieve a string with the passed name , if no value with passed name returns the  passed default value&lt;br /&gt;
::''parameter_name (string) the name of the parameter''&lt;br /&gt;
::''value (string) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:SetString(string parameter_name, string value)===&lt;br /&gt;
Store a string with the passed name and value&lt;br /&gt;
::''parameter_name (string) the name which will be used to store and retrieve the value''&lt;br /&gt;
::''value (string) the value which will be stored in the parameter list''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''Sample Code:'''''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function ReadRegistry()  -- Read from Registry values&lt;br /&gt;
  local RegistryRead = Registry(&amp;quot;MyProgram&amp;quot;)&lt;br /&gt;
  if not(RegistryRead:StringExists(&amp;quot;CodeBy&amp;quot;)) then&lt;br /&gt;
      LoadRegistry()&lt;br /&gt;
  end&lt;br /&gt;
  CodeBy = RegistryRead:GetString(&amp;quot;CodeBy&amp;quot;, &amp;quot;James Anderson&amp;quot;)&lt;br /&gt;
  ProgramName = RegistryRead:GetString(&amp;quot;ProgramName&amp;quot;, &amp;quot;Easy Dovetail Maker&amp;quot;)&lt;br /&gt;
  ProgramVersion = RegistryRead:GetString(&amp;quot;ProgramVersion&amp;quot;, Dovetail.ProgramVersion)&lt;br /&gt;
  ProgramYear = RegistryRead:GetString(&amp;quot;ProgramYear&amp;quot;, &amp;quot;2020&amp;quot;)&lt;br /&gt;
 end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=User Interface]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 10.0, published August 21, 2019. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Registry&amp;diff=1084</id>
		<title>Registry</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Registry&amp;diff=1084"/>
		<updated>2024-10-11T21:47:21Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: /* :GetInt(string parameter_name, integer default_value) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=User Interface]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
This object is used to save and load values from the registry. This allows gadgets to persist settings across different runs of the gadget. All the values are stored under a single &amp;lt;q&amp;gt;section&amp;lt;/q&amp;gt; in the registry, so it is important that each gadget uses a unique name for its section. The sections are unique to each product, so the same gadget run under both Aspire and VCarve Pro will store their settings in different areas.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Constructor==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Registry(string section_name)===&lt;br /&gt;
Create a new object used for reading and writing values&lt;br /&gt;
Section_name (string) Name of section in registry to store all values under&lt;br /&gt;
::''local dir_reader = DirectoryReader(&amp;quot;MyGadget&amp;quot;)''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:BoolExists(string parameter_name)===&lt;br /&gt;
 '''Returns:''' (bool) true if there is an existing bool parameter with passed name&lt;br /&gt;
&lt;br /&gt;
===:GetBool(string parameter_name, bool default_value)===&lt;br /&gt;
Retrieve a bool with the passed name, if no value with passed name returns the passed default value&lt;br /&gt;
::''parameter_name (string) the name of the parameter ''&lt;br /&gt;
::''value (integer) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
===:SetBool(string parameter_name, bool default_value)===&lt;br /&gt;
Retrieve a Boolean flag (true or false) with the passed name, if no value with passed name returns the passed default value&lt;br /&gt;
::''parameter_name (string) the name of the parameter''&lt;br /&gt;
::''default_value(bool) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:DoubleExists(string parameter_name)===&lt;br /&gt;
 '''Returns:''' (bool) true if there is an existing double parameter with passed name&lt;br /&gt;
&lt;br /&gt;
===:GetDouble(string parameter_name, double default_value)===&lt;br /&gt;
Retrieve a double with the passed name, if no value with passed name returns the passed default value&lt;br /&gt;
::''parameter_name (string) the name of the parameter default_value(double) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
===:SetDouble(string parameter_name, double value)===&lt;br /&gt;
Store a double with the passed name and value&lt;br /&gt;
::''parameter_name (string) the name which will be used to store and retrieve the value''&lt;br /&gt;
::''value(double) the value which will be stored in the parameter list''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:IntExists(string parameter_name)===&lt;br /&gt;
 '''Returns:''' (bool) true if there is an existing int parameter with passed name&lt;br /&gt;
&lt;br /&gt;
===:GetInt(string parameter_name, integer default_value)===&lt;br /&gt;
Retrieve an integer with the passed name, if no value with passed name returns the passed default value&lt;br /&gt;
::''parameter_name (string) the name of the parameter''&lt;br /&gt;
::''value (integer) the value which will be returned if there is no existing value stored''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; &lt;br /&gt;
  JimAndI.Count = RegistryRead:GetInt(&amp;quot;JimAndI.Count&amp;quot;, 2)&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===:SetInt(string parameter_name, integer value)===&lt;br /&gt;
Store an integer with the passed name and value&lt;br /&gt;
::''parameter_name (string) the name which will be used to store and retrieve the value''&lt;br /&gt;
::''value (integer) the value which will be stored in the parameter list''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:StringExists(string parameter_name)===&lt;br /&gt;
 '''Returns:''' (bool) true if there is an existing string parameter with passed name&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:GetString(string parameter_name, string value)===&lt;br /&gt;
Retrieve a string with the passed name , if no value with passed name returns the  passed default value&lt;br /&gt;
::''parameter_name (string) the name of the parameter''&lt;br /&gt;
::''value (string) the value which will be returned if there is no existing value stored''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:SetString(string parameter_name, string value)===&lt;br /&gt;
Store a string with the passed name and value&lt;br /&gt;
::''parameter_name (string) the name which will be used to store and retrieve the value''&lt;br /&gt;
::''value (string) the value which will be stored in the parameter list''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''''Sample Code:'''''&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; function ReadRegistry()  -- Read from Registry values&lt;br /&gt;
  local RegistryRead = Registry(&amp;quot;MyProgram&amp;quot;)&lt;br /&gt;
  if not(RegistryRead:StringExists(&amp;quot;CodeBy&amp;quot;)) then&lt;br /&gt;
      LoadRegistry()&lt;br /&gt;
  end&lt;br /&gt;
  CodeBy = RegistryRead:GetString(&amp;quot;CodeBy&amp;quot;, &amp;quot;James Anderson&amp;quot;)&lt;br /&gt;
  ProgramName = RegistryRead:GetString(&amp;quot;ProgramName&amp;quot;, &amp;quot;Easy Dovetail Maker&amp;quot;)&lt;br /&gt;
  ProgramVersion = RegistryRead:GetString(&amp;quot;ProgramVersion&amp;quot;, Dovetail.ProgramVersion)&lt;br /&gt;
  ProgramYear = RegistryRead:GetString(&amp;quot;ProgramYear&amp;quot;, &amp;quot;2020&amp;quot;)&lt;br /&gt;
 end &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=User Interface]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 10.0, published August 21, 2019. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=SDK:Revisions&amp;diff=1083</id>
		<title>SDK:Revisions</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=SDK:Revisions&amp;diff=1083"/>
		<updated>2024-09-16T03:51:32Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]] &lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
'''Revision History'''&lt;br /&gt;
&lt;br /&gt;
[[ToolpathManager#:DeleteAllToolpaths.28.29|Number 1.0 - Feb 10, 2020 :DeleteAllToolpath()]]&lt;br /&gt;
&lt;br /&gt;
[[HTML_Dialog#:AddFilePicker.28 bool_File_can_be_new.2C_string_element_id.2C_string_buddy_name.2C_bool_buddy_is_edit.29|Number 002 - May 21, 2020 :AddFilePicker()]]&lt;br /&gt;
&lt;br /&gt;
[[Number 3.0 - Jul 8, 2020]] Revised to Version 10.0&lt;br /&gt;
&lt;br /&gt;
[[Gadget_File_Requirements#|Number 3.1 - May 5, 2023]] Added the Gadget File Requirements&lt;br /&gt;
&lt;br /&gt;
[[RemoveObject(object)#|Number 12 - Sept 9, 2024]] Revised to Version 11.0&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Vectric_Lua_Interface_for_Gadgets&amp;diff=1082</id>
		<title>Vectric Lua Interface for Gadgets</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Vectric_Lua_Interface_for_Gadgets&amp;diff=1082"/>
		<updated>2024-09-16T03:44:13Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Main Page]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
======''Version 3.1''======&lt;br /&gt;
'''Please Note: ''The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 12.0, published 9th September 2024. by Vectric Ltd.'''''&lt;br /&gt;
&lt;br /&gt;
::Most current document and sample Gadgets can be downloaded from Vertric at '''[https://gadgets.vectric.com/developerinfo.html Vertric Developer Information ]'''&lt;br /&gt;
[[File:VLIFG.jpg|thumb|Vectric SDK ver 12.0]]&lt;br /&gt;
&amp;lt;p&amp;gt;The Script interface and associated documentation is designed for people who are familiar with programming and is provided as a development tool for such people. It is extremely important to understand that Vectric cannot offer individual support for people wanting to write scripts. This documentation and the associated example scripts available from the [https://www.vectric.com Vectric web site] are the only way you can learn about the script interface and develop your own gadgets. The appropriate area on the [http://forum.vectric.com/index.php Vectric forum] may also be useful for asking questions of other users.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;Introduction&amp;lt;/strong&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;The Script interface and associated documentation is designed for people who are familiar with&lt;br /&gt;
programming and is provided as a development tool for such people. It is extremely important to&lt;br /&gt;
understand that Vectric cannot offer individual support for people wanting to write scripts. This&lt;br /&gt;
documentation and the associated example scripts available from the Vectric web site are the only&lt;br /&gt;
way you can learn about the script interface and develop your own gadgets. The appropriate area on&lt;br /&gt;
the Vectric forum may also be useful for asking questions of other users.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This document lists the objects (classes) available to Lua scripts (Gadgets) from VCarve Pro V7.5 and&lt;br /&gt;
Aspire V4.5&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;An object in Lua can have both methods and properties. A method is called using ‘:’ after the object&lt;br /&gt;
name e.g. job:Refresh2DView(), a property is accessed via ‘.’ e.g. job.Exists . Properties can be either&lt;br /&gt;
read only (R/O i.e Get Values) or read / write (R/W - Get/Set Values).&amp;lt;/p&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;Software Development Kit&amp;lt;/strong&amp;gt; &lt;br /&gt;
;*[[SDK: Revisions | Revision History]]&lt;br /&gt;
;*[[Gadget File Requirements]]&lt;br /&gt;
;*[[Global_Methods]]&lt;br /&gt;
;*[[Job Related Global Methods]]&lt;br /&gt;
;*[[Vector Object Related Global Methods]]&lt;br /&gt;
;*[[Component Related Global Methods – Aspire Only]]&lt;br /&gt;
;*[[Document Variable Related Global Methods]]&lt;br /&gt;
;*[[Data File Locations Related Global Methods]]&lt;br /&gt;
;*[[High Level Objects]]&lt;br /&gt;
;*[[Creating Vectors From Script]]&lt;br /&gt;
;*[[Low Level Geometry]]&lt;br /&gt;
;*[[Toolpaths]]&lt;br /&gt;
;*[[User Interface]]&lt;br /&gt;
;*[[Aspire Only]]&lt;br /&gt;
;*[[DocumentVariableList]] &lt;br /&gt;
;*[[DocumentVariable]]&lt;br /&gt;
;*[[JimAndi Toolbox]]&lt;br /&gt;
;*[[Wiki Toolbox]]&lt;br /&gt;
;*[[Licence.txt]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Main Page]]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Vectric_Lua_Interface_for_Gadgets&amp;diff=1081</id>
		<title>Vectric Lua Interface for Gadgets</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Vectric_Lua_Interface_for_Gadgets&amp;diff=1081"/>
		<updated>2024-09-16T03:43:16Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Main Page]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
======''Version 3.1''======&lt;br /&gt;
'''Please Note: ''The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 12.0, published 18st October 2024. by Vectric Ltd.'''''&lt;br /&gt;
&lt;br /&gt;
::Most current document and sample Gadgets can be downloaded from Vertric at '''[https://gadgets.vectric.com/developerinfo.html Vertric Developer Information ]'''&lt;br /&gt;
[[File:VLIFG.jpg|thumb|Vectric SDK ver 12.0]]&lt;br /&gt;
&amp;lt;p&amp;gt;The Script interface and associated documentation is designed for people who are familiar with programming and is provided as a development tool for such people. It is extremely important to understand that Vectric cannot offer individual support for people wanting to write scripts. This documentation and the associated example scripts available from the [https://www.vectric.com Vectric web site] are the only way you can learn about the script interface and develop your own gadgets. The appropriate area on the [http://forum.vectric.com/index.php Vectric forum] may also be useful for asking questions of other users.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;Introduction&amp;lt;/strong&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;The Script interface and associated documentation is designed for people who are familiar with&lt;br /&gt;
programming and is provided as a development tool for such people. It is extremely important to&lt;br /&gt;
understand that Vectric cannot offer individual support for people wanting to write scripts. This&lt;br /&gt;
documentation and the associated example scripts available from the Vectric web site are the only&lt;br /&gt;
way you can learn about the script interface and develop your own gadgets. The appropriate area on&lt;br /&gt;
the Vectric forum may also be useful for asking questions of other users.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This document lists the objects (classes) available to Lua scripts (Gadgets) from VCarve Pro V7.5 and&lt;br /&gt;
Aspire V4.5&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;An object in Lua can have both methods and properties. A method is called using ‘:’ after the object&lt;br /&gt;
name e.g. job:Refresh2DView(), a property is accessed via ‘.’ e.g. job.Exists . Properties can be either&lt;br /&gt;
read only (R/O i.e Get Values) or read / write (R/W - Get/Set Values).&amp;lt;/p&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;Software Development Kit&amp;lt;/strong&amp;gt; &lt;br /&gt;
;*[[SDK: Revisions | Revision History]]&lt;br /&gt;
;*[[Gadget File Requirements]]&lt;br /&gt;
;*[[Global_Methods]]&lt;br /&gt;
;*[[Job Related Global Methods]]&lt;br /&gt;
;*[[Vector Object Related Global Methods]]&lt;br /&gt;
;*[[Component Related Global Methods – Aspire Only]]&lt;br /&gt;
;*[[Document Variable Related Global Methods]]&lt;br /&gt;
;*[[Data File Locations Related Global Methods]]&lt;br /&gt;
;*[[High Level Objects]]&lt;br /&gt;
;*[[Creating Vectors From Script]]&lt;br /&gt;
;*[[Low Level Geometry]]&lt;br /&gt;
;*[[Toolpaths]]&lt;br /&gt;
;*[[User Interface]]&lt;br /&gt;
;*[[Aspire Only]]&lt;br /&gt;
;*[[DocumentVariableList]] &lt;br /&gt;
;*[[DocumentVariable]]&lt;br /&gt;
;*[[JimAndi Toolbox]]&lt;br /&gt;
;*[[Wiki Toolbox]]&lt;br /&gt;
;*[[Licence.txt]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Main Page]]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Vectric_Lua_Interface_for_Gadgets&amp;diff=1080</id>
		<title>Vectric Lua Interface for Gadgets</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Vectric_Lua_Interface_for_Gadgets&amp;diff=1080"/>
		<updated>2024-09-16T03:40:46Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Main Page]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
======''Version 3.1''======&lt;br /&gt;
'''Please Note: ''The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 11.0, published 18st October 2024. by Vectric Ltd.'''''&lt;br /&gt;
&lt;br /&gt;
::Most current document and sample Gadgets can be downloaded from Vertric at '''[https://gadgets.vectric.com/developerinfo.html Vertric Developer Information ]'''&lt;br /&gt;
[[File:VLIFG.jpg|thumb|Vectric SDK ver 12.0]]&lt;br /&gt;
&amp;lt;p&amp;gt;The Script interface and associated documentation is designed for people who are familiar with programming and is provided as a development tool for such people. It is extremely important to understand that Vectric cannot offer individual support for people wanting to write scripts. This documentation and the associated example scripts available from the [https://www.vectric.com Vectric web site] are the only way you can learn about the script interface and develop your own gadgets. The appropriate area on the [http://forum.vectric.com/index.php Vectric forum] may also be useful for asking questions of other users.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;Introduction&amp;lt;/strong&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;The Script interface and associated documentation is designed for people who are familiar with&lt;br /&gt;
programming and is provided as a development tool for such people. It is extremely important to&lt;br /&gt;
understand that Vectric cannot offer individual support for people wanting to write scripts. This&lt;br /&gt;
documentation and the associated example scripts available from the Vectric web site are the only&lt;br /&gt;
way you can learn about the script interface and develop your own gadgets. The appropriate area on&lt;br /&gt;
the Vectric forum may also be useful for asking questions of other users.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;This document lists the objects (classes) available to Lua scripts (Gadgets) from VCarve Pro V7.5 and&lt;br /&gt;
Aspire V4.5&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;An object in Lua can have both methods and properties. A method is called using ‘:’ after the object&lt;br /&gt;
name e.g. job:Refresh2DView(), a property is accessed via ‘.’ e.g. job.Exists . Properties can be either&lt;br /&gt;
read only (R/O i.e Get Values) or read / write (R/W - Get/Set Values).&amp;lt;/p&amp;gt;  &lt;br /&gt;
&lt;br /&gt;
&amp;lt;strong&amp;gt;Software Development Kit&amp;lt;/strong&amp;gt; &lt;br /&gt;
;*[[SDK: Revisions | Revision History]]&lt;br /&gt;
;*[[Gadget File Requirements]]&lt;br /&gt;
;*[[Global_Methods]]&lt;br /&gt;
;*[[Job Related Global Methods]]&lt;br /&gt;
;*[[Vector Object Related Global Methods]]&lt;br /&gt;
;*[[Component Related Global Methods – Aspire Only]]&lt;br /&gt;
;*[[Document Variable Related Global Methods]]&lt;br /&gt;
;*[[Data File Locations Related Global Methods]]&lt;br /&gt;
;*[[High Level Objects]]&lt;br /&gt;
;*[[Creating Vectors From Script]]&lt;br /&gt;
;*[[Low Level Geometry]]&lt;br /&gt;
;*[[Toolpaths]]&lt;br /&gt;
;*[[User Interface]]&lt;br /&gt;
;*[[Aspire Only]]&lt;br /&gt;
;*[[DocumentVariableList]] &lt;br /&gt;
;*[[DocumentVariable]]&lt;br /&gt;
;*[[JimAndi Toolbox]]&lt;br /&gt;
;*[[Wiki Toolbox]]&lt;br /&gt;
;*[[Licence.txt]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Main Page]]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=CadContour&amp;diff=1079</id>
		<title>CadContour</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=CadContour&amp;diff=1079"/>
		<updated>2024-09-03T20:10:34Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=High Level Objects]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
This object is derived from CadObject and represents a single vector within the job. A CadContour holds a Contour object which contains the actual data for the vector shape. A CadContour is created from a Contour object using the CreateCadContour() method. To access the Contour data from a CadContour object, use the :GetContour() method from the base CadObject class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Properties==&lt;br /&gt;
All the properties for this object are documented in the CadObject base class&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&lt;br /&gt;
'''Note:''' This object inherits all documented methods from the CadObject base class with the following additions&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:InsertToolpathTabAtPoint(Point2D point)===&lt;br /&gt;
&lt;br /&gt;
This method inserts a toolpath tab at the point on the CadContour closest to the specified point. &lt;br /&gt;
&lt;br /&gt;
'''Returns:''' a ToolpathTab object.&lt;br /&gt;
&lt;br /&gt;
::''point (Point2D)  The point where to place the toolpath tab''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=High Level Objects]]&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=CadContour&amp;diff=1078</id>
		<title>CadContour</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=CadContour&amp;diff=1078"/>
		<updated>2024-09-03T20:07:44Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=High Level Objects]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
This object is derived from CadObject and represents a single vector within the job. A CadContour holds a Contour object which contains the actual data for the vector shape. A CadContour is created from a Contour object using the CreateCadContour() method. To access the Contour data from a CadContour object, use the:GetContour() method from the base CadObject class.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Properties==&lt;br /&gt;
All the properties for this object are documented in the CadObject base class&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&lt;br /&gt;
'''Note:''' This object inherits all documented methods from the CadObject base class with the following additions&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===:InsertToolpathTabAtPoint(Point2D point)===&lt;br /&gt;
&lt;br /&gt;
This method inserts a toolpath tab at the point on the CadContour closest to the specified point. &lt;br /&gt;
&lt;br /&gt;
'''Returns:''' a ToolpathTab object.&lt;br /&gt;
&lt;br /&gt;
::''point (Point2D)  The point where to place the toolpath tab''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=High Level Objects]]&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=ArcSpan&amp;diff=1077</id>
		<title>ArcSpan</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=ArcSpan&amp;diff=1077"/>
		<updated>2024-08-31T15:32:51Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; [[File:Back.jpg|right|50px|link=Creating Vectors From Script]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
&lt;br /&gt;
This object represents an arc span in a Contour. It is derived from the Span class and all methods and properties of the span class are valid on this object as well. As well as creating spans to append to a contour you can use the ArcTo methods to avoid span creation. Arcs are represented internally using the start and end points and a ‘bulge factor’ which controls the shape of the arc. The bulge represents a ratio between the chord length of an arc and its height (bulge = (2 * arc_height) / chord_length).&lt;br /&gt;
&lt;br /&gt;
== Constructors ==&lt;br /&gt;
&lt;br /&gt;
=== ArcSpan(Point2D start_pt, Point2D end_pt, Point2D pt_on_arc) === &lt;br /&gt;
 - Constructor -&lt;br /&gt;
A new span representing an arc is created within a Lua script using this contructor method&lt;br /&gt;
::''start_pt – Point2D – 2D position for start point of span&lt;br /&gt;
::''end_pt – Point2D – 2D position for end point of span- must have same Z values as start&lt;br /&gt;
::''pt_on_arc- Point2D – 2D position for a point on arc&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
::''NOTE: arcs can be a maximum of 180 degrees&lt;br /&gt;
::''e.g&lt;br /&gt;
 &amp;lt;nowiki&amp;gt; local start_pt = Point2D(0, 0)&lt;br /&gt;
 local end_pt = Point2D(1.0, 0)&lt;br /&gt;
 local pt_on_arc = Point2D(0.5, 0.3)&lt;br /&gt;
 local arc_span = ArcSpan(start_pt, end_pt, pt_on_arc) &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===ArcSpan(Point2D start_pt, Point2D end_pt, Point2D centre_pt, bool ccw) - Constructor ===&lt;br /&gt;
&lt;br /&gt;
A new span representing an arc is created within a Lua script using this contructor method&lt;br /&gt;
&lt;br /&gt;
::''start_pt – Point2D – 2D position for start point of span&lt;br /&gt;
::''end_pt – Point2D – 2D position for end point of span- must have same Z values as start&lt;br /&gt;
::''centre_pt – Point2D – 2D position for centre point of arc (not mid-point)&lt;br /&gt;
::''ccw - bool - true if arc is Counter Clockwise&lt;br /&gt;
&lt;br /&gt;
:: e.g&lt;br /&gt;
&amp;lt;nowiki&amp;gt; local start_pt = Point2D(0, 0)&lt;br /&gt;
 local end_pt = Point2D(1.0, 0)&lt;br /&gt;
 local center_pt = Point2D(0.5, 0)&lt;br /&gt;
 local arc_span = ArcSpan(start_pt, end_pt, center_pt, false) &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:: NOTE: arcs can be a maximum of 180 degrees&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== ArcSpan(Point3D start_pt, Point3D end_pt, Point3D centre_pt, bool ccw) - Constructor ===&lt;br /&gt;
&lt;br /&gt;
A new span representing an arc is created within a Lua script using this contructor method&lt;br /&gt;
::''start_pt - Point3D - 3d position for start point of span&lt;br /&gt;
::''end_pt - Point3D - 3d position for end point of span- must have same Z values as start&lt;br /&gt;
::''centre_pt - Point3D - 3d position for centre point of arc (not mid-point)&lt;br /&gt;
::''ccw - bool - true if arc is Counter Clockwise&lt;br /&gt;
&lt;br /&gt;
::''e.g&lt;br /&gt;
::''local start_pt = Point3D(0, 0, 0)&lt;br /&gt;
::''local end_pt = Point3D(1.0, 0, 0) &lt;br /&gt;
::local center_pt = Point3D(0.5, 0, 0)&lt;br /&gt;
::local arc_span = ArcSpan(start_pt, end_pt, center_pt, false)&lt;br /&gt;
::NOTE: arcs can be a maximum of 180 degrees&lt;br /&gt;
&lt;br /&gt;
=== ArcSpan(Point3D start_pt, Point3D end_pt, Point2D pt_on_arc) - Constructor ===&lt;br /&gt;
&lt;br /&gt;
A new span representing an arc is created within a Lua script using this contructor method&lt;br /&gt;
::''start_pt - Point3D – 3D position for start point of span&lt;br /&gt;
::''end_pt - Point3D – 3D position for end point of span- must have same Z values as start pt_on_arc- Point2D – 2D position for a point on arc&lt;br /&gt;
&lt;br /&gt;
:: NOTE: arcs can be a maximum of 180 degrees &lt;br /&gt;
&lt;br /&gt;
::''e.g &lt;br /&gt;
::''local start_pt = Point3D(0, 0, 0) &lt;br /&gt;
::''local end_pt = Point3D(1.0, 0, 0) &lt;br /&gt;
::''local pt_on_arc = Point2D(0.5, 0.3) &lt;br /&gt;
::''local arc_span = ArcSpan(start_pt, end_pt, pt_on_arc) &lt;br /&gt;
&lt;br /&gt;
=== ArcSpan(Point2D start_pt, Point2D end_pt, double bulge) - Constructor ===&lt;br /&gt;
&lt;br /&gt;
A new span representing an arc is created within a Lua script using this contructor method start_pt – Point2D – 2D position for start point of span end_pt – Point2D – 2D position for end point of span - must have same Z values as start bulge - double - buge factor for arc e.g local start_pt = Point2D(0, 0) local end_pt = Point2D(1.0, 0) local arc_span = ArcSpan(start_pt, end_pt, 1.0) &lt;br /&gt;
&lt;br /&gt;
=== ArcSpan(Point3D start_pt, Point3D end_pt, double bulge) - Constructor ===&lt;br /&gt;
&lt;br /&gt;
A new span representing an arc is created within a Lua script using this contructor method start_pt - Point3D – 3D position for start point of span end_pt - Point3D – 3D position for end point of span - must have same Z values as start bulge - double - buge factor for arc e.g local start_pt = Point3D(0, 0, 0) local end_pt = Point3D(1.0, 0, 0) local arc_span = &lt;br /&gt;
&lt;br /&gt;
=== ArcSpan(start_pt, end_pt, 1.0) === &lt;br /&gt;
&lt;br /&gt;
 NOTE: arcs can be a maximum of 180 degrees &lt;br /&gt;
&lt;br /&gt;
== Properties ==&lt;br /&gt;
&lt;br /&gt;
=== .Bulge ===&lt;br /&gt;
R/O - double - signed bulge for arc &lt;br /&gt;
&lt;br /&gt;
=== .IsAntiClockwise ===&lt;br /&gt;
R/O - bool - true if arc is anticlockwise (same as .IsCCW) &lt;br /&gt;
&lt;br /&gt;
=== .IsCCW ===&lt;br /&gt;
R/O - bool - true if arc is counter clockwise (same as . IsAntiClockwise) &lt;br /&gt;
&lt;br /&gt;
===.IsClockwise ===&lt;br /&gt;
R/O - bool - true if arc is clockwise (same as . IsCW ) &lt;br /&gt;
&lt;br /&gt;
===.IsCW ===&lt;br /&gt;
R/O - bool - true if arc is clockwise (same as . IsClockwise) &lt;br /&gt;
&lt;br /&gt;
== Methods ==&lt;br /&gt;
&lt;br /&gt;
=== :ArcMidPoint() ===&lt;br /&gt;
Returns a Point3D holding the mid point of the arc&lt;br /&gt;
&lt;br /&gt;
=== :RadiusAndCentre(Point3D ret_centre_pt) ===&lt;br /&gt;
Calculate the centre point of the arc and the radius. The method returns the radius and also sets the position of the passed point to the centre point position of the arc.&lt;br /&gt;
ret_centre_pt - Point3D - returned 3d position for centre point of arc (not mid-point)&lt;br /&gt;
&lt;br /&gt;
 Example Code&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 local arc = ArcSpan(Point3D(0,0,0), Point3D(1,0,0), 1.0)&lt;br /&gt;
 local centre = Point3D()&lt;br /&gt;
 local radius = arc:RadiusAndCentre(centre)&lt;br /&gt;
 MessageBox(&amp;quot;Arc Radius = &amp;quot; .. radius ..&lt;br /&gt;
 &amp;quot; Centre Point = &amp;quot; .. centre.x .. &amp;quot;,&amp;quot; .. centre.y ) &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== :SetBulge(bulge) ===&lt;br /&gt;
Set the bulge factor for this arc&lt;br /&gt;
Bulge - double - bulge factor for arc&lt;br /&gt;
&lt;br /&gt;
---&lt;br /&gt;
&lt;br /&gt;
== Global helper methods ==&lt;br /&gt;
&lt;br /&gt;
=== ArcBulgeFromMidPoint(Point2D start, Point2D end, Point2D mid) ===&lt;br /&gt;
::''Return the bulge factor for an arc through the specified 3 points&lt;br /&gt;
::''start -Point2D -Start point for arc&lt;br /&gt;
::''end -Point2D -End point for arc&lt;br /&gt;
::''mid -Point2D -mid point for arc ( NOT centre point)&lt;br /&gt;
&lt;br /&gt;
 [[File:Back.jpg|right|50px|link=Creating Vectors From Script]]&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Creating_Vectors_From_Script&amp;diff=1076</id>
		<title>Creating Vectors From Script</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Creating_Vectors_From_Script&amp;diff=1076"/>
		<updated>2024-08-31T15:27:00Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
&lt;br /&gt;
The previous objects (VectricJob, CadLayer, CadContour etc) represent high level objects used within the program. When the user wants to create new geometry from within a script, they will be working with lower level entities. These entities are Spans, Contours and Contour Groups.&lt;br /&gt;
A Span is the lowest level piece of geometry and it always has a start and end point. It is important to realize that although geometry in the main program is always 2D, the underlying reprentation of Spans and Contours supports full 3d values. This means that when Contours are used to define toolpaths, full 3D tool moves can be represented. If you are simply creating geometry which will appear in the 2D view in the main program, the Z value for all points should be left at 0.0.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
;*[[ArcSpan|ArcSpan]]&lt;br /&gt;
;*[[BezierSpan|BezierSpan]]&lt;br /&gt;
;*[[Contour|Contour]]&lt;br /&gt;
;*[[ContourGroup|ContourGroup]]&lt;br /&gt;
;*[[LineSpan|LineSpan]]&lt;br /&gt;
;*[[Span Helper Methods|Span Helper Methods]]&lt;br /&gt;
;*[[Span|Span]]&lt;br /&gt;
;*[[ToolpathTab|ToolpathTab]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Creating_Vectors_From_Script&amp;diff=1075</id>
		<title>Creating Vectors From Script</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Creating_Vectors_From_Script&amp;diff=1075"/>
		<updated>2024-08-31T15:25:01Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
&lt;br /&gt;
The previous objects (VectricJob, CadLayer, CadContour etc) represent high level objects used within the program. When the user wants to create new geometry from within a script, they will be working with lower level entities. These entities are Spans, Contours and Contour Groups.&lt;br /&gt;
A Span is the lowest level piece of geometry and it always has a start and end point. It is important to realize that although geometry in the main program is always 2D, the underlying reprentation of Spans and Contours supports full 3d values. This means that when Contours are used to define toolpaths, full 3D tool moves can be represented. If you are simply creating geometry which will appear in the 2D view in the main program, the Z value for all points should be left at 0.0.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[ArcSpan]]&lt;br /&gt;
&lt;br /&gt;
[[BezierSpan]]&lt;br /&gt;
&lt;br /&gt;
[[Contour]]&lt;br /&gt;
&lt;br /&gt;
[[ContourGroup]]&lt;br /&gt;
&lt;br /&gt;
[[LineSpan]]&lt;br /&gt;
&lt;br /&gt;
[[Span Helper Methods]]&lt;br /&gt;
&lt;br /&gt;
[[Span]]&lt;br /&gt;
&lt;br /&gt;
[[ToolpathTab]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Creating_Vectors_From_Script&amp;diff=1074</id>
		<title>Creating Vectors From Script</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Creating_Vectors_From_Script&amp;diff=1074"/>
		<updated>2024-08-31T15:24:44Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
&lt;br /&gt;
The previous objects (VectricJob, CadLayer, CadContour etc) represent high level objects used within the program. When the user wants to create new geometry from within a script, they will be working with lower level entities. These entities are Spans, Contours and Contour Groups.&lt;br /&gt;
A Span is the lowest level piece of geometry and it always has a start and end point. It is important to realize that although geometry in the main program is always 2D, the underlying reprentation of Spans and Contours supports full 3d values. This means that when Contours are used to define toolpaths, full 3D tool moves can be represented. If you are simply creating geometry which will appear in the 2D view in the main program, the Z value for all points should be left at 0.0.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[ArcSpan]]&lt;br /&gt;
[[BezierSpan]]&lt;br /&gt;
[[Contour]]&lt;br /&gt;
[[ContourGroup]]&lt;br /&gt;
[[LineSpan]]&lt;br /&gt;
[[Span Helper Methods]]&lt;br /&gt;
[[Span]]&lt;br /&gt;
[[ToolpathTab]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Span&amp;diff=1073</id>
		<title>Span</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Span&amp;diff=1073"/>
		<updated>2024-08-30T20:34:36Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:SDK]]&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Creating Vectors From Script]]&lt;br /&gt;
This object is the base class for spans in a Contour. Spans are either lines, arcs or beziers or a single ‘point’  &lt;br /&gt;
&lt;br /&gt;
==Constructors==&lt;br /&gt;
&lt;br /&gt;
===Span( Point3D pt3d)===&lt;br /&gt;
&lt;br /&gt;
A new span representing a single point is created within a Lua script using this constructor method   &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
pt3d - Point3D - 3d position for a point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
e.g  &lt;br /&gt;
&lt;br /&gt;
local pt = Point3D(0, 0, 0)  &lt;br /&gt;
&lt;br /&gt;
local pt_span = Span(pt)  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
NOTE: most spans are created as either a LineSpan,  ArcSpan or BezierSpan.  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
==Properties==  &lt;br /&gt;
&lt;br /&gt;
===.EndPoint3D===&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (Point3D) The 3D end point of the span  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.EndPoint2D===&lt;br /&gt;
&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
 '''Returns:''' (Point2D)  The 2D end point of the span  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.IsLineType===&lt;br /&gt;
&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
 '''Returns:''' (Bool) true if span is a line      &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.IsArcType===&lt;br /&gt;
&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
 '''Returns:''' (Bool)  true if span is an arc  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.IsBezierType===&lt;br /&gt;
&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
 '''Returns:''' (Bool)  true if span is a bezier   &lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
===.IsLeadInType===&lt;br /&gt;
&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
 '''Returns:''' (Bool) true if span is a lead in   &lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
===.IsLeadOutType===&lt;br /&gt;
&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
 '''Returns:''' (Bool) true if span is a lead out   &lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
===.IsOvercutType===&lt;br /&gt;
&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
 '''Returns:''' (Bool) true if span is part of an overcut  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.NumberOfControlPoints===&lt;br /&gt;
&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
 '''Returns:''' (Integer) number of control points for span (2 for Bezier, 1 for an arc (the mid point), 0 for a line  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.StartPoint3D===&lt;br /&gt;
&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
 '''Returns:''' (Point3D) The 3D start point of the span  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.StartPoint2D===&lt;br /&gt;
&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
 '''Returns:''' (Point2D) The 2D start point of the span  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.Type===&lt;br /&gt;
&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
 '''Returns:''' (Integer) enum identifying type of the span  &lt;br /&gt;
&lt;br /&gt;
Usual values are Span.NormalLine, Span.Arc and Span.Bezier  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&lt;br /&gt;
               &lt;br /&gt;
&lt;br /&gt;
===:ChordLength()===  &lt;br /&gt;
&lt;br /&gt;
Return the straight-line distance between start and end points of the span                &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:EndVector( bool normalise)===                  &lt;br /&gt;
&lt;br /&gt;
Return a Vector2D representing the direction of the span at the end.   &lt;br /&gt;
&lt;br /&gt;
 normalise - bool - if true, the returned vector is normalised  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:GetControlPointPosition( integer index)===  &lt;br /&gt;
&lt;br /&gt;
Return a Point2D with position of requested control point (use .NumberOfControlPoints to get count). This call is only valid on a Bezier or an Arc. For a Bezier 0 returns first control point, 1 returns the second. For an arc, 0 returns arc mid point.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
 index - integer - index of control point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:GetLength( double tolerance)===  &lt;br /&gt;
&lt;br /&gt;
Return a double holding the length of the span. The passed tolerance is used for beziers to approximate length to given tolerance.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
 tolerance - double - tolerance to use when polygonizing beziers to find length  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:MoveControlPoint( integer index, Point2D pt)  === &lt;br /&gt;
&lt;br /&gt;
This is only valid for an arc or Bezier and attempts to move the specified control point to the passed position. This call is only valid on a Bezier or an Arc. For a Bezier, index 0 modifies first control point, 1 modifies the second. For an arc, 0 modifies the arc mid point. If the control point can’t be moved to the passed position (e.g would make an invalid arc) returns false, else true.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
 index - integer - index of control point pt - Point2D - position for control point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:PointAtParameter( double param,  double tolerance)  ===&lt;br /&gt;
&lt;br /&gt;
Return a Point2D representing the point on the span at passed parameter in range 0 - 1.0. Passed tolerance is used for polygonisation for Bezier spans.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
parameter - double - parameter in range 0 - 1.0 to find point on span at tolerance - double - tolerance to use when polygonizing beziers  :Reverse()  &lt;br /&gt;
&lt;br /&gt;
Reverse the span - swap start and end points and for arcs swap sign of bulge, for beziers swap control points.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:StartVector( bool normalise)===  &lt;br /&gt;
&lt;br /&gt;
Return a Vector2D representing the direction of the span at the start.   &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
 normalise - bool - if true, the returned vector is normalized  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:SetStartPoint3D( Point3D pt)===            &lt;br /&gt;
&lt;br /&gt;
Set start point for span - be EXTREMELY careful if you call this method on spans in a contour as gaps will open between adjoining spans leading to an invalid contour.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
 pt - Point3D - 3D position for point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:SetStartPoint2D( Point2D pt)===       &lt;br /&gt;
&lt;br /&gt;
Set start point for span - be EXTREMELY careful if you call this method on spans in a contour as gaps will open between adjoining spans leading to an invalid contour.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
 pt - Point2D - 2D position for point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:SetEndPoint3D( Point3D pt)===&lt;br /&gt;
&lt;br /&gt;
Set end point for span - be EXTREMELY careful if you call this method on spans in a contour as gaps will open between adjoining spans leading to an invalid contour.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
 pt - Point3D - 3D position for point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:SetEndPoint2D( Point2D pt)===&lt;br /&gt;
&lt;br /&gt;
Set end point for span - be EXTREMELY careful if you call this method on spans in a contour as gaps will open between adjoining spans leading to an invalid contour.  &lt;br /&gt;
&lt;br /&gt;
 pt - Point2D - 2D position for point  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Creating Vectors From Script]]&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Span&amp;diff=1072</id>
		<title>Span</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Span&amp;diff=1072"/>
		<updated>2024-08-30T20:32:46Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:SDK]]&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Creating Vectors From Script]]&lt;br /&gt;
This object is the base class for spans in a Contour. Spans are either lines, arcs or beziers or a single ‘point’  &lt;br /&gt;
&lt;br /&gt;
==Constructors==&lt;br /&gt;
&lt;br /&gt;
===Span( Point3D pt3d)===&lt;br /&gt;
&lt;br /&gt;
A new span representing a single point is created within a Lua script using this constructor method   &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
pt3d - Point3D - 3d position for a point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
e.g  &lt;br /&gt;
&lt;br /&gt;
local pt = Point3D(0, 0, 0)  &lt;br /&gt;
&lt;br /&gt;
local pt_span = Span(pt)  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
NOTE: most spans are created as either a LineSpan,  ArcSpan or BezierSpan.  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
==Properties==  &lt;br /&gt;
&lt;br /&gt;
===.EndPoint3D===&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
&lt;br /&gt;
 '''Returns:''' (Point3D) The 3D end point of the span  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.EndPoint2D===&lt;br /&gt;
&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
 '''Returns:''' (Point2D)  The 2D end point of the span  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.IsLineType===&lt;br /&gt;
&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
 '''Returns:''' (Bool) true if span is a line      &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.IsArcType===&lt;br /&gt;
&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
 '''Returns:''' (Bool)  true if span is an arc  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.IsBezierType===&lt;br /&gt;
&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
 '''Returns:''' (Bool)  true if span is a bezier   &lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
===.IsLeadInType===&lt;br /&gt;
&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
 '''Returns:''' (Bool) true if span is a lead in   &lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
===.IsLeadOutType===&lt;br /&gt;
&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
 '''Returns:''' (Bool) true if span is a lead out   &lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
===.IsOvercutType===&lt;br /&gt;
&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
 '''Returns:''' (Bool) true if span is part of an overcut  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.NumberOfControlPoints===&lt;br /&gt;
&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
 '''Returns:''' (Integer) number of control points for span (2 for Bezier, 1 for an arc (the mid point), 0 for a line  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.StartPoint3D===&lt;br /&gt;
&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
 '''Returns:''' (Point3D) The 3D start point of the span  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.StartPoint2D===&lt;br /&gt;
&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
 '''Returns:''' (Point2D)  The 2D start point of the span  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.Type===&lt;br /&gt;
&lt;br /&gt;
'''Interaction:''' Read Only&lt;br /&gt;
 '''Returns:''' (Integer) enum identifying type of the span  &lt;br /&gt;
&lt;br /&gt;
Usual values are Span.NormalLine, Span.Arc and Span.Bezier  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&lt;br /&gt;
               &lt;br /&gt;
&lt;br /&gt;
===:ChordLength()===  &lt;br /&gt;
&lt;br /&gt;
Return the straight-line distance between start and end points of the span                &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:EndVector( bool normalise)===                  &lt;br /&gt;
&lt;br /&gt;
Return a Vector2D representing the direction of the span at the end.   &lt;br /&gt;
&lt;br /&gt;
 normalise - bool - if true, the returned vector is normalised  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:GetControlPointPosition( integer index)===  &lt;br /&gt;
&lt;br /&gt;
Return a Point2D with position of requested control point (use .NumberOfControlPoints to get count). This call is only valid on a Bezier or an Arc. For a Bezier 0 returns first control point, 1 returns the second. For an arc, 0 returns arc mid point.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
index - integer - index of control point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:GetLength( double tolerance)===  &lt;br /&gt;
&lt;br /&gt;
Return a double holding the length of the span. The passed tolerance is used for beziers to approximate length to given tolerance.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
tolerance - double - tolerance to use when polygonizing beziers to find length  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:MoveControlPoint( integer index, Point2D pt)  === &lt;br /&gt;
&lt;br /&gt;
This is only valid for an arc or Bezier and attempts to move the specified control point to the passed position. This call is only valid on a Bezier or an Arc. For a Bezier, index 0 modifies first control point, 1 modifies the second. For an arc, 0 modifies the arc mid point. If the control point can’t be moved to the passed position (e.g would make an invalid arc) returns false, else true.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
index - integer - index of control point pt - Point2D - position for control point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:PointAtParameter( double param,  double tolerance)  ===&lt;br /&gt;
&lt;br /&gt;
Return a Point2D representing the point on the span at passed parameter in range 0 - 1.0. Passed tolerance is used for polygonisation for Bezier spans.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
parameter - double - parameter in range 0 - 1.0 to find point on span at tolerance - double - tolerance to use when polygonizing beziers  :Reverse()  &lt;br /&gt;
&lt;br /&gt;
Reverse the span - swap start and end points and for arcs swap sign of bulge, for beziers swap control points.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:StartVector( bool normalise)===  &lt;br /&gt;
&lt;br /&gt;
Return a Vector2D representing the direction of the span at the start.   &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
normalise - bool - if true, the returned vector is normalized  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:SetStartPoint3D( Point3D pt)===            &lt;br /&gt;
&lt;br /&gt;
Set start point for span - be EXTREMELY careful if you call this method on spans in a contour as gaps will open between adjoining spans leading to an invalid contour.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
pt - Point3D - 3D position for point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:SetStartPoint2D( Point2D pt)===       &lt;br /&gt;
&lt;br /&gt;
Set start point for span - be EXTREMELY careful if you call this method on spans in a contour as gaps will open between adjoining spans leading to an invalid contour.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
pt - Point2D - 2D position for point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:SetEndPoint3D( Point3D pt)===&lt;br /&gt;
&lt;br /&gt;
Set end point for span - be EXTREMELY careful if you call this method on spans in a contour as gaps will open between adjoining spans leading to an invalid contour.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
pt - Point3D - 3D position for point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:SetEndPoint2D( Point2D pt)===&lt;br /&gt;
&lt;br /&gt;
Set end point for span - be EXTREMELY careful if you call this method on spans in a contour as gaps will open between adjoining spans leading to an invalid contour.  &lt;br /&gt;
&lt;br /&gt;
pt - Point2D - 2D position for point  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Creating Vectors From Script]]&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=ContourGroup&amp;diff=1071</id>
		<title>ContourGroup</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=ContourGroup&amp;diff=1071"/>
		<updated>2024-08-30T19:04:52Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: /* Example Code */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; [[File:Back.jpg|right|50px|link=Creating Vectors From Script]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
This object is used to move along a contour a fixed distance at a time irrespective of the number of spans in the contour or the type of spans.  &lt;br /&gt;
&lt;br /&gt;
==Constructor==&lt;br /&gt;
&lt;br /&gt;
===ContourCarriage( Contour ctr, Point2D pt) === &lt;br /&gt;
&lt;br /&gt;
Creates a ‘carriage’ for the passed contour and positions it at the nearest point on the contour to the passed point.  &lt;br /&gt;
&lt;br /&gt;
ctr-Contour -The contour that the carriage travels along   &lt;br /&gt;
&lt;br /&gt;
pt-Point2D -The carriage is positioned on the contour at the closest position to this point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===ContourCarriage( integer span_index, double parameter)===  &lt;br /&gt;
&lt;br /&gt;
Creates a ‘carriage’ for a contour and set its positions for the span with the passed index at the passed parameter position (in range 0-1.0) on the span. These values are normaly specified as 0,0.0 to position the carriage at the start of the first span in the contour.  &lt;br /&gt;
&lt;br /&gt;
span_index-integer -Index of span, carriage will be positioned at parameter-double -Parameter along span carriage will be positioned at  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
e.g       local cursor = ContourCarriage(0, 0.0)  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
==Properties==  &lt;br /&gt;
&lt;br /&gt;
===.IsInvalid===  &lt;br /&gt;
&lt;br /&gt;
R/O - bool - Returns true if current position is invalid  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.SpanIndex===  &lt;br /&gt;
&lt;br /&gt;
R/O - integer - Return span index for current position of carriage  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.SpanParameter===  &lt;br /&gt;
&lt;br /&gt;
R/O - double - Return span parameter (in range 0-1.0) for current position of carriage  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&lt;br /&gt;
===:Move( Contour ctr, double distance)===  &lt;br /&gt;
&lt;br /&gt;
Moves the carriage the requested distance along the contour. Returns true if manage to move requested distance successfully. If the contour is closed we will wrap around at the end, if it is open and you attempt to move past the end this method will return false.  &lt;br /&gt;
&lt;br /&gt;
ctr-Contour -The contour this carriage rides along   &lt;br /&gt;
&lt;br /&gt;
distance - double –The distance to move along the contour, negative values will move back  towards the start  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:Position( Contour ctr)===  &lt;br /&gt;
&lt;br /&gt;
Returns a Point2D representing the current position on the carriage on the passed contour  &lt;br /&gt;
&lt;br /&gt;
ctr-Contour -The contour this carriage rides along   &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:UpdatePosition( Contour ctr, Point2D pt)===  &lt;br /&gt;
&lt;br /&gt;
Update the position of the carriage to the nearest position on the contour to the passed point.  &lt;br /&gt;
&lt;br /&gt;
ctr-Contour -The contour that the carriage travels along   &lt;br /&gt;
&lt;br /&gt;
pt-Point2D -The carriage is positioned on the contour at the closest position to this point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
====Example Code====&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[  -------------- MarkContourParameterSteps ---------------------------------   |  &lt;br /&gt;
|  Insert a marker at each parameter step around the contour and display the  &lt;br /&gt;
|  distance from the start point  &lt;br /&gt;
| ]]  &lt;br /&gt;
&lt;br /&gt;
function MarkContourParameterSteps(num_steps, contour, layer)  &lt;br /&gt;
   local cursor = ContourCarriage(0, 0.0)  &lt;br /&gt;
   local contour_length = contour.Length    &lt;br /&gt;
   local step_dist = contour_length / num_steps  &lt;br /&gt;
   local end_index = num_steps    &lt;br /&gt;
   if contour.IsOpen then&lt;br /&gt;
     end_index = end_index + 1      &lt;br /&gt;
   end -- if end&lt;br /&gt;
   for i = 1, end_index do  &lt;br /&gt;
     local ctr_pos = cursor:Position(contour)  &lt;br /&gt;
     local marker = CadMarker(&amp;quot;D:&amp;quot; .. (step_dist * (i - 1)), ctr_pos, 3)           &lt;br /&gt;
     layer:AddObject(marker, true)      &lt;br /&gt;
     cursor:Move(contour, step_dist)  &lt;br /&gt;
   end  -- for end&lt;br /&gt;
  end -- function end&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Creating Vectors From Script]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=ContourGroup&amp;diff=1070</id>
		<title>ContourGroup</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=ContourGroup&amp;diff=1070"/>
		<updated>2024-08-30T19:04:37Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; [[File:Back.jpg|right|50px|link=Creating Vectors From Script]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
This object is used to move along a contour a fixed distance at a time irrespective of the number of spans in the contour or the type of spans.  &lt;br /&gt;
&lt;br /&gt;
==Constructor==&lt;br /&gt;
&lt;br /&gt;
===ContourCarriage( Contour ctr, Point2D pt) === &lt;br /&gt;
&lt;br /&gt;
Creates a ‘carriage’ for the passed contour and positions it at the nearest point on the contour to the passed point.  &lt;br /&gt;
&lt;br /&gt;
ctr-Contour -The contour that the carriage travels along   &lt;br /&gt;
&lt;br /&gt;
pt-Point2D -The carriage is positioned on the contour at the closest position to this point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===ContourCarriage( integer span_index, double parameter)===  &lt;br /&gt;
&lt;br /&gt;
Creates a ‘carriage’ for a contour and set its positions for the span with the passed index at the passed parameter position (in range 0-1.0) on the span. These values are normaly specified as 0,0.0 to position the carriage at the start of the first span in the contour.  &lt;br /&gt;
&lt;br /&gt;
span_index-integer -Index of span, carriage will be positioned at parameter-double -Parameter along span carriage will be positioned at  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
e.g       local cursor = ContourCarriage(0, 0.0)  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
==Properties==  &lt;br /&gt;
&lt;br /&gt;
===.IsInvalid===  &lt;br /&gt;
&lt;br /&gt;
R/O - bool - Returns true if current position is invalid  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.SpanIndex===  &lt;br /&gt;
&lt;br /&gt;
R/O - integer - Return span index for current position of carriage  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.SpanParameter===  &lt;br /&gt;
&lt;br /&gt;
R/O - double - Return span parameter (in range 0-1.0) for current position of carriage  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&lt;br /&gt;
===:Move( Contour ctr, double distance)===  &lt;br /&gt;
&lt;br /&gt;
Moves the carriage the requested distance along the contour. Returns true if manage to move requested distance successfully. If the contour is closed we will wrap around at the end, if it is open and you attempt to move past the end this method will return false.  &lt;br /&gt;
&lt;br /&gt;
ctr-Contour -The contour this carriage rides along   &lt;br /&gt;
&lt;br /&gt;
distance - double –The distance to move along the contour, negative values will move back  towards the start  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:Position( Contour ctr)===  &lt;br /&gt;
&lt;br /&gt;
Returns a Point2D representing the current position on the carriage on the passed contour  &lt;br /&gt;
&lt;br /&gt;
ctr-Contour -The contour this carriage rides along   &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:UpdatePosition( Contour ctr, Point2D pt)===  &lt;br /&gt;
&lt;br /&gt;
Update the position of the carriage to the nearest position on the contour to the passed point.  &lt;br /&gt;
&lt;br /&gt;
ctr-Contour -The contour that the carriage travels along   &lt;br /&gt;
&lt;br /&gt;
pt-Point2D -The carriage is positioned on the contour at the closest position to this point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
====Example Code====&lt;br /&gt;
&lt;br /&gt;
  &amp;lt;nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[  -------------- MarkContourParameterSteps ---------------------------------   |  &lt;br /&gt;
&lt;br /&gt;
|  Insert a marker at each parameter step around the contour and display the  &lt;br /&gt;
&lt;br /&gt;
|  distance from the start point  &lt;br /&gt;
&lt;br /&gt;
| ]]  &lt;br /&gt;
&lt;br /&gt;
function MarkContourParameterSteps(num_steps, contour, layer)  &lt;br /&gt;
   local cursor = ContourCarriage(0, 0.0)  &lt;br /&gt;
   local contour_length = contour.Length    &lt;br /&gt;
   local step_dist = contour_length / num_steps  &lt;br /&gt;
   local end_index = num_steps    &lt;br /&gt;
   if contour.IsOpen then&lt;br /&gt;
     end_index = end_index + 1      &lt;br /&gt;
   end -- if end&lt;br /&gt;
   for i = 1, end_index do  &lt;br /&gt;
     local ctr_pos = cursor:Position(contour)  &lt;br /&gt;
     local marker = CadMarker(&amp;quot;D:&amp;quot; .. (step_dist * (i - 1)), ctr_pos, 3)           &lt;br /&gt;
     layer:AddObject(marker, true)      &lt;br /&gt;
     cursor:Move(contour, step_dist)  &lt;br /&gt;
   end  -- for end&lt;br /&gt;
  end -- function end&lt;br /&gt;
&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Creating Vectors From Script]]&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=LineSpan&amp;diff=1069</id>
		<title>LineSpan</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=LineSpan&amp;diff=1069"/>
		<updated>2024-08-30T19:01:06Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Creating Vectors From Script]]&lt;br /&gt;
This object represents a line span in a Contour. It is derived from the Span class and all methods and properties of the span class are valid on this object as well. As well as creating spans to append to a contour you can use the LineTo methods to avoid span creation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Constructors==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===LineSpan(Point3D start_pt, Point3D end_pt)===&lt;br /&gt;
&lt;br /&gt;
A new span representing a line is created within a Lua script using this contructor method&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
start_pt - Point3D – 3D position for start point of span end_pt - Point3D – 3D position for end point of span&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
e.g&lt;br /&gt;
&lt;br /&gt;
local start_pt = Point3D(0, 0, 0) local end_pt = Point3D(1.0, 0, 0)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local line_span = LineSpan(start_pt, end_pt)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===LineSpan(Point2D start_pt, Point2D end_pt)===&lt;br /&gt;
&lt;br /&gt;
A new span representing aline is created within a Lua script using this contructor method&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
start_pt - Point2D - 2d position for start point of span end_pt - Point2D - 2d position for end point of span&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
e.g&lt;br /&gt;
&lt;br /&gt;
local start_pt = Point2D(0, 0) local end_pt = Point2D(1.0, 0)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
local line_span = LineSpan(start_pt, end_pt)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===ClosestParameterToPoint( Point2D pt)===&lt;br /&gt;
Return the parameter of the point on the line which is closest to the passed point&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
pt - Point2D - 2d position of point finding closest parameter to&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Back.jpg&lt;br /&gt;
References&lt;br /&gt;
Please Note: The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at Vertric Developer Information&lt;br /&gt;
&lt;br /&gt;
Category: SDK&lt;br /&gt;
Navigation menu&lt;br /&gt;
JimAndITalkPreferencesWatchlistContributionsLog outPageDiscussionReadEditView historyUnwatch&lt;br /&gt;
More&lt;br /&gt;
Search&lt;br /&gt;
Search SDK Wiki&lt;br /&gt;
Main page&lt;br /&gt;
Recent changes&lt;br /&gt;
Random page&lt;br /&gt;
Help about MediaWiki&lt;br /&gt;
This page was last edited on 28 July 2020, at 18:54.&lt;br /&gt;
Privacy policyAbout SDK WikiDisclaimersPowered by MediaWiki&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Creating Vectors From Script]]&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=ContourGroup&amp;diff=1068</id>
		<title>ContourGroup</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=ContourGroup&amp;diff=1068"/>
		<updated>2024-08-30T18:58:25Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; [[File:Back.jpg|right|50px|link=Creating Vectors From Script]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
This object is used to move along a contour a fixed distance at a time irrespective of the number of spans in the contour or the type of spans.  &lt;br /&gt;
&lt;br /&gt;
==Constructor==&lt;br /&gt;
&lt;br /&gt;
===ContourCarriage( Contour ctr, Point2D pt) === &lt;br /&gt;
&lt;br /&gt;
Creates a ‘carriage’ for the passed contour and positions it at the nearest point on the contour to the passed point.  &lt;br /&gt;
&lt;br /&gt;
ctr-Contour -The contour that the carriage travels along   &lt;br /&gt;
&lt;br /&gt;
pt-Point2D -The carriage is positioned on the contour at the closest position to this point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===ContourCarriage( integer span_index, double parameter)===  &lt;br /&gt;
&lt;br /&gt;
Creates a ‘carriage’ for a contour and set its positions for the span with the passed index at the passed parameter position (in range 0-1.0) on the span. These values are normaly specified as 0,0.0 to position the carriage at the start of the first span in the contour.  &lt;br /&gt;
&lt;br /&gt;
span_index-integer -Index of span, carriage will be positioned at parameter-double -Parameter along span carriage will be positioned at  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
e.g       local cursor = ContourCarriage(0, 0.0)  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
==Properties==  &lt;br /&gt;
&lt;br /&gt;
===.IsInvalid===  &lt;br /&gt;
&lt;br /&gt;
R/O - bool - Returns true if current position is invalid  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.SpanIndex===  &lt;br /&gt;
&lt;br /&gt;
R/O - integer - Return span index for current position of carriage  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.SpanParameter===  &lt;br /&gt;
&lt;br /&gt;
R/O - double - Return span parameter (in range 0-1.0) for current position of carriage  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&lt;br /&gt;
===:Move( Contour ctr, double distance)===  &lt;br /&gt;
&lt;br /&gt;
Moves the carriage the requested distance along the contour. Returns true if manage to move requested distance successfully. If the contour is closed we will wrap around at the end, if it is open and you attempt to move past the end this method will return false.  &lt;br /&gt;
&lt;br /&gt;
ctr-Contour -The contour this carriage rides along   &lt;br /&gt;
&lt;br /&gt;
distance - double –The distance to move along the contour, negative values will move back  towards the start  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:Position( Contour ctr)===  &lt;br /&gt;
&lt;br /&gt;
Returns a Point2D representing the current position on the carriage on the passed contour  &lt;br /&gt;
&lt;br /&gt;
ctr-Contour -The contour this carriage rides along   &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:UpdatePosition( Contour ctr, Point2D pt)===  &lt;br /&gt;
&lt;br /&gt;
Update the position of the carriage to the nearest position on the contour to the passed point.  &lt;br /&gt;
&lt;br /&gt;
ctr-Contour -The contour that the carriage travels along   &lt;br /&gt;
&lt;br /&gt;
pt-Point2D -The carriage is positioned on the contour at the closest position to this point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
====Example Code====&lt;br /&gt;
&amp;lt;nowiki&amp;gt;&lt;br /&gt;
[[  -------------- MarkContourParameterSteps ---------------------------------   |  &lt;br /&gt;
&lt;br /&gt;
|  Insert a marker at each parameter step around the contour and display the  &lt;br /&gt;
&lt;br /&gt;
|  distance from the start point  &lt;br /&gt;
&lt;br /&gt;
| ]]  &lt;br /&gt;
&lt;br /&gt;
function MarkContourParameterSteps(num_steps, contour, layer)  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
   local cursor = ContourCarriage(0, 0.0)  &lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
&lt;br /&gt;
   local contour_length = contour.Length    local step_dist = contour_length / num_steps  &lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
&lt;br /&gt;
   local end_index = num_steps    if contour.IsOpen then       end_index = end_index + 1      end          &lt;br /&gt;
&lt;br /&gt;
   for i = 1, end_index do  &lt;br /&gt;
&lt;br /&gt;
     local ctr_pos = cursor:Position(contour)  &lt;br /&gt;
&lt;br /&gt;
     local marker = CadMarker(&amp;quot;D:&amp;quot; .. (step_dist * (i - 1)), ctr_pos, 3)           layer:AddObject(marker, true)      cursor:Move(contour, step_dist)  &lt;br /&gt;
&lt;br /&gt;
      end  &lt;br /&gt;
  end  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Creating Vectors From Script]]&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=ContourGroup&amp;diff=1067</id>
		<title>ContourGroup</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=ContourGroup&amp;diff=1067"/>
		<updated>2024-08-30T18:57:03Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; [[File:Back.jpg|right|50px|link=Creating Vectors From Script]]&lt;br /&gt;
[[Category:SDK]]&lt;br /&gt;
This object is used to move along a contour a fixed distance at a time irrespective of the number of spans in the contour or the type of spans.  &lt;br /&gt;
&lt;br /&gt;
==Constructor==&lt;br /&gt;
&lt;br /&gt;
===ContourCarriage( Contour ctr, Point2D pt) === &lt;br /&gt;
&lt;br /&gt;
Creates a ‘carriage’ for the passed contour and positions it at the nearest point on the contour to the passed point.  &lt;br /&gt;
&lt;br /&gt;
ctr-Contour -The contour that the carriage travels along   &lt;br /&gt;
&lt;br /&gt;
pt-Point2D -The carriage is positioned on the contour at the closest position to this point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===ContourCarriage( integer span_index, double parameter)===  &lt;br /&gt;
&lt;br /&gt;
Creates a ‘carriage’ for a contour and set its positions for the span with the passed index at the passed parameter position (in range 0-1.0) on the span. These values are normaly specified as 0,0.0 to position the carriage at the start of the first span in the contour.  &lt;br /&gt;
&lt;br /&gt;
span_index-integer -Index of span, carriage will be positioned at parameter-double -Parameter along span carriage will be positioned at  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
e.g       local cursor = ContourCarriage(0, 0.0)  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
==Properties==  &lt;br /&gt;
&lt;br /&gt;
===.IsInvalid===  &lt;br /&gt;
&lt;br /&gt;
R/O - bool - Returns true if current position is invalid  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.SpanIndex===  &lt;br /&gt;
&lt;br /&gt;
R/O - integer - Return span index for current position of carriage  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.SpanParameter===  &lt;br /&gt;
&lt;br /&gt;
R/O - double - Return span parameter (in range 0-1.0) for current position of carriage  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&lt;br /&gt;
===:Move( Contour ctr, double distance)===  &lt;br /&gt;
&lt;br /&gt;
Moves the carriage the requested distance along the contour. Returns true if manage to move requested distance successfully. If the contour is closed we will wrap around at the end, if it is open and you attempt to move past the end this method will return false.  &lt;br /&gt;
&lt;br /&gt;
ctr-Contour -The contour this carriage rides along   &lt;br /&gt;
&lt;br /&gt;
distance - double –The distance to move along the contour, negative values will move back  towards the start  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:Position( Contour ctr)===  &lt;br /&gt;
&lt;br /&gt;
Returns a Point2D representing the current position on the carriage on the passed contour  &lt;br /&gt;
&lt;br /&gt;
ctr-Contour -The contour this carriage rides along   &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:UpdatePosition( Contour ctr, Point2D pt)===  &lt;br /&gt;
&lt;br /&gt;
Update the position of the carriage to the nearest position on the contour to the passed point.  &lt;br /&gt;
&lt;br /&gt;
ctr-Contour -The contour that the carriage travels along   &lt;br /&gt;
&lt;br /&gt;
pt-Point2D -The carriage is positioned on the contour at the closest position to this point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
Example Code  &lt;br /&gt;
&lt;br /&gt;
[[  -------------- MarkContourParameterSteps ---------------------------------   |  &lt;br /&gt;
&lt;br /&gt;
|  Insert a marker at each parameter step around the contour and display the  &lt;br /&gt;
&lt;br /&gt;
|  distance from the start point  &lt;br /&gt;
&lt;br /&gt;
| ]]  &lt;br /&gt;
&lt;br /&gt;
function MarkContourParameterSteps(num_steps, contour, layer)  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
   local cursor = ContourCarriage(0, 0.0)  &lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
&lt;br /&gt;
   local contour_length = contour.Length    local step_dist = contour_length / num_steps  &lt;br /&gt;
&lt;br /&gt;
     &lt;br /&gt;
&lt;br /&gt;
   local end_index = num_steps    if contour.IsOpen then       end_index = end_index + 1      end          &lt;br /&gt;
&lt;br /&gt;
   for i = 1, end_index do  &lt;br /&gt;
&lt;br /&gt;
     local ctr_pos = cursor:Position(contour)  &lt;br /&gt;
&lt;br /&gt;
     local marker = CadMarker(&amp;quot;D:&amp;quot; .. (step_dist * (i - 1)), ctr_pos, 3)           layer:AddObject(marker, true)      cursor:Move(contour, step_dist)  &lt;br /&gt;
&lt;br /&gt;
      end  end  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Creating Vectors From Script]]&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Span&amp;diff=1066</id>
		<title>Span</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Span&amp;diff=1066"/>
		<updated>2024-08-30T18:53:06Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:SDK]]&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Creating Vectors From Script]]&lt;br /&gt;
This object is the base class for spans in a Contour. Spans are either lines, arcs or beziers or a single  &lt;br /&gt;
&lt;br /&gt;
‘point’  &lt;br /&gt;
&lt;br /&gt;
==Constructors==&lt;br /&gt;
&lt;br /&gt;
===Span( Point3D pt3d)===&lt;br /&gt;
&lt;br /&gt;
A new span representing a single point is created within a Lua script using this contructor method   &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
pt3d - Point3D - 3d position for a point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
e.g  &lt;br /&gt;
&lt;br /&gt;
local pt = Point3D(0, 0, 0)  &lt;br /&gt;
&lt;br /&gt;
local pt_span = Span(pt)  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
NOTE: most spans are created as either a LineSpan,  ArcSpan or BezierSpan.  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
==Properties==  &lt;br /&gt;
&lt;br /&gt;
===.EndPoint3D===&lt;br /&gt;
&lt;br /&gt;
R/O - Point3D - The 3D end point of the span  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.EndPoint2D===&lt;br /&gt;
&lt;br /&gt;
R/O - Point3D - The 2D end point of the span  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.IsLineType===&lt;br /&gt;
&lt;br /&gt;
R/O - bool - true if span is a line      &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.IsArcType===&lt;br /&gt;
&lt;br /&gt;
R/O - bool - true if span is an arc  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.IsBezierType===&lt;br /&gt;
&lt;br /&gt;
R/O - bool - true if span is a bezier   &lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
===.IsLeadInType===&lt;br /&gt;
&lt;br /&gt;
R/O - bool - true if span is a lead in   &lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
===.IsLeadOutType===&lt;br /&gt;
&lt;br /&gt;
R/O - bool - true if span is a lead out   &lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
===.IsOvercutType===&lt;br /&gt;
&lt;br /&gt;
R/O - bool - true if span is part of an overcut  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.NumberOfControlPoints===&lt;br /&gt;
&lt;br /&gt;
R/O - integer - number of control points for span (2 for Bezier, 1 for an arc (the mid point), 0 for a line  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.StartPoint3D===&lt;br /&gt;
&lt;br /&gt;
R/O - Point3D - The 3D start point of the span  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.StartPoint2D===&lt;br /&gt;
&lt;br /&gt;
R/O - Point2D - The 2D start point of the span  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.Type===&lt;br /&gt;
&lt;br /&gt;
R/O - integer - enum identifying type of the span  &lt;br /&gt;
&lt;br /&gt;
Usual values are Span.NormalLine, Span.Arc and Span.Bezier  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
==Methods==&lt;br /&gt;
&lt;br /&gt;
               &lt;br /&gt;
&lt;br /&gt;
===:ChordLength()===  &lt;br /&gt;
&lt;br /&gt;
Return the straight-line distance between start and end points of the span                &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:EndVector( bool normalise)===                  &lt;br /&gt;
&lt;br /&gt;
Return a Vector2D representing the direction of the span at the end.   &lt;br /&gt;
&lt;br /&gt;
 normalise - bool - if true, the returned vector is normalised  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:GetControlPointPosition( integer index)===  &lt;br /&gt;
&lt;br /&gt;
Return a Point2D with position of requested control point (use .NumberOfControlPoints to get count). This call is only valid on a Bezier or an Arc. For a Bezier 0 returns first control point, 1 returns the second. For an arc, 0 returns arc mid point.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
index - integer - index of control point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:GetLength( double tolerance)===  &lt;br /&gt;
&lt;br /&gt;
Return a double holding the length of the span. The passed tolerance is used for beziers to approximate length to given tolerance.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
tolerance - double - tolerance to use when polygonizing beziers to find length  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:MoveControlPoint( integer index, Point2D pt)  === &lt;br /&gt;
&lt;br /&gt;
This is only valid for an arc or Bezier and attempts to move the specified control point to the passed position. This call is only valid on a Bezier or an Arc. For a Bezier, index 0 modifies first control point, 1 modifies the second. For an arc, 0 modifies the arc mid point. If the control point can’t be moved to the passed position (e.g would make an invalid arc) returns false, else true.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
index - integer - index of control point pt - Point2D - position for control point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:PointAtParameter( double param,  double tolerance)  ===&lt;br /&gt;
&lt;br /&gt;
Return a Point2D representing the point on the span at passed parameter in range 0 - 1.0. Passed tolerance is used for polygonisation for Bezier spans.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
parameter - double - parameter in range 0 - 1.0 to find point on span at tolerance - double - tolerance to use when polygonizing beziers  :Reverse()  &lt;br /&gt;
&lt;br /&gt;
Reverse the span - swap start and end points and for arcs swap sign of bulge, for beziers swap control points.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:StartVector( bool normalise)===  &lt;br /&gt;
&lt;br /&gt;
Return a Vector2D representing the direction of the span at the start.   &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
normalise - bool - if true, the returned vector is normalized  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:SetStartPoint3D( Point3D pt)===            &lt;br /&gt;
&lt;br /&gt;
Set start point for span - be EXTREMELY careful if you call this method on spans in a contour as gaps will open between adjoining spans leading to an invalid contour.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
pt - Point3D - 3D position for point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:SetStartPoint2D( Point2D pt)===       &lt;br /&gt;
&lt;br /&gt;
Set start point for span - be EXTREMELY careful if you call this method on spans in a contour as gaps will open between adjoining spans leading to an invalid contour.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
pt - Point2D - 2D position for point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:SetEndPoint3D( Point3D pt)===&lt;br /&gt;
&lt;br /&gt;
Set end point for span - be EXTREMELY careful if you call this method on spans in a contour as gaps will open between adjoining spans leading to an invalid contour.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
pt - Point3D - 3D position for point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
===:SetEndPoint2D( Point2D pt)===&lt;br /&gt;
&lt;br /&gt;
Set end point for span - be EXTREMELY careful if you call this method on spans in a contour as gaps will open between adjoining spans leading to an invalid contour.  &lt;br /&gt;
&lt;br /&gt;
pt - Point2D - 2D position for point  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Creating Vectors From Script]]&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Span&amp;diff=1065</id>
		<title>Span</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Span&amp;diff=1065"/>
		<updated>2024-08-30T18:51:25Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:SDK]]&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Creating Vectors From Script]]&lt;br /&gt;
This object is the base class for spans in a Contour. Spans are either lines, arcs or beziers or a single  &lt;br /&gt;
&lt;br /&gt;
‘point’  &lt;br /&gt;
&lt;br /&gt;
==Constructors==&lt;br /&gt;
&lt;br /&gt;
===Span( Point3D pt3d)===&lt;br /&gt;
&lt;br /&gt;
A new span representing a single point is created within a Lua script using this contructor method   &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
pt3d - Point3D - 3d position for a point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
e.g  &lt;br /&gt;
&lt;br /&gt;
local pt = Point3D(0, 0, 0)  &lt;br /&gt;
&lt;br /&gt;
local pt_span = Span(pt)  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
NOTE: most spans are created as either a LineSpan,  ArcSpan or BezierSpan.  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
==Properties==  &lt;br /&gt;
&lt;br /&gt;
===.EndPoint3D===&lt;br /&gt;
&lt;br /&gt;
R/O - Point3D - The 3D end point of the span  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.EndPoint2D===&lt;br /&gt;
&lt;br /&gt;
R/O - Point3D - The 2D end point of the span  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.IsLineType===&lt;br /&gt;
&lt;br /&gt;
R/O - bool - true if span is a line      &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.IsArcType===&lt;br /&gt;
&lt;br /&gt;
R/O - bool - true if span is an arc  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.IsBezierType===&lt;br /&gt;
&lt;br /&gt;
R/O - bool - true if span is a bezier   &lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
===.IsLeadInType===&lt;br /&gt;
&lt;br /&gt;
R/O - bool - true if span is a lead in   &lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
===.IsLeadOutType===&lt;br /&gt;
&lt;br /&gt;
R/O - bool - true if span is a lead out   &lt;br /&gt;
&lt;br /&gt;
    &lt;br /&gt;
&lt;br /&gt;
===.IsOvercutType===&lt;br /&gt;
&lt;br /&gt;
R/O - bool - true if span is part of an overcut  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.NumberOfControlPoints===&lt;br /&gt;
&lt;br /&gt;
R/O - integer - number of control points for span (2 for Bezier, 1 for an arc (the mid point), 0 for a line  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.StartPoint3D===&lt;br /&gt;
&lt;br /&gt;
R/O - Point3D - The 3D start point of the span  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.StartPoint2D===&lt;br /&gt;
&lt;br /&gt;
R/O - Point2D - The 2D start point of the span  &lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
===.Type===&lt;br /&gt;
&lt;br /&gt;
R/O - integer - enum identifying type of the span  &lt;br /&gt;
&lt;br /&gt;
Usual values are Span.NormalLine, Span.Arc and Span.Bezier  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
Methods  &lt;br /&gt;
&lt;br /&gt;
               &lt;br /&gt;
&lt;br /&gt;
:ChordLength()  &lt;br /&gt;
&lt;br /&gt;
Return the straight-line distance between start and end points of the span                &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
:EndVector( bool normalise)                  &lt;br /&gt;
&lt;br /&gt;
Return a Vector2D representing the direction of the span at the end.   &lt;br /&gt;
&lt;br /&gt;
 normalise - bool - if true, the returned vector is normalised  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
:GetControlPointPosition( integer index)  &lt;br /&gt;
&lt;br /&gt;
Return a Point2D with position of requested control point (use .NumberOfControlPoints to get count). This call is only valid on a Bezier or an Arc. For a Bezier 0 returns first control point, 1 returns the second. For an arc, 0 returns arc mid point.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
index - integer - index of control point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
:GetLength( double tolerance)  &lt;br /&gt;
&lt;br /&gt;
Return a double holding the length of the span. The passed tolerance is used for beziers to approximate length to given tolerance.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
tolerance - double - tolerance to use when polygonizing beziers to find length  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
:MoveControlPoint( integer index, Point2D pt)   &lt;br /&gt;
&lt;br /&gt;
This is only valid for an arc or Bezier and attempts to move the specified control point to the passed position. This call is only valid on a Bezier or an Arc. For a Bezier, index 0 modifies first control point, 1 modifies the second. For an arc, 0 modifies the arc mid point. If the control point can’t be moved to the passed position (e.g would make an invalid arc) returns false, else true.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
index - integer - index of control point pt - Point2D - position for control point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
:PointAtParameter( double param,  double tolerance)  &lt;br /&gt;
&lt;br /&gt;
Return a Point2D representing the point on the span at passed parameter in range 0 - 1.0. Passed tolerance is used for polygonisation for Bezier spans.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
parameter - double - parameter in range 0 - 1.0 to find point on span at tolerance - double - tolerance to use when polygonizing beziers  :Reverse()  &lt;br /&gt;
&lt;br /&gt;
Reverse the span - swap start and end points and for arcs swap sign of bulge, for beziers swap control points.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
:StartVector( bool normalise)  &lt;br /&gt;
&lt;br /&gt;
Return a Vector2D representing the direction of the span at the start.   &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
normalise - bool - if true, the returned vector is normalized  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
:SetStartPoint3D( Point3D pt)            &lt;br /&gt;
&lt;br /&gt;
Set start point for span - be EXTREMELY careful if you call this method on spans in a contour as gaps will open between adjoining spans leading to an invalid contour.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
pt - Point3D - 3D position for point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
:SetStartPoint2D( Point2D pt)       &lt;br /&gt;
&lt;br /&gt;
Set start point for span - be EXTREMELY careful if you call this method on spans in a contour as gaps will open between adjoining spans leading to an invalid contour.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
pt - Point2D - 2D position for point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
:SetEndPoint3D( Point3D pt)             &lt;br /&gt;
&lt;br /&gt;
Set end point for span - be EXTREMELY careful if you call this method on spans in a contour as gaps will open between adjoining spans leading to an invalid contour.  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
pt - Point3D - 3D position for point  &lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
&lt;br /&gt;
:SetEndPoint2D( Point2D pt)           &lt;br /&gt;
&lt;br /&gt;
Set end point for span - be EXTREMELY careful if you call this method on spans in a contour as gaps will open between adjoining spans leading to an invalid contour.  &lt;br /&gt;
&lt;br /&gt;
pt - Point2D - 2D position for point  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Creating Vectors From Script]]&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Licence.txt&amp;diff=1064</id>
		<title>Licence.txt</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Licence.txt&amp;diff=1064"/>
		<updated>2024-08-23T00:21:01Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
&lt;br /&gt;
===Licence Agreement===&lt;br /&gt;
The Licence agreement file is a text (ascii) base file that is placed in the gadget directory and included in the vgadget zip file. (spelling is the British English version of license) The Message below will be displayed on Gadget Install of a GadgetName.vgadget file.&lt;br /&gt;
&lt;br /&gt;
[[File:Licence.png|left|450px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It must have the name of Licence.txt and contains the following information.&lt;br /&gt;
&lt;br /&gt;
== Example Code: App Info==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Property of Company Name. &lt;br /&gt;
The following restrictions applies:&lt;br /&gt;
 1. You must have written permission from [Clients Name] to use this gadget.&lt;br /&gt;
 2. Any altered source must be plainly marked as property of [Company Name].&lt;br /&gt;
 3. These notices may not be removed or altered from any source distribution.&lt;br /&gt;
------------------------------------------------------------------------------&lt;br /&gt;
This gadget was written by JimAndi Gadgets of Houston Texas 2024&lt;br /&gt;
  Written for: &lt;br /&gt;
            Client First and Last Name of&lt;br /&gt;
            Company Name&lt;br /&gt;
            Address Line 1&lt;br /&gt;
            Address Line 2&lt;br /&gt;
            Address Line 3&lt;br /&gt;
            Phone Number&lt;br /&gt;
            Cell Number&lt;br /&gt;
            Email Address&lt;br /&gt;
            Web Site&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Licence.txt&amp;diff=1063</id>
		<title>Licence.txt</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Licence.txt&amp;diff=1063"/>
		<updated>2024-08-23T00:19:27Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
&lt;br /&gt;
===Licence Agreement===&lt;br /&gt;
The Licence agreement file is a text (ascii) base file that is placed in the gadget directory. (spelling is the British English version of license) The Message below will be displayed on Gadget Install of a GadgetName.vgadget file.&lt;br /&gt;
&lt;br /&gt;
[[File:Licence.png|left|450px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It must have the name of Licence.txt and contains the following information.&lt;br /&gt;
&lt;br /&gt;
== Example Code: App Info==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Property of Company Name. &lt;br /&gt;
The following restrictions applies:&lt;br /&gt;
 1. You must have written permission from [Clients Name] to use this gadget.&lt;br /&gt;
 2. Any altered source must be plainly marked as property of [Company Name].&lt;br /&gt;
 3. These notices may not be removed or altered from any source distribution.&lt;br /&gt;
------------------------------------------------------------------------------&lt;br /&gt;
This gadget was written by JimAndi Gadgets of Houston Texas 2024&lt;br /&gt;
  Written for: &lt;br /&gt;
            Client First and Last Name of&lt;br /&gt;
            Company Name&lt;br /&gt;
            Address Line 1&lt;br /&gt;
            Address Line 2&lt;br /&gt;
            Address Line 3&lt;br /&gt;
            Phone Number&lt;br /&gt;
            Cell Number&lt;br /&gt;
            Email Address&lt;br /&gt;
            Web Site&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Licence.txt&amp;diff=1062</id>
		<title>Licence.txt</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Licence.txt&amp;diff=1062"/>
		<updated>2024-08-23T00:18:50Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
&lt;br /&gt;
===Licence Agreement===&lt;br /&gt;
The Licence agreement file is a text (ascii) base file that is placed in the gadget directory. (spelling is the British English version of license) And will be displayed on Gadget Install of a GadgetName.vgadget file.&lt;br /&gt;
&lt;br /&gt;
[[File:Licence.png|left|450px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It must have the name of Licence.txt and contains the following information.&lt;br /&gt;
&lt;br /&gt;
== Example Code: App Info==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Property of Company Name. &lt;br /&gt;
The following restrictions applies:&lt;br /&gt;
 1. You must have written permission from [Clients Name] to use this gadget.&lt;br /&gt;
 2. Any altered source must be plainly marked as property of [Company Name].&lt;br /&gt;
 3. These notices may not be removed or altered from any source distribution.&lt;br /&gt;
------------------------------------------------------------------------------&lt;br /&gt;
This gadget was written by JimAndi Gadgets of Houston Texas 2024&lt;br /&gt;
  Written for: &lt;br /&gt;
            Client First and Last Name of&lt;br /&gt;
            Company Name&lt;br /&gt;
            Address Line 1&lt;br /&gt;
            Address Line 2&lt;br /&gt;
            Address Line 3&lt;br /&gt;
            Phone Number&lt;br /&gt;
            Cell Number&lt;br /&gt;
            Email Address&lt;br /&gt;
            Web Site&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Licence.txt&amp;diff=1061</id>
		<title>Licence.txt</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Licence.txt&amp;diff=1061"/>
		<updated>2024-08-23T00:17:33Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
&lt;br /&gt;
===Licence Agreement===&lt;br /&gt;
The Licence agreement file is a text (ascii) base file that is placed in the gadget directory. (spelling is the British English version of license)&lt;br /&gt;
&lt;br /&gt;
[[File:Licence.png|left|450px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It must have the name of Licence.txt and contains the following information.&lt;br /&gt;
&lt;br /&gt;
== Example Code: App Info==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Property of Company Name. &lt;br /&gt;
The following restrictions applies:&lt;br /&gt;
 1. You must have written permission from [Clients Name] to use this gadget.&lt;br /&gt;
 2. Any altered source must be plainly marked as property of [Company Name].&lt;br /&gt;
 3. These notices may not be removed or altered from any source distribution.&lt;br /&gt;
------------------------------------------------------------------------------&lt;br /&gt;
This gadget was written by JimAndi Gadgets of Houston Texas 2024&lt;br /&gt;
  Written for: &lt;br /&gt;
            Client First and Last Name of&lt;br /&gt;
            Company Name&lt;br /&gt;
            Address Line 1&lt;br /&gt;
            Address Line 2&lt;br /&gt;
            Address Line 3&lt;br /&gt;
            Phone Number&lt;br /&gt;
            Cell Number&lt;br /&gt;
            Email Address&lt;br /&gt;
            Web Site&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Licence.txt&amp;diff=1060</id>
		<title>Licence.txt</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Licence.txt&amp;diff=1060"/>
		<updated>2024-08-23T00:15:17Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
&lt;br /&gt;
===Licence Agreement===&lt;br /&gt;
The Licence agreement file is a text (ascii) base file that is placed in the gadget directory. (spelling is the English version of License)&lt;br /&gt;
&lt;br /&gt;
[[File:Licence.png|left|450px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It must have the name of Licence.txt and contains the following information.&lt;br /&gt;
&lt;br /&gt;
== Example Code: App Info==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Property of Company Name. &lt;br /&gt;
The following restrictions applies:&lt;br /&gt;
 1. You must have written permission from [Clients Name] to use this gadget.&lt;br /&gt;
 2. Any altered source must be plainly marked as property of [Company Name].&lt;br /&gt;
 3. These notices may not be removed or altered from any source distribution.&lt;br /&gt;
------------------------------------------------------------------------------&lt;br /&gt;
This gadget was written by JimAndi Gadgets of Houston Texas 2024&lt;br /&gt;
  Written for: &lt;br /&gt;
            Client First and Last Name of&lt;br /&gt;
            Company Name&lt;br /&gt;
            Address Line 1&lt;br /&gt;
            Address Line 2&lt;br /&gt;
            Address Line 3&lt;br /&gt;
            Phone Number&lt;br /&gt;
            Cell Number&lt;br /&gt;
            Email Address&lt;br /&gt;
            Web Site&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Licence.txt&amp;diff=1059</id>
		<title>Licence.txt</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Licence.txt&amp;diff=1059"/>
		<updated>2024-08-23T00:11:54Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
&lt;br /&gt;
===Licence.txt===&lt;br /&gt;
The License file is a text (ascii) base file that is placed in the gadget directory. &lt;br /&gt;
&lt;br /&gt;
[[File:Licence.png|left|450px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It must have the name of Licence.txt and contains the following information.&lt;br /&gt;
&lt;br /&gt;
== Example Code: App Info==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Property of Company Name. &lt;br /&gt;
The following restrictions applies:&lt;br /&gt;
 1. You must have written permission from [Clients Name] to use this gadget.&lt;br /&gt;
 2. Any altered source must be plainly marked as property of [Company Name].&lt;br /&gt;
 3. These notices may not be removed or altered from any source distribution.&lt;br /&gt;
------------------------------------------------------------------------------&lt;br /&gt;
This gadget was written by JimAndi Gadgets of Houston Texas 2024&lt;br /&gt;
  Written for: &lt;br /&gt;
            Client First and Last Name of&lt;br /&gt;
            Company Name&lt;br /&gt;
            Address Line 1&lt;br /&gt;
            Address Line 2&lt;br /&gt;
            Address Line 3&lt;br /&gt;
            Phone Number&lt;br /&gt;
            Cell Number&lt;br /&gt;
            Email Address&lt;br /&gt;
            Web Site&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Licence.txt&amp;diff=1058</id>
		<title>Licence.txt</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Licence.txt&amp;diff=1058"/>
		<updated>2024-08-23T00:11:32Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
&lt;br /&gt;
===Licence.txt===&lt;br /&gt;
The License file is a text (ascii) base file that is placed in the gadget directory. &lt;br /&gt;
&lt;br /&gt;
[[File:Licence.png|left|450px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It must have the name of Licence.txt and contains the following information.&lt;br /&gt;
&lt;br /&gt;
== Example Code: App Info==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Property of Company Name. &lt;br /&gt;
The following restrictions applies:&lt;br /&gt;
 1. You must have written permission from [Clients Name] to use this gadget.&lt;br /&gt;
 2. Any altered source must be plainly marked as property of [Company Name].&lt;br /&gt;
 3. These notices may not be removed or altered from any source distribution.&lt;br /&gt;
------------------------------------------------------------------------------&lt;br /&gt;
This gadget was written by JimAndi Gadgets of Houston Texas 2024&lt;br /&gt;
  Written for: &lt;br /&gt;
            Client First and Last Name of&lt;br /&gt;
            Company Name&lt;br /&gt;
            Address Line 1&lt;br /&gt;
            Address Line 2&lt;br /&gt;
            Address Line 3&lt;br /&gt;
            Phone Number&lt;br /&gt;
            Cell Number&lt;br /&gt;
            Email Address&lt;br /&gt;
            Web Site&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Licence.txt&amp;diff=1057</id>
		<title>Licence.txt</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Licence.txt&amp;diff=1057"/>
		<updated>2024-08-23T00:11:04Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
&lt;br /&gt;
===Licence.txt===&lt;br /&gt;
The License file is a text (ascii) base file that is placed in the gadget directory. &lt;br /&gt;
&lt;br /&gt;
It must have the name of Licence.txt and contains the following information.&lt;br /&gt;
&lt;br /&gt;
[[File:Licence.png|left|450px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Example Code: App Info==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Property of Company Name. &lt;br /&gt;
The following restrictions applies:&lt;br /&gt;
 1. You must have written permission from [Clients Name] to use this gadget.&lt;br /&gt;
 2. Any altered source must be plainly marked as property of [Company Name].&lt;br /&gt;
 3. These notices may not be removed or altered from any source distribution.&lt;br /&gt;
------------------------------------------------------------------------------&lt;br /&gt;
This gadget was written by JimAndi Gadgets of Houston Texas 2024&lt;br /&gt;
  Written for: &lt;br /&gt;
            Client First and Last Name of&lt;br /&gt;
            Company Name&lt;br /&gt;
            Address Line 1&lt;br /&gt;
            Address Line 2&lt;br /&gt;
            Address Line 3&lt;br /&gt;
            Phone Number&lt;br /&gt;
            Cell Number&lt;br /&gt;
            Email Address&lt;br /&gt;
            Web Site&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Licence.txt&amp;diff=1056</id>
		<title>Licence.txt</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Licence.txt&amp;diff=1056"/>
		<updated>2024-08-23T00:10:31Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
&lt;br /&gt;
===Licence.txt===&lt;br /&gt;
The License file is a text (ascii) base file that is placed in the gadget directory. &lt;br /&gt;
It must have the name of Licence.txt and contains the following information.&lt;br /&gt;
&lt;br /&gt;
[[File:Licence.png|left|450px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Example Code: App Info==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Property of Company Name. &lt;br /&gt;
The following restrictions applies:&lt;br /&gt;
 1. You must have written permission from [Clients Name] to use this gadget.&lt;br /&gt;
 2. Any altered source must be plainly marked as property of [Company Name].&lt;br /&gt;
 3. These notices may not be removed or altered from any source distribution.&lt;br /&gt;
------------------------------------------------------------------------------&lt;br /&gt;
This gadget was written by JimAndi Gadgets of Houston Texas 2024&lt;br /&gt;
  Written for: &lt;br /&gt;
            Client First and Last Name of&lt;br /&gt;
            Company Name&lt;br /&gt;
            Address Line 1&lt;br /&gt;
            Address Line 2&lt;br /&gt;
            Address Line 3&lt;br /&gt;
            Phone Number&lt;br /&gt;
            Cell Number&lt;br /&gt;
            Email Address&lt;br /&gt;
            Web Site&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
	<entry>
		<id>https://jimandi.com/SDK/index.php?title=Licence.txt&amp;diff=1055</id>
		<title>Licence.txt</title>
		<link rel="alternate" type="text/html" href="https://jimandi.com/SDK/index.php?title=Licence.txt&amp;diff=1055"/>
		<updated>2024-08-23T00:10:23Z</updated>

		<summary type="html">&lt;p&gt;WikiSysop: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
&lt;br /&gt;
===Licence.txt===&lt;br /&gt;
The License file is a text (ascii) base file that is placed in the gadget directory. &lt;br /&gt;
It must have the name of Licence.txt and contains the following information.&lt;br /&gt;
&lt;br /&gt;
[[File:Licence.png|left|450px]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Example Code: App Info==&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
Property of Company Name. &lt;br /&gt;
The following restrictions applies:&lt;br /&gt;
 1. You must have written permission from [Clients Name] to use this gadget.&lt;br /&gt;
 2. Any altered source must be plainly marked as property of [Company Name].&lt;br /&gt;
 3. These notices may not be removed or altered from any source distribution.&lt;br /&gt;
------------------------------------------------------------------------------&lt;br /&gt;
This gadget was written by JimAndi Gadgets of Houston Texas 2024&lt;br /&gt;
  Written for: &lt;br /&gt;
            Client First and Last Name of&lt;br /&gt;
            Company Name&lt;br /&gt;
            Address Line 1&lt;br /&gt;
            Address Line 2&lt;br /&gt;
            Address Line 3&lt;br /&gt;
            Phone Number&lt;br /&gt;
            Cell Number&lt;br /&gt;
            Email Address&lt;br /&gt;
            Web Site&lt;br /&gt;
  &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Back.jpg|right|50px|link=Vectric Lua Interface for Gadgets]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
'''Please Note:''' The base material for the contents found in this WiKi was sourced from Vectric Lua Interface for Gadgets, version 2.05, published September 12, 2018. by Vectric Ltd. Most current document from Vertric can be downloaded at [https://gadgets.vectric.com/developerinfo.html Vertric Developer Information]&lt;/div&gt;</summary>
		<author><name>WikiSysop</name></author>
	</entry>
</feed>